@perses-dev/tempo-plugin 0.47.0 → 0.48.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/TraceQLEditor.js +98 -0
- package/dist/cjs/components/TraceQLExtension.js +73 -0
- package/dist/cjs/components/complete.js +322 -0
- package/dist/cjs/components/highlight.js +41 -0
- package/dist/cjs/components/index.js +30 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/model/tempo-client.js +33 -15
- package/dist/cjs/plugins/tempo-datasource.js +22 -4
- package/dist/cjs/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +6 -2
- package/dist/cjs/plugins/tempo-trace-query/get-trace-data.js +3 -13
- package/dist/cjs/test/mock-data.js +58 -0
- package/dist/components/TraceQLEditor.d.ts +7 -0
- package/dist/components/TraceQLEditor.d.ts.map +1 -0
- package/dist/{plugins/tempo-trace-query → components}/TraceQLEditor.js +20 -4
- package/dist/components/TraceQLEditor.js.map +1 -0
- package/dist/components/TraceQLExtension.d.ts +8 -0
- package/dist/components/TraceQLExtension.d.ts.map +1 -0
- package/dist/components/TraceQLExtension.js +65 -0
- package/dist/components/TraceQLExtension.js.map +1 -0
- package/dist/components/complete.d.ts +36 -0
- package/dist/components/complete.d.ts.map +1 -0
- package/dist/components/complete.js +313 -0
- package/dist/components/complete.js.map +1 -0
- package/dist/components/highlight.d.ts +2 -0
- package/dist/components/highlight.d.ts.map +1 -0
- package/dist/components/highlight.js +33 -0
- package/dist/components/highlight.js.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +15 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/model/api-types.d.ts +62 -11
- package/dist/model/api-types.d.ts.map +1 -1
- package/dist/model/api-types.js.map +1 -1
- package/dist/model/tempo-client.d.ts +18 -8
- package/dist/model/tempo-client.d.ts.map +1 -1
- package/dist/model/tempo-client.js +26 -10
- package/dist/model/tempo-client.js.map +1 -1
- package/dist/plugins/tempo-datasource.d.ts.map +1 -1
- package/dist/plugins/tempo-datasource.js +23 -5
- package/dist/plugins/tempo-datasource.js.map +1 -1
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.d.ts.map +1 -1
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +6 -2
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js.map +1 -1
- package/dist/plugins/tempo-trace-query/get-trace-data.d.ts.map +1 -1
- package/dist/plugins/tempo-trace-query/get-trace-data.js +3 -13
- package/dist/plugins/tempo-trace-query/get-trace-data.js.map +1 -1
- package/dist/test/mock-data.d.ts +6 -5
- package/dist/test/mock-data.d.ts.map +1 -1
- package/dist/test/mock-data.js +55 -0
- package/dist/test/mock-data.js.map +1 -1
- package/package.json +8 -4
- package/dist/cjs/plugins/tempo-trace-query/TraceQLEditor.js +0 -46
- package/dist/plugins/tempo-trace-query/TraceQLEditor.d.ts +0 -4
- package/dist/plugins/tempo-trace-query/TraceQLEditor.d.ts.map +0 -1
- package/dist/plugins/tempo-trace-query/TraceQLEditor.js.map +0 -1
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { RequestHeaders } from '@perses-dev/core';
|
|
2
2
|
import { DatasourceClient } from '@perses-dev/plugin-system';
|
|
3
|
-
import { SearchRequestParameters,
|
|
3
|
+
import { QueryRequestParameters, SearchRequestParameters, SearchTagsRequestParameters, SearchTagsResponse, QueryResponse, SearchResponse, SearchTagValuesRequestParameters, SearchTagValuesResponse } from './api-types';
|
|
4
4
|
interface TempoClientOptions {
|
|
5
5
|
datasourceUrl: string;
|
|
6
6
|
headers?: RequestHeaders;
|
|
7
7
|
}
|
|
8
8
|
export interface TempoClient extends DatasourceClient {
|
|
9
9
|
options: TempoClientOptions;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
query(params: QueryRequestParameters, headers?: RequestHeaders): Promise<QueryResponse>;
|
|
11
|
+
search(params: SearchRequestParameters, headers?: RequestHeaders): Promise<SearchResponse>;
|
|
12
|
+
searchWithFallback(params: SearchRequestParameters, headers?: RequestHeaders): Promise<SearchResponse>;
|
|
13
|
+
searchTags(params: SearchTagsRequestParameters, headers?: RequestHeaders): Promise<SearchTagsResponse>;
|
|
14
|
+
searchTagValues(params: SearchTagValuesRequestParameters, headers?: RequestHeaders): Promise<SearchTagValuesResponse>;
|
|
13
15
|
}
|
|
14
16
|
export interface QueryOptions {
|
|
15
17
|
datasourceUrl: string;
|
|
@@ -19,11 +21,11 @@ export declare const executeRequest: <T>(input: string | URL | Request, init?: R
|
|
|
19
21
|
/**
|
|
20
22
|
* Returns a summary report of traces that satisfy the query.
|
|
21
23
|
*/
|
|
22
|
-
export declare function
|
|
24
|
+
export declare function search(params: SearchRequestParameters, queryOptions: QueryOptions): Promise<SearchResponse>;
|
|
23
25
|
/**
|
|
24
|
-
* Returns
|
|
26
|
+
* Returns an entire trace.
|
|
25
27
|
*/
|
|
26
|
-
export declare function
|
|
28
|
+
export declare function query(params: QueryRequestParameters, queryOptions: QueryOptions): Promise<QueryResponse>;
|
|
27
29
|
/**
|
|
28
30
|
* Returns a summary report of traces that satisfy the query.
|
|
29
31
|
*
|
|
@@ -33,6 +35,14 @@ export declare function searchTraceID(traceID: string, queryOptions: QueryOption
|
|
|
33
35
|
* Tempo computes the serviceStats field during ingestion since vParquet4,
|
|
34
36
|
* this fallback is required for older block formats.
|
|
35
37
|
*/
|
|
36
|
-
export declare function
|
|
38
|
+
export declare function searchWithFallback(params: SearchRequestParameters, queryOptions: QueryOptions): Promise<SearchResponse>;
|
|
39
|
+
/**
|
|
40
|
+
* Returns a list of all tag names for a given scope.
|
|
41
|
+
*/
|
|
42
|
+
export declare function searchTags(params: SearchTagsRequestParameters, queryOptions: QueryOptions): Promise<SearchTagsResponse>;
|
|
43
|
+
/**
|
|
44
|
+
* Returns a list of all tag values for a given tag.
|
|
45
|
+
*/
|
|
46
|
+
export declare function searchTagValues(params: SearchTagValuesRequestParameters, queryOptions: QueryOptions): Promise<SearchTagValuesResponse>;
|
|
37
47
|
export {};
|
|
38
48
|
//# sourceMappingURL=tempo-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tempo-client.d.ts","sourceRoot":"","sources":["../../src/model/tempo-client.ts"],"names":[],"mappings":"AAaA,OAAO,EAAS,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,uBAAuB,EACvB,
|
|
1
|
+
{"version":3,"file":"tempo-client.d.ts","sourceRoot":"","sources":["../../src/model/tempo-client.ts"],"names":[],"mappings":"AAaA,OAAO,EAAS,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,kBAAkB,EAClB,aAAa,EAGb,cAAc,EACd,gCAAgC,EAChC,uBAAuB,EACxB,MAAM,aAAa,CAAC;AAErB,UAAU,kBAAkB;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACnD,OAAO,EAAE,kBAAkB,CAAC;IAE5B,KAAK,CAAC,MAAM,EAAE,sBAAsB,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACxF,MAAM,CAAC,MAAM,EAAE,uBAAuB,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3F,kBAAkB,CAAC,MAAM,EAAE,uBAAuB,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACvG,UAAU,CAAC,MAAM,EAAE,2BAA2B,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACvG,eAAe,CAAC,MAAM,EAAE,gCAAgC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;CACvH;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,eAAO,MAAM,cAAc,kFAI1B,CAAC;AAiBF;;GAEG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,uBAAuB,EAAE,YAAY,EAAE,YAAY,2BAEjF;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,sBAAsB,EAAE,YAAY,EAAE,YAAY,0BAE/E;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,uBAAuB,EAC/B,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,cAAc,CAAC,CAqDzB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,2BAA2B,EAAE,YAAY,EAAE,YAAY,+BAEzF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gCAAgC,EAAE,YAAY,EAAE,YAAY,oCAOnG"}
|
|
@@ -31,13 +31,13 @@ function fetchWithGet(apiURI, params, queryOptions) {
|
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* Returns a summary report of traces that satisfy the query.
|
|
34
|
-
*/ export function
|
|
35
|
-
return fetchWithGet(
|
|
34
|
+
*/ export function search(params, queryOptions) {
|
|
35
|
+
return fetchWithGet('/api/search', params, queryOptions);
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
-
* Returns
|
|
39
|
-
*/ export function
|
|
40
|
-
return fetchWithGet(`/api/traces/${
|
|
38
|
+
* Returns an entire trace.
|
|
39
|
+
*/ export function query(params, queryOptions) {
|
|
40
|
+
return fetchWithGet(`/api/traces/${encodeURIComponent(params.traceId)}`, null, queryOptions);
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* Returns a summary report of traces that satisfy the query.
|
|
@@ -47,24 +47,29 @@ function fetchWithGet(apiURI, params, queryOptions) {
|
|
|
47
47
|
*
|
|
48
48
|
* Tempo computes the serviceStats field during ingestion since vParquet4,
|
|
49
49
|
* this fallback is required for older block formats.
|
|
50
|
-
*/ export async function
|
|
51
|
-
var _searchResponse_traces_;
|
|
50
|
+
*/ export async function searchWithFallback(params, queryOptions) {
|
|
52
51
|
// Get a list of traces that satisfy the query.
|
|
53
|
-
const searchResponse = await
|
|
52
|
+
const searchResponse = await search(params, queryOptions);
|
|
54
53
|
if (!searchResponse.traces || searchResponse.traces.length === 0) {
|
|
55
54
|
return {
|
|
56
55
|
traces: []
|
|
57
56
|
};
|
|
58
57
|
}
|
|
59
58
|
// exit early if fallback is not required (serviceStats are contained in the response)
|
|
60
|
-
if (
|
|
59
|
+
if (searchResponse.traces.every((t)=>t.serviceStats)) {
|
|
61
60
|
return searchResponse;
|
|
62
61
|
}
|
|
63
62
|
// calculate serviceStats (number of spans and errors) per service
|
|
64
63
|
return {
|
|
65
64
|
traces: await Promise.all(searchResponse.traces.map(async (trace)=>{
|
|
65
|
+
if (trace.serviceStats) {
|
|
66
|
+
// fallback not required, serviceStats are contained in the response
|
|
67
|
+
return trace;
|
|
68
|
+
}
|
|
66
69
|
const serviceStats = {};
|
|
67
|
-
const searchTraceIDResponse = await
|
|
70
|
+
const searchTraceIDResponse = await query({
|
|
71
|
+
traceId: trace.traceID
|
|
72
|
+
}, queryOptions);
|
|
68
73
|
// For every trace, get the full trace, and find the number of spans and errors.
|
|
69
74
|
for (const batch of searchTraceIDResponse.batches){
|
|
70
75
|
let serviceName = '?';
|
|
@@ -97,5 +102,16 @@ function fetchWithGet(apiURI, params, queryOptions) {
|
|
|
97
102
|
}))
|
|
98
103
|
};
|
|
99
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Returns a list of all tag names for a given scope.
|
|
107
|
+
*/ export function searchTags(params, queryOptions) {
|
|
108
|
+
return fetchWithGet('/api/v2/search/tags', params, queryOptions);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Returns a list of all tag values for a given tag.
|
|
112
|
+
*/ export function searchTagValues(params, queryOptions) {
|
|
113
|
+
const { tag, ...rest } = params;
|
|
114
|
+
return fetchWithGet(`/api/v2/search/tag/${encodeURIComponent(tag)}/values`, rest, queryOptions);
|
|
115
|
+
}
|
|
100
116
|
|
|
101
117
|
//# sourceMappingURL=tempo-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/model/tempo-client.ts"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { fetch, RequestHeaders } from '@perses-dev/core';\nimport { DatasourceClient } from '@perses-dev/plugin-system';\nimport {\n SearchRequestParameters,\n
|
|
1
|
+
{"version":3,"sources":["../../src/model/tempo-client.ts"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { fetch, RequestHeaders } from '@perses-dev/core';\nimport { DatasourceClient } from '@perses-dev/plugin-system';\nimport {\n QueryRequestParameters,\n SearchRequestParameters,\n SearchTagsRequestParameters,\n SearchTagsResponse,\n QueryResponse,\n ServiceStats,\n SpanStatusError,\n SearchResponse,\n SearchTagValuesRequestParameters,\n SearchTagValuesResponse,\n} from './api-types';\n\ninterface TempoClientOptions {\n datasourceUrl: string;\n headers?: RequestHeaders;\n}\n\nexport interface TempoClient extends DatasourceClient {\n options: TempoClientOptions;\n // https://grafana.com/docs/tempo/latest/api_docs/\n query(params: QueryRequestParameters, headers?: RequestHeaders): Promise<QueryResponse>;\n search(params: SearchRequestParameters, headers?: RequestHeaders): Promise<SearchResponse>;\n searchWithFallback(params: SearchRequestParameters, headers?: RequestHeaders): Promise<SearchResponse>;\n searchTags(params: SearchTagsRequestParameters, headers?: RequestHeaders): Promise<SearchTagsResponse>;\n searchTagValues(params: SearchTagValuesRequestParameters, headers?: RequestHeaders): Promise<SearchTagValuesResponse>;\n}\n\nexport interface QueryOptions {\n datasourceUrl: string;\n headers?: RequestHeaders;\n}\n\nexport const executeRequest = async <T>(...args: Parameters<typeof global.fetch>): Promise<T> => {\n const response = await fetch(...args);\n const jsonData = await response.json();\n return jsonData;\n};\n\nfunction fetchWithGet<T, TResponse>(apiURI: string, params: T | null, queryOptions: QueryOptions) {\n const { datasourceUrl, headers = {} } = queryOptions;\n\n let url = `${datasourceUrl}${apiURI}`;\n if (params) {\n url += '?' + new URLSearchParams(params);\n }\n const init = {\n method: 'GET',\n headers,\n };\n\n return executeRequest<TResponse>(url, init);\n}\n\n/**\n * Returns a summary report of traces that satisfy the query.\n */\nexport function search(params: SearchRequestParameters, queryOptions: QueryOptions) {\n return fetchWithGet<SearchRequestParameters, SearchResponse>('/api/search', params, queryOptions);\n}\n\n/**\n * Returns an entire trace.\n */\nexport function query(params: QueryRequestParameters, queryOptions: QueryOptions) {\n return fetchWithGet<null, QueryResponse>(`/api/traces/${encodeURIComponent(params.traceId)}`, null, queryOptions);\n}\n\n/**\n * Returns a summary report of traces that satisfy the query.\n *\n * If the serviceStats field is missing in the response, fetches all traces\n * and calculates the serviceStats.\n *\n * Tempo computes the serviceStats field during ingestion since vParquet4,\n * this fallback is required for older block formats.\n */\nexport async function searchWithFallback(\n params: SearchRequestParameters,\n queryOptions: QueryOptions\n): Promise<SearchResponse> {\n // Get a list of traces that satisfy the query.\n const searchResponse = await search(params, queryOptions);\n if (!searchResponse.traces || searchResponse.traces.length === 0) {\n return { traces: [] };\n }\n\n // exit early if fallback is not required (serviceStats are contained in the response)\n if (searchResponse.traces.every((t) => t.serviceStats)) {\n return searchResponse;\n }\n\n // calculate serviceStats (number of spans and errors) per service\n return {\n traces: await Promise.all(\n searchResponse.traces.map(async (trace) => {\n if (trace.serviceStats) {\n // fallback not required, serviceStats are contained in the response\n return trace;\n }\n\n const serviceStats: Record<string, ServiceStats> = {};\n const searchTraceIDResponse = await query({ traceId: trace.traceID }, queryOptions);\n\n // For every trace, get the full trace, and find the number of spans and errors.\n for (const batch of searchTraceIDResponse.batches) {\n let serviceName = '?';\n for (const attr of batch.resource.attributes) {\n if (attr.key === 'service.name' && 'stringValue' in attr.value) {\n serviceName = attr.value.stringValue;\n break;\n }\n }\n\n const stats = serviceStats[serviceName] ?? { spanCount: 0 };\n for (const scopeSpan of batch.scopeSpans) {\n stats.spanCount += scopeSpan.spans.length;\n for (const span of scopeSpan.spans) {\n if (span.status?.code === SpanStatusError) {\n stats.errorCount = (stats.errorCount ?? 0) + 1;\n }\n }\n }\n serviceStats[serviceName] = stats;\n }\n\n return {\n ...trace,\n serviceStats,\n };\n })\n ),\n };\n}\n\n/**\n * Returns a list of all tag names for a given scope.\n */\nexport function searchTags(params: SearchTagsRequestParameters, queryOptions: QueryOptions) {\n return fetchWithGet<SearchTagsRequestParameters, SearchTagsResponse>('/api/v2/search/tags', params, queryOptions);\n}\n\n/**\n * Returns a list of all tag values for a given tag.\n */\nexport function searchTagValues(params: SearchTagValuesRequestParameters, queryOptions: QueryOptions) {\n const { tag, ...rest } = params;\n return fetchWithGet<Omit<SearchTagValuesRequestParameters, 'tag'>, SearchTagValuesResponse>(\n `/api/v2/search/tag/${encodeURIComponent(tag)}/values`,\n rest,\n queryOptions\n );\n}\n"],"names":["fetch","SpanStatusError","executeRequest","args","response","jsonData","json","fetchWithGet","apiURI","params","queryOptions","datasourceUrl","headers","url","URLSearchParams","init","method","search","query","encodeURIComponent","traceId","searchWithFallback","searchResponse","traces","length","every","t","serviceStats","Promise","all","map","trace","searchTraceIDResponse","traceID","batch","batches","serviceName","attr","resource","attributes","key","value","stringValue","stats","spanCount","scopeSpan","scopeSpans","spans","span","status","code","errorCount","searchTags","searchTagValues","tag","rest"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tempo-datasource.d.ts","sourceRoot":"","sources":["../../src/plugins/tempo-datasource.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,
|
|
1
|
+
{"version":3,"file":"tempo-datasource.d.ts","sourceRoot":"","sources":["../../src/plugins/tempo-datasource.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAkE,MAAM,uBAAuB,CAAC;AACpH,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AA8B/D,eAAO,MAAM,eAAe,EAAE,gBAAgB,CAAC,mBAAmB,EAAE,WAAW,CAK9E,CAAC"}
|
|
@@ -10,24 +10,42 @@
|
|
|
10
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
|
-
import {
|
|
13
|
+
import { query, search, searchTagValues, searchTags, searchWithFallback } from '../model/tempo-client';
|
|
14
14
|
/**
|
|
15
15
|
* Creates a TempoClient for a specific datasource spec.
|
|
16
16
|
*/ const createClient = (spec, options)=>{
|
|
17
|
-
const { directUrl } = spec;
|
|
17
|
+
const { directUrl, proxy } = spec;
|
|
18
18
|
const { proxyUrl } = options;
|
|
19
19
|
// Use the direct URL if specified, but fallback to the proxyUrl by default if not specified
|
|
20
20
|
const datasourceUrl = directUrl !== null && directUrl !== void 0 ? directUrl : proxyUrl;
|
|
21
21
|
if (datasourceUrl === undefined) {
|
|
22
22
|
throw new Error('No URL specified for Tempo client. You can use directUrl in the spec to configure it.');
|
|
23
23
|
}
|
|
24
|
+
const specHeaders = proxy === null || proxy === void 0 ? void 0 : proxy.spec.headers;
|
|
24
25
|
return {
|
|
25
26
|
options: {
|
|
26
27
|
datasourceUrl
|
|
27
28
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
query: (params, headers)=>query(params, {
|
|
30
|
+
datasourceUrl,
|
|
31
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
32
|
+
}),
|
|
33
|
+
search: (params, headers)=>search(params, {
|
|
34
|
+
datasourceUrl,
|
|
35
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
36
|
+
}),
|
|
37
|
+
searchWithFallback: (params, headers)=>searchWithFallback(params, {
|
|
38
|
+
datasourceUrl,
|
|
39
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
40
|
+
}),
|
|
41
|
+
searchTags: (params, headers)=>searchTags(params, {
|
|
42
|
+
datasourceUrl,
|
|
43
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
44
|
+
}),
|
|
45
|
+
searchTagValues: (params, headers)=>searchTagValues(params, {
|
|
46
|
+
datasourceUrl,
|
|
47
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
48
|
+
})
|
|
31
49
|
};
|
|
32
50
|
};
|
|
33
51
|
export const TempoDatasource = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugins/tempo-datasource.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { DatasourcePlugin } from '@perses-dev/plugin-system';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/plugins/tempo-datasource.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { DatasourcePlugin } from '@perses-dev/plugin-system';\nimport { TempoClient, query, search, searchTagValues, searchTags, searchWithFallback } from '../model/tempo-client';\nimport { TempoDatasourceSpec } from './tempo-datasource-types';\n\n/**\n * Creates a TempoClient for a specific datasource spec.\n */\nconst createClient: DatasourcePlugin<TempoDatasourceSpec, TempoClient>['createClient'] = (spec, options) => {\n const { directUrl, proxy } = spec;\n const { proxyUrl } = options;\n\n // Use the direct URL if specified, but fallback to the proxyUrl by default if not specified\n const datasourceUrl = directUrl ?? proxyUrl;\n if (datasourceUrl === undefined) {\n throw new Error('No URL specified for Tempo client. You can use directUrl in the spec to configure it.');\n }\n\n const specHeaders = proxy?.spec.headers;\n\n return {\n options: {\n datasourceUrl,\n },\n query: (params, headers) => query(params, { datasourceUrl, headers: headers ?? specHeaders }),\n search: (params, headers) => search(params, { datasourceUrl, headers: headers ?? specHeaders }),\n searchWithFallback: (params, headers) =>\n searchWithFallback(params, { datasourceUrl, headers: headers ?? specHeaders }),\n searchTags: (params, headers) => searchTags(params, { datasourceUrl, headers: headers ?? specHeaders }),\n searchTagValues: (params, headers) => searchTagValues(params, { datasourceUrl, headers: headers ?? specHeaders }),\n };\n};\n\nexport const TempoDatasource: DatasourcePlugin<TempoDatasourceSpec, TempoClient> = {\n createClient,\n // TODO add a options editor component for tempo datasource\n // OptionsEditorComponent: TempoDatasourceEditor,\n createInitialOptions: () => ({ directUrl: '' }),\n};\n"],"names":["query","search","searchTagValues","searchTags","searchWithFallback","createClient","spec","options","directUrl","proxy","proxyUrl","datasourceUrl","undefined","Error","specHeaders","headers","params","TempoDatasource","createInitialOptions"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAGjC,SAAsBA,KAAK,EAAEC,MAAM,EAAEC,eAAe,EAAEC,UAAU,EAAEC,kBAAkB,QAAQ,wBAAwB;AAGpH;;CAEC,GACD,MAAMC,eAAmF,CAACC,MAAMC;IAC9F,MAAM,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAGH;IAC7B,MAAM,EAAEI,QAAQ,EAAE,GAAGH;IAErB,4FAA4F;IAC5F,MAAMI,gBAAgBH,sBAAAA,uBAAAA,YAAaE;IACnC,IAAIC,kBAAkBC,WAAW;QAC/B,MAAM,IAAIC,MAAM;IAClB;IAEA,MAAMC,cAAcL,kBAAAA,4BAAAA,MAAOH,IAAI,CAACS,OAAO;IAEvC,OAAO;QACLR,SAAS;YACPI;QACF;QACAX,OAAO,CAACgB,QAAQD,UAAYf,MAAMgB,QAAQ;gBAAEL;gBAAeI,SAASA,oBAAAA,qBAAAA,UAAWD;YAAY;QAC3Fb,QAAQ,CAACe,QAAQD,UAAYd,OAAOe,QAAQ;gBAAEL;gBAAeI,SAASA,oBAAAA,qBAAAA,UAAWD;YAAY;QAC7FV,oBAAoB,CAACY,QAAQD,UAC3BX,mBAAmBY,QAAQ;gBAAEL;gBAAeI,SAASA,oBAAAA,qBAAAA,UAAWD;YAAY;QAC9EX,YAAY,CAACa,QAAQD,UAAYZ,WAAWa,QAAQ;gBAAEL;gBAAeI,SAASA,oBAAAA,qBAAAA,UAAWD;YAAY;QACrGZ,iBAAiB,CAACc,QAAQD,UAAYb,gBAAgBc,QAAQ;gBAAEL;gBAAeI,SAASA,oBAAAA,qBAAAA,UAAWD;YAAY;IACjH;AACF;AAEA,OAAO,MAAMG,kBAAsE;IACjFZ;IACA,2DAA2D;IAC3D,iDAAiD;IACjDa,sBAAsB,IAAO,CAAA;YAAEV,WAAW;QAAG,CAAA;AAC/C,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardTempoTraceQueryEditor.d.ts","sourceRoot":"","sources":["../../../src/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAyB,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"DashboardTempoTraceQueryEditor.d.ts","sourceRoot":"","sources":["../../../src/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAyB,MAAM,6BAA6B,CAAC;AAI7F,UAAU,mCAAmC;IAC3C,kBAAkB,EAAE,uBAAuB,CAAC;IAC5C,sBAAsB,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC3D,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,mCAAmC,2CAqBxF"}
|
|
@@ -12,11 +12,12 @@
|
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
14
|
import { Stack, FormControl, InputLabel } from '@mui/material';
|
|
15
|
-
import { DatasourceSelect } from '@perses-dev/plugin-system';
|
|
15
|
+
import { DatasourceSelect, useDatasourceClient } from '@perses-dev/plugin-system';
|
|
16
16
|
import { TEMPO_DATASOURCE_KIND } from '../../model/tempo-selectors';
|
|
17
|
-
import { TraceQLEditor } from '
|
|
17
|
+
import { TraceQLEditor } from '../../components';
|
|
18
18
|
export function DashboardTempoTraceQueryEditor(props) {
|
|
19
19
|
const { selectedDatasource, handleDatasourceChange, query, handleQueryChange, handleQueryBlur } = props;
|
|
20
|
+
const { data: client } = useDatasourceClient(selectedDatasource);
|
|
20
21
|
return /*#__PURE__*/ _jsxs(Stack, {
|
|
21
22
|
spacing: 2,
|
|
22
23
|
children: [
|
|
@@ -38,6 +39,9 @@ export function DashboardTempoTraceQueryEditor(props) {
|
|
|
38
39
|
]
|
|
39
40
|
}),
|
|
40
41
|
/*#__PURE__*/ _jsx(TraceQLEditor, {
|
|
42
|
+
completeConfig: {
|
|
43
|
+
client
|
|
44
|
+
},
|
|
41
45
|
value: query,
|
|
42
46
|
onChange: handleQueryChange,
|
|
43
47
|
onBlur: handleQueryBlur
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Stack, FormControl, InputLabel } from '@mui/material';\nimport { DatasourceSelect } from '@perses-dev/plugin-system';\nimport { DatasourceSelector } from '@perses-dev/core';\nimport { TempoDatasourceSelector, TEMPO_DATASOURCE_KIND } from '../../model/tempo-selectors';\nimport { TraceQLEditor } from '
|
|
1
|
+
{"version":3,"sources":["../../../src/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Stack, FormControl, InputLabel } from '@mui/material';\nimport { DatasourceSelect, useDatasourceClient } from '@perses-dev/plugin-system';\nimport { DatasourceSelector } from '@perses-dev/core';\nimport { TempoDatasourceSelector, TEMPO_DATASOURCE_KIND } from '../../model/tempo-selectors';\nimport { TraceQLEditor } from '../../components';\nimport { TempoClient } from '../../model/tempo-client';\n\ninterface DashboardTempoTraceQueryEditorProps {\n selectedDatasource: TempoDatasourceSelector;\n handleDatasourceChange: (next: DatasourceSelector) => void;\n datasourceURL: string | undefined;\n query: string;\n handleQueryChange: (e: string) => void;\n handleQueryBlur: () => void;\n}\n\nexport function DashboardTempoTraceQueryEditor(props: DashboardTempoTraceQueryEditorProps) {\n const { selectedDatasource, handleDatasourceChange, query, handleQueryChange, handleQueryBlur } = props;\n const { data: client } = useDatasourceClient<TempoClient>(selectedDatasource);\n\n return (\n <Stack spacing={2}>\n <FormControl margin=\"dense\" fullWidth={false}>\n {/* TODO: How do we ensure unique ID values if there are multiple of these? Can we use React 18 useId and\n maintain 17 compatibility somehow with a polyfill/shim? */}\n <InputLabel id=\"tempo-datasource-label\">Tempo Datasource</InputLabel>\n <DatasourceSelect\n datasourcePluginKind={TEMPO_DATASOURCE_KIND}\n value={selectedDatasource}\n onChange={handleDatasourceChange}\n labelId=\"tempo-datasource-label\"\n label=\"Tempo Datasource\"\n />\n </FormControl>\n <TraceQLEditor completeConfig={{ client }} value={query} onChange={handleQueryChange} onBlur={handleQueryBlur} />\n </Stack>\n );\n}\n"],"names":["Stack","FormControl","InputLabel","DatasourceSelect","useDatasourceClient","TEMPO_DATASOURCE_KIND","TraceQLEditor","DashboardTempoTraceQueryEditor","props","selectedDatasource","handleDatasourceChange","query","handleQueryChange","handleQueryBlur","data","client","spacing","margin","fullWidth","id","datasourcePluginKind","value","onChange","labelId","label","completeConfig","onBlur"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,KAAK,EAAEC,WAAW,EAAEC,UAAU,QAAQ,gBAAgB;AAC/D,SAASC,gBAAgB,EAAEC,mBAAmB,QAAQ,4BAA4B;AAElF,SAAkCC,qBAAqB,QAAQ,8BAA8B;AAC7F,SAASC,aAAa,QAAQ,mBAAmB;AAYjD,OAAO,SAASC,+BAA+BC,KAA0C;IACvF,MAAM,EAAEC,kBAAkB,EAAEC,sBAAsB,EAAEC,KAAK,EAAEC,iBAAiB,EAAEC,eAAe,EAAE,GAAGL;IAClG,MAAM,EAAEM,MAAMC,MAAM,EAAE,GAAGX,oBAAiCK;IAE1D,qBACE,MAACT;QAAMgB,SAAS;;0BACd,MAACf;gBAAYgB,QAAO;gBAAQC,WAAW;;kCAGrC,KAAChB;wBAAWiB,IAAG;kCAAyB;;kCACxC,KAAChB;wBACCiB,sBAAsBf;wBACtBgB,OAAOZ;wBACPa,UAAUZ;wBACVa,SAAQ;wBACRC,OAAM;;;;0BAGV,KAAClB;gBAAcmB,gBAAgB;oBAAEV;gBAAO;gBAAGM,OAAOV;gBAAOW,UAAUV;gBAAmBc,QAAQb;;;;AAGpG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-trace-data.d.ts","sourceRoot":"","sources":["../../../src/plugins/tempo-trace-query/get-trace-data.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAEL,iBAAiB,EAMlB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAYpE,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,iBAAiB;;;EAM5D;AAED,eAAO,MAAM,YAAY,EAAE,gBAAgB,CAAC,mBAAmB,CAAC,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"get-trace-data.d.ts","sourceRoot":"","sources":["../../../src/plugins/tempo-trace-query/get-trace-data.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAEL,iBAAiB,EAMlB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAYpE,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,iBAAiB;;;EAM5D;AAED,eAAO,MAAM,YAAY,EAAE,gBAAgB,CAAC,mBAAmB,CAAC,CAAC,cAAc,CAmD9E,CAAC"}
|
|
@@ -22,7 +22,6 @@ export function getUnixTimeRange(timeRange) {
|
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
export const getTraceData = async (spec, context)=>{
|
|
25
|
-
var _client_options;
|
|
26
25
|
if (spec.query === undefined || spec.query === null || spec.query === '') {
|
|
27
26
|
// Do not make a request to the backend, instead return an empty TraceData
|
|
28
27
|
console.error('TempoTraceQuery is undefined, null, or an empty string.');
|
|
@@ -35,13 +34,6 @@ export const getTraceData = async (spec, context)=>{
|
|
|
35
34
|
};
|
|
36
35
|
var _spec_datasource;
|
|
37
36
|
const client = await context.datasourceStore.getDatasourceClient((_spec_datasource = spec.datasource) !== null && _spec_datasource !== void 0 ? _spec_datasource : defaultTempoDatasource);
|
|
38
|
-
const datasourceUrl = client === null || client === void 0 ? void 0 : (_client_options = client.options) === null || _client_options === void 0 ? void 0 : _client_options.datasourceUrl;
|
|
39
|
-
if (datasourceUrl === undefined || datasourceUrl === null || datasourceUrl === '') {
|
|
40
|
-
console.error('TempoDatasource is undefined, null, or an empty string.');
|
|
41
|
-
return {
|
|
42
|
-
searchResult: []
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
37
|
const getQuery = ()=>{
|
|
46
38
|
// if time range not defined -- only return the query from the spec
|
|
47
39
|
if (context.absoluteTimeRange === undefined) {
|
|
@@ -62,8 +54,8 @@ export const getTraceData = async (spec, context)=>{
|
|
|
62
54
|
* if the query is a valid traceId, fetch the trace by traceId
|
|
63
55
|
* otherwise, execute a TraceQL query
|
|
64
56
|
*/ if (isValidTraceId(spec.query)) {
|
|
65
|
-
const response = await client.
|
|
66
|
-
|
|
57
|
+
const response = await client.query({
|
|
58
|
+
traceId: spec.query
|
|
67
59
|
});
|
|
68
60
|
return {
|
|
69
61
|
trace: parseTraceResponse(response),
|
|
@@ -72,9 +64,7 @@ export const getTraceData = async (spec, context)=>{
|
|
|
72
64
|
}
|
|
73
65
|
};
|
|
74
66
|
} else {
|
|
75
|
-
const response = await client.
|
|
76
|
-
datasourceUrl
|
|
77
|
-
});
|
|
67
|
+
const response = await client.searchWithFallback(getQuery());
|
|
78
68
|
return {
|
|
79
69
|
searchResult: parseSearchResponse(response),
|
|
80
70
|
metadata: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/plugins/tempo-trace-query/get-trace-data.ts"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { TraceQueryPlugin } from '@perses-dev/plugin-system';\nimport {\n TraceSearchResult,\n AbsoluteTimeRange,\n Trace,\n Span,\n isValidTraceId,\n TraceResource,\n SpanEvent,\n} from '@perses-dev/core';\nimport { getUnixTime } from 'date-fns';\nimport { sortedIndexBy } from 'lodash';\nimport { TempoTraceQuerySpec } from '../../model/trace-query-model';\nimport { TEMPO_DATASOURCE_KIND, TempoDatasourceSelector } from '../../model/tempo-selectors';\nimport { TempoClient } from '../../model/tempo-client';\nimport {\n SearchRequestParameters,\n SearchTraceIDResponse,\n SearchTraceQueryResponse,\n Resource as TempoResource,\n Span as TempoSpan,\n SpanEvent as TempoSpanEvent,\n} from '../../model/api-types';\n\nexport function getUnixTimeRange(timeRange: AbsoluteTimeRange) {\n const { start, end } = timeRange;\n return {\n start: Math.ceil(getUnixTime(start)),\n end: Math.ceil(getUnixTime(end)),\n };\n}\n\nexport const getTraceData: TraceQueryPlugin<TempoTraceQuerySpec>['getTraceData'] = async (spec, context) => {\n if (spec.query === undefined || spec.query === null || spec.query === '') {\n // Do not make a request to the backend, instead return an empty TraceData\n console.error('TempoTraceQuery is undefined, null, or an empty string.');\n return { searchResult: [] };\n }\n\n const defaultTempoDatasource: TempoDatasourceSelector = {\n kind: TEMPO_DATASOURCE_KIND,\n };\n\n const client: TempoClient = await context.datasourceStore.getDatasourceClient(\n spec.datasource ?? defaultTempoDatasource\n );\n\n const datasourceUrl = client?.options?.datasourceUrl;\n if (datasourceUrl === undefined || datasourceUrl === null || datasourceUrl === '') {\n console.error('TempoDatasource is undefined, null, or an empty string.');\n return { searchResult: [] };\n }\n\n const getQuery = (): SearchRequestParameters => {\n // if time range not defined -- only return the query from the spec\n if (context.absoluteTimeRange === undefined) {\n return { q: spec.query };\n }\n // handle time range selection from UI drop down (e.g. last 5 minutes, last 1 hour )\n const { start, end } = getUnixTimeRange(context?.absoluteTimeRange);\n return {\n q: spec.query,\n start,\n end,\n };\n };\n\n /**\n * determine type of query:\n * if the query is a valid traceId, fetch the trace by traceId\n * otherwise, execute a TraceQL query\n */\n if (isValidTraceId(spec.query)) {\n const response = await client.searchTraceID(spec.query, { datasourceUrl });\n return {\n trace: parseTraceResponse(response),\n metadata: {\n executedQueryString: spec.query,\n },\n };\n } else {\n const response = await client.searchTraceQueryFallback(getQuery(), { datasourceUrl });\n return {\n searchResult: parseSearchResponse(response),\n metadata: {\n executedQueryString: spec.query,\n },\n };\n }\n};\n\nfunction parseResource(resource: TempoResource): TraceResource {\n let serviceName = 'unknown';\n for (const attr of resource.attributes) {\n if (attr.key === 'service.name' && 'stringValue' in attr.value) {\n serviceName = attr.value.stringValue;\n break;\n }\n }\n\n return {\n serviceName,\n attributes: resource.attributes,\n };\n}\n\nfunction parseEvent(event: TempoSpanEvent): SpanEvent {\n return {\n timeUnixMs: parseInt(event.timeUnixNano) * 1e-6, // convert to milliseconds because JS cannot handle numbers larger than 9007199254740991\n name: event.name,\n attributes: event.attributes || [],\n };\n}\n\n/**\n * parseSpan parses the Span API type to the internal representation\n * i.e. convert strings to numbers etc.\n */\nfunction parseSpan(span: TempoSpan) {\n return {\n traceId: span.traceId,\n spanId: span.spanId,\n parentSpanId: span.parentSpanId,\n name: span.name,\n kind: span.kind,\n startTimeUnixMs: parseInt(span.startTimeUnixNano) * 1e-6, // convert to milliseconds because JS cannot handle numbers larger than 9007199254740991\n endTimeUnixMs: parseInt(span.endTimeUnixNano) * 1e-6,\n attributes: span.attributes || [],\n events: (span.events || []).map(parseEvent),\n status: span.status,\n };\n}\n\n/**\n * parseTraceResponse builds a tree of spans from the Tempo API response\n * time complexity: O(2n)\n */\nfunction parseTraceResponse(response: SearchTraceIDResponse): Trace {\n // first pass: build lookup table <spanId, Span>\n const lookup = new Map<string, Span>();\n for (const batch of response.batches) {\n const resource = parseResource(batch.resource);\n\n for (const scopeSpan of batch.scopeSpans) {\n const scope = scopeSpan.scope;\n\n for (const tempoSpan of scopeSpan.spans) {\n const span: Span = {\n resource,\n scope,\n childSpans: [],\n ...parseSpan(tempoSpan),\n };\n lookup.set(tempoSpan.spanId, span);\n }\n }\n }\n\n // second pass: build tree based on parentSpanId property\n let rootSpan: Span | null = null;\n for (const [, span] of lookup) {\n if (!span.parentSpanId) {\n rootSpan = span;\n } else {\n const parent = lookup.get(span.parentSpanId);\n if (!parent) {\n console.error(`span ${span.spanId} has parent ${span.parentSpanId} which has not been received yet`);\n continue;\n }\n\n span.parentSpan = parent;\n const insertChildSpanAt = sortedIndexBy(parent.childSpans, span, (s) => s.startTimeUnixMs);\n parent.childSpans.splice(insertChildSpanAt, 0, span);\n }\n }\n\n if (!rootSpan) {\n throw new Error('root span not found');\n }\n\n return {\n rootSpan,\n };\n}\n\nfunction parseSearchResponse(response: SearchTraceQueryResponse): TraceSearchResult[] {\n return response.traces.map((trace) => ({\n startTimeUnixMs: parseInt(trace.startTimeUnixNano) * 1e-6, // convert to millisecond for eChart time format,\n durationMs: trace.durationMs ?? 0, // Tempo API doesn't return 0 values\n traceId: trace.traceID,\n rootServiceName: trace.rootServiceName,\n rootTraceName: trace.rootTraceName,\n serviceStats: trace.serviceStats || {},\n }));\n}\n"],"names":["isValidTraceId","getUnixTime","sortedIndexBy","TEMPO_DATASOURCE_KIND","getUnixTimeRange","timeRange","start","end","Math","ceil","getTraceData","spec","context","client","query","undefined","console","error","searchResult","defaultTempoDatasource","kind","datasourceStore","getDatasourceClient","datasource","datasourceUrl","options","getQuery","absoluteTimeRange","q","response","searchTraceID","trace","parseTraceResponse","metadata","executedQueryString","searchTraceQueryFallback","parseSearchResponse","parseResource","resource","serviceName","attr","attributes","key","value","stringValue","parseEvent","event","timeUnixMs","parseInt","timeUnixNano","name","parseSpan","span","traceId","spanId","parentSpanId","startTimeUnixMs","startTimeUnixNano","endTimeUnixMs","endTimeUnixNano","events","map","status","lookup","Map","batch","batches","scopeSpan","scopeSpans","scope","tempoSpan","spans","childSpans","set","rootSpan","parent","get","parentSpan","insertChildSpanAt","s","splice","Error","traces","durationMs","traceID","rootServiceName","rootTraceName","serviceStats"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/plugins/tempo-trace-query/get-trace-data.ts"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { TraceQueryPlugin } from '@perses-dev/plugin-system';\nimport {\n TraceSearchResult,\n AbsoluteTimeRange,\n Trace,\n Span,\n isValidTraceId,\n TraceResource,\n SpanEvent,\n} from '@perses-dev/core';\nimport { getUnixTime } from 'date-fns';\nimport { sortedIndexBy } from 'lodash';\nimport { TempoTraceQuerySpec } from '../../model/trace-query-model';\nimport { TEMPO_DATASOURCE_KIND, TempoDatasourceSelector } from '../../model/tempo-selectors';\nimport { TempoClient } from '../../model/tempo-client';\nimport {\n SearchRequestParameters,\n QueryResponse,\n SearchResponse,\n Resource as TempoResource,\n Span as TempoSpan,\n SpanEvent as TempoSpanEvent,\n} from '../../model/api-types';\n\nexport function getUnixTimeRange(timeRange: AbsoluteTimeRange) {\n const { start, end } = timeRange;\n return {\n start: Math.ceil(getUnixTime(start)),\n end: Math.ceil(getUnixTime(end)),\n };\n}\n\nexport const getTraceData: TraceQueryPlugin<TempoTraceQuerySpec>['getTraceData'] = async (spec, context) => {\n if (spec.query === undefined || spec.query === null || spec.query === '') {\n // Do not make a request to the backend, instead return an empty TraceData\n console.error('TempoTraceQuery is undefined, null, or an empty string.');\n return { searchResult: [] };\n }\n\n const defaultTempoDatasource: TempoDatasourceSelector = {\n kind: TEMPO_DATASOURCE_KIND,\n };\n\n const client: TempoClient = await context.datasourceStore.getDatasourceClient(\n spec.datasource ?? defaultTempoDatasource\n );\n\n const getQuery = (): SearchRequestParameters => {\n // if time range not defined -- only return the query from the spec\n if (context.absoluteTimeRange === undefined) {\n return { q: spec.query };\n }\n // handle time range selection from UI drop down (e.g. last 5 minutes, last 1 hour )\n const { start, end } = getUnixTimeRange(context?.absoluteTimeRange);\n return {\n q: spec.query,\n start,\n end,\n };\n };\n\n /**\n * determine type of query:\n * if the query is a valid traceId, fetch the trace by traceId\n * otherwise, execute a TraceQL query\n */\n if (isValidTraceId(spec.query)) {\n const response = await client.query({ traceId: spec.query });\n return {\n trace: parseTraceResponse(response),\n metadata: {\n executedQueryString: spec.query,\n },\n };\n } else {\n const response = await client.searchWithFallback(getQuery());\n return {\n searchResult: parseSearchResponse(response),\n metadata: {\n executedQueryString: spec.query,\n },\n };\n }\n};\n\nfunction parseResource(resource: TempoResource): TraceResource {\n let serviceName = 'unknown';\n for (const attr of resource.attributes) {\n if (attr.key === 'service.name' && 'stringValue' in attr.value) {\n serviceName = attr.value.stringValue;\n break;\n }\n }\n\n return {\n serviceName,\n attributes: resource.attributes,\n };\n}\n\nfunction parseEvent(event: TempoSpanEvent): SpanEvent {\n return {\n timeUnixMs: parseInt(event.timeUnixNano) * 1e-6, // convert to milliseconds because JS cannot handle numbers larger than 9007199254740991\n name: event.name,\n attributes: event.attributes || [],\n };\n}\n\n/**\n * parseSpan parses the Span API type to the internal representation\n * i.e. convert strings to numbers etc.\n */\nfunction parseSpan(span: TempoSpan) {\n return {\n traceId: span.traceId,\n spanId: span.spanId,\n parentSpanId: span.parentSpanId,\n name: span.name,\n kind: span.kind,\n startTimeUnixMs: parseInt(span.startTimeUnixNano) * 1e-6, // convert to milliseconds because JS cannot handle numbers larger than 9007199254740991\n endTimeUnixMs: parseInt(span.endTimeUnixNano) * 1e-6,\n attributes: span.attributes || [],\n events: (span.events || []).map(parseEvent),\n status: span.status,\n };\n}\n\n/**\n * parseTraceResponse builds a tree of spans from the Tempo API response\n * time complexity: O(2n)\n */\nfunction parseTraceResponse(response: QueryResponse): Trace {\n // first pass: build lookup table <spanId, Span>\n const lookup = new Map<string, Span>();\n for (const batch of response.batches) {\n const resource = parseResource(batch.resource);\n\n for (const scopeSpan of batch.scopeSpans) {\n const scope = scopeSpan.scope;\n\n for (const tempoSpan of scopeSpan.spans) {\n const span: Span = {\n resource,\n scope,\n childSpans: [],\n ...parseSpan(tempoSpan),\n };\n lookup.set(tempoSpan.spanId, span);\n }\n }\n }\n\n // second pass: build tree based on parentSpanId property\n let rootSpan: Span | null = null;\n for (const [, span] of lookup) {\n if (!span.parentSpanId) {\n rootSpan = span;\n } else {\n const parent = lookup.get(span.parentSpanId);\n if (!parent) {\n console.error(`span ${span.spanId} has parent ${span.parentSpanId} which has not been received yet`);\n continue;\n }\n\n span.parentSpan = parent;\n const insertChildSpanAt = sortedIndexBy(parent.childSpans, span, (s) => s.startTimeUnixMs);\n parent.childSpans.splice(insertChildSpanAt, 0, span);\n }\n }\n\n if (!rootSpan) {\n throw new Error('root span not found');\n }\n\n return {\n rootSpan,\n };\n}\n\nfunction parseSearchResponse(response: SearchResponse): TraceSearchResult[] {\n return response.traces.map((trace) => ({\n startTimeUnixMs: parseInt(trace.startTimeUnixNano) * 1e-6, // convert to millisecond for eChart time format,\n durationMs: trace.durationMs ?? 0, // Tempo API doesn't return 0 values\n traceId: trace.traceID,\n rootServiceName: trace.rootServiceName,\n rootTraceName: trace.rootTraceName,\n serviceStats: trace.serviceStats || {},\n }));\n}\n"],"names":["isValidTraceId","getUnixTime","sortedIndexBy","TEMPO_DATASOURCE_KIND","getUnixTimeRange","timeRange","start","end","Math","ceil","getTraceData","spec","context","query","undefined","console","error","searchResult","defaultTempoDatasource","kind","client","datasourceStore","getDatasourceClient","datasource","getQuery","absoluteTimeRange","q","response","traceId","trace","parseTraceResponse","metadata","executedQueryString","searchWithFallback","parseSearchResponse","parseResource","resource","serviceName","attr","attributes","key","value","stringValue","parseEvent","event","timeUnixMs","parseInt","timeUnixNano","name","parseSpan","span","spanId","parentSpanId","startTimeUnixMs","startTimeUnixNano","endTimeUnixMs","endTimeUnixNano","events","map","status","lookup","Map","batch","batches","scopeSpan","scopeSpans","scope","tempoSpan","spans","childSpans","set","rootSpan","parent","get","parentSpan","insertChildSpanAt","s","splice","Error","traces","durationMs","traceID","rootServiceName","rootTraceName","serviceStats"],"mappings":"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"}
|
package/dist/test/mock-data.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { TraceData } from '@perses-dev/core';
|
|
2
|
-
import {
|
|
3
|
-
export declare const MOCK_TRACE_RESPONSE:
|
|
4
|
-
export declare const MOCK_TRACE_RESPONSE_SMALL:
|
|
5
|
-
export declare const MOCK_SEARCH_RESPONSE_VPARQUET3:
|
|
6
|
-
export declare const MOCK_SEARCH_RESPONSE_VPARQUET4:
|
|
2
|
+
import { QueryResponse, SearchResponse } from '../model/api-types';
|
|
3
|
+
export declare const MOCK_TRACE_RESPONSE: QueryResponse;
|
|
4
|
+
export declare const MOCK_TRACE_RESPONSE_SMALL: QueryResponse;
|
|
5
|
+
export declare const MOCK_SEARCH_RESPONSE_VPARQUET3: SearchResponse;
|
|
6
|
+
export declare const MOCK_SEARCH_RESPONSE_VPARQUET4: SearchResponse;
|
|
7
|
+
export declare const MOCK_SEARCH_RESPONSE_MIXED_VPARQUET3_AND_4: SearchResponse;
|
|
7
8
|
export declare const MOCK_TRACE_DATA_SEARCHRESULT: TraceData;
|
|
8
9
|
export declare const MOCK_TRACE_DATA_TRACE: TraceData;
|
|
9
10
|
//# sourceMappingURL=mock-data.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock-data.d.ts","sourceRoot":"","sources":["../../src/test/mock-data.ts"],"names":[],"mappings":"AAaA,OAAO,EAAQ,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"mock-data.d.ts","sourceRoot":"","sources":["../../src/test/mock-data.ts"],"names":[],"mappings":"AAaA,OAAO,EAAQ,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEnE,eAAO,MAAM,mBAAmB,EAAE,aA2gEjC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,aA+IvC,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,cAkD5C,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,cAmE5C,CAAC;AAEF,eAAO,MAAM,0CAA0C,EAAE,cAsDxD,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,SA4B1C,CAAC;AA6JF,eAAO,MAAM,qBAAqB,EAAE,SAKnC,CAAC"}
|
package/dist/test/mock-data.js
CHANGED
|
@@ -2333,6 +2333,61 @@ export const MOCK_SEARCH_RESPONSE_VPARQUET4 = {
|
|
|
2333
2333
|
}
|
|
2334
2334
|
]
|
|
2335
2335
|
};
|
|
2336
|
+
export const MOCK_SEARCH_RESPONSE_MIXED_VPARQUET3_AND_4 = {
|
|
2337
|
+
traces: [
|
|
2338
|
+
{
|
|
2339
|
+
traceID: '224a0e75a0d244f1a3dab3af233e6cf3',
|
|
2340
|
+
rootServiceName: 'telemetrygen',
|
|
2341
|
+
rootTraceName: 'lets-go',
|
|
2342
|
+
startTimeUnixNano: '1727969811138427469',
|
|
2343
|
+
spanSets: [
|
|
2344
|
+
{
|
|
2345
|
+
spans: [
|
|
2346
|
+
{
|
|
2347
|
+
spanID: '237f68dfbed2f473',
|
|
2348
|
+
startTimeUnixNano: '1727969811138427469',
|
|
2349
|
+
durationNanos: '123000'
|
|
2350
|
+
},
|
|
2351
|
+
{
|
|
2352
|
+
spanID: 'a8eefdaad116a872',
|
|
2353
|
+
startTimeUnixNano: '1727969811138427469',
|
|
2354
|
+
durationNanos: '123000'
|
|
2355
|
+
}
|
|
2356
|
+
],
|
|
2357
|
+
matched: 2
|
|
2358
|
+
}
|
|
2359
|
+
],
|
|
2360
|
+
serviceStats: {
|
|
2361
|
+
telemetrygen: {
|
|
2362
|
+
spanCount: 2
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
},
|
|
2366
|
+
{
|
|
2367
|
+
traceID: '71bd40553a881d98dc52f2a27fd53fe3',
|
|
2368
|
+
rootServiceName: 'telemetrygen',
|
|
2369
|
+
rootTraceName: 'lets-go',
|
|
2370
|
+
startTimeUnixNano: '1727969665041183110',
|
|
2371
|
+
spanSets: [
|
|
2372
|
+
{
|
|
2373
|
+
spans: [
|
|
2374
|
+
{
|
|
2375
|
+
spanID: '968a78f0ffbc6570',
|
|
2376
|
+
startTimeUnixNano: '1727969665041183110',
|
|
2377
|
+
durationNanos: '123000'
|
|
2378
|
+
},
|
|
2379
|
+
{
|
|
2380
|
+
spanID: 'bb8ab44ffd46ca07',
|
|
2381
|
+
startTimeUnixNano: '1727969665041183110',
|
|
2382
|
+
durationNanos: '123000'
|
|
2383
|
+
}
|
|
2384
|
+
],
|
|
2385
|
+
matched: 2
|
|
2386
|
+
}
|
|
2387
|
+
]
|
|
2388
|
+
}
|
|
2389
|
+
]
|
|
2390
|
+
};
|
|
2336
2391
|
export const MOCK_TRACE_DATA_SEARCHRESULT = {
|
|
2337
2392
|
searchResult: [
|
|
2338
2393
|
{
|