@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.
Files changed (60) hide show
  1. package/dist/cjs/components/TraceQLEditor.js +98 -0
  2. package/dist/cjs/components/TraceQLExtension.js +73 -0
  3. package/dist/cjs/components/complete.js +322 -0
  4. package/dist/cjs/components/highlight.js +41 -0
  5. package/dist/cjs/components/index.js +30 -0
  6. package/dist/cjs/index.js +1 -0
  7. package/dist/cjs/model/tempo-client.js +33 -15
  8. package/dist/cjs/plugins/tempo-datasource.js +22 -4
  9. package/dist/cjs/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +6 -2
  10. package/dist/cjs/plugins/tempo-trace-query/get-trace-data.js +3 -13
  11. package/dist/cjs/test/mock-data.js +58 -0
  12. package/dist/components/TraceQLEditor.d.ts +7 -0
  13. package/dist/components/TraceQLEditor.d.ts.map +1 -0
  14. package/dist/{plugins/tempo-trace-query → components}/TraceQLEditor.js +20 -4
  15. package/dist/components/TraceQLEditor.js.map +1 -0
  16. package/dist/components/TraceQLExtension.d.ts +8 -0
  17. package/dist/components/TraceQLExtension.d.ts.map +1 -0
  18. package/dist/components/TraceQLExtension.js +65 -0
  19. package/dist/components/TraceQLExtension.js.map +1 -0
  20. package/dist/components/complete.d.ts +36 -0
  21. package/dist/components/complete.d.ts.map +1 -0
  22. package/dist/components/complete.js +313 -0
  23. package/dist/components/complete.js.map +1 -0
  24. package/dist/components/highlight.d.ts +2 -0
  25. package/dist/components/highlight.d.ts.map +1 -0
  26. package/dist/components/highlight.js +33 -0
  27. package/dist/components/highlight.js.map +1 -0
  28. package/dist/components/index.d.ts +2 -0
  29. package/dist/components/index.d.ts.map +1 -0
  30. package/dist/components/index.js +15 -0
  31. package/dist/components/index.js.map +1 -0
  32. package/dist/index.d.ts +1 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +2 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/model/api-types.d.ts +62 -11
  37. package/dist/model/api-types.d.ts.map +1 -1
  38. package/dist/model/api-types.js.map +1 -1
  39. package/dist/model/tempo-client.d.ts +18 -8
  40. package/dist/model/tempo-client.d.ts.map +1 -1
  41. package/dist/model/tempo-client.js +26 -10
  42. package/dist/model/tempo-client.js.map +1 -1
  43. package/dist/plugins/tempo-datasource.d.ts.map +1 -1
  44. package/dist/plugins/tempo-datasource.js +23 -5
  45. package/dist/plugins/tempo-datasource.js.map +1 -1
  46. package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.d.ts.map +1 -1
  47. package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +6 -2
  48. package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js.map +1 -1
  49. package/dist/plugins/tempo-trace-query/get-trace-data.d.ts.map +1 -1
  50. package/dist/plugins/tempo-trace-query/get-trace-data.js +3 -13
  51. package/dist/plugins/tempo-trace-query/get-trace-data.js.map +1 -1
  52. package/dist/test/mock-data.d.ts +6 -5
  53. package/dist/test/mock-data.d.ts.map +1 -1
  54. package/dist/test/mock-data.js +55 -0
  55. package/dist/test/mock-data.js.map +1 -1
  56. package/package.json +8 -4
  57. package/dist/cjs/plugins/tempo-trace-query/TraceQLEditor.js +0 -46
  58. package/dist/plugins/tempo-trace-query/TraceQLEditor.d.ts +0 -4
  59. package/dist/plugins/tempo-trace-query/TraceQLEditor.d.ts.map +0 -1
  60. 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, SearchTraceIDResponse, SearchTraceQueryResponse } from './api-types';
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
- searchTraceQuery(params: SearchRequestParameters, queryOptions: QueryOptions): Promise<SearchTraceQueryResponse>;
11
- searchTraceQueryFallback(params: SearchRequestParameters, queryOptions: QueryOptions): Promise<SearchTraceQueryResponse>;
12
- searchTraceID(traceID: string, queryOptions: QueryOptions): Promise<SearchTraceIDResponse>;
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 searchTraceQuery(params: SearchRequestParameters, queryOptions: QueryOptions): Promise<SearchTraceQueryResponse>;
24
+ export declare function search(params: SearchRequestParameters, queryOptions: QueryOptions): Promise<SearchResponse>;
23
25
  /**
24
- * Returns a detailed report, including all the spans, for a given trace.
26
+ * Returns an entire trace.
25
27
  */
26
- export declare function searchTraceID(traceID: string, queryOptions: QueryOptions): Promise<SearchTraceIDResponse>;
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 searchTraceQueryFallback(params: SearchRequestParameters, queryOptions: QueryOptions): Promise<SearchTraceQueryResponse>;
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,qBAAqB,EACrB,wBAAwB,EAGzB,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;IAC5B,gBAAgB,CAAC,MAAM,EAAE,uBAAuB,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACjH,wBAAwB,CACtB,MAAM,EAAE,uBAAuB,EAC/B,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACrC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC5F;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,gBAAgB,CAAC,MAAM,EAAE,uBAAuB,EAAE,YAAY,EAAE,YAAY,qCAE3F;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,kCAExE;AAED;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,uBAAuB,EAC/B,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,wBAAwB,CAAC,CAgDnC"}
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 searchTraceQuery(params, queryOptions) {
35
- return fetchWithGet(`/api/search`, params, queryOptions);
34
+ */ export function search(params, queryOptions) {
35
+ return fetchWithGet('/api/search', params, queryOptions);
36
36
  }
37
37
  /**
38
- * Returns a detailed report, including all the spans, for a given trace.
39
- */ export function searchTraceID(traceID, queryOptions) {
40
- return fetchWithGet(`/api/traces/${traceID}`, null, queryOptions);
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 searchTraceQueryFallback(params, queryOptions) {
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 searchTraceQuery(params, queryOptions);
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 ((_searchResponse_traces_ = searchResponse.traces[0]) === null || _searchResponse_traces_ === void 0 ? void 0 : _searchResponse_traces_.serviceStats) {
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 searchTraceID(trace.traceID, queryOptions);
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 SearchTraceIDResponse,\n SearchTraceQueryResponse,\n ServiceStats,\n SpanStatusError,\n} from './api-types';\n\ninterface TempoClientOptions {\n datasourceUrl: string;\n headers?: RequestHeaders;\n}\n\nexport interface TempoClient extends DatasourceClient {\n options: TempoClientOptions;\n searchTraceQuery(params: SearchRequestParameters, queryOptions: QueryOptions): Promise<SearchTraceQueryResponse>;\n searchTraceQueryFallback(\n params: SearchRequestParameters,\n queryOptions: QueryOptions\n ): Promise<SearchTraceQueryResponse>;\n searchTraceID(traceID: string, queryOptions: QueryOptions): Promise<SearchTraceIDResponse>;\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 searchTraceQuery(params: SearchRequestParameters, queryOptions: QueryOptions) {\n return fetchWithGet<SearchRequestParameters, SearchTraceQueryResponse>(`/api/search`, params, queryOptions);\n}\n\n/**\n * Returns a detailed report, including all the spans, for a given trace.\n */\nexport function searchTraceID(traceID: string, queryOptions: QueryOptions) {\n return fetchWithGet<null, SearchTraceIDResponse>(`/api/traces/${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 searchTraceQueryFallback(\n params: SearchRequestParameters,\n queryOptions: QueryOptions\n): Promise<SearchTraceQueryResponse> {\n // Get a list of traces that satisfy the query.\n const searchResponse = await searchTraceQuery(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[0]?.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 const serviceStats: Record<string, ServiceStats> = {};\n const searchTraceIDResponse = await searchTraceID(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"],"names":["fetch","SpanStatusError","executeRequest","args","response","jsonData","json","fetchWithGet","apiURI","params","queryOptions","datasourceUrl","headers","url","URLSearchParams","init","method","searchTraceQuery","searchTraceID","traceID","searchTraceQueryFallback","searchResponse","traces","length","serviceStats","Promise","all","map","trace","searchTraceIDResponse","batch","batches","serviceName","attr","resource","attributes","key","value","stringValue","stats","spanCount","scopeSpan","scopeSpans","spans","span","status","code","errorCount"],"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,QAAwB,mBAAmB;AAEzD,SAKEC,eAAe,QACV,cAAc;AAsBrB,OAAO,MAAMC,iBAAiB,OAAU,GAAGC;IACzC,MAAMC,WAAW,MAAMJ,SAASG;IAChC,MAAME,WAAW,MAAMD,SAASE,IAAI;IACpC,OAAOD;AACT,EAAE;AAEF,SAASE,aAA2BC,MAAc,EAAEC,MAAgB,EAAEC,YAA0B;IAC9F,MAAM,EAAEC,aAAa,EAAEC,UAAU,CAAC,CAAC,EAAE,GAAGF;IAExC,IAAIG,MAAM,CAAC,EAAEF,cAAc,EAAEH,OAAO,CAAC;IACrC,IAAIC,QAAQ;QACVI,OAAO,MAAM,IAAIC,gBAAgBL;IACnC;IACA,MAAMM,OAAO;QACXC,QAAQ;QACRJ;IACF;IAEA,OAAOV,eAA0BW,KAAKE;AACxC;AAEA;;CAEC,GACD,OAAO,SAASE,iBAAiBR,MAA+B,EAAEC,YAA0B;IAC1F,OAAOH,aAAgE,CAAC,WAAW,CAAC,EAAEE,QAAQC;AAChG;AAEA;;CAEC,GACD,OAAO,SAASQ,cAAcC,OAAe,EAAET,YAA0B;IACvE,OAAOH,aAA0C,CAAC,YAAY,EAAEY,QAAQ,CAAC,EAAE,MAAMT;AACnF;AAEA;;;;;;;;CAQC,GACD,OAAO,eAAeU,yBACpBX,MAA+B,EAC/BC,YAA0B;QAStBW;IAPJ,+CAA+C;IAC/C,MAAMA,iBAAiB,MAAMJ,iBAAiBR,QAAQC;IACtD,IAAI,CAACW,eAAeC,MAAM,IAAID,eAAeC,MAAM,CAACC,MAAM,KAAK,GAAG;QAChE,OAAO;YAAED,QAAQ,EAAE;QAAC;IACtB;IAEA,sFAAsF;IACtF,KAAID,0BAAAA,eAAeC,MAAM,CAAC,EAAE,cAAxBD,8CAAAA,wBAA0BG,YAAY,EAAE;QAC1C,OAAOH;IACT;IAEA,kEAAkE;IAClE,OAAO;QACLC,QAAQ,MAAMG,QAAQC,GAAG,CACvBL,eAAeC,MAAM,CAACK,GAAG,CAAC,OAAOC;YAC/B,MAAMJ,eAA6C,CAAC;YACpD,MAAMK,wBAAwB,MAAMX,cAAcU,MAAMT,OAAO,EAAET;YAEjE,gFAAgF;YAChF,KAAK,MAAMoB,SAASD,sBAAsBE,OAAO,CAAE;gBACjD,IAAIC,cAAc;gBAClB,KAAK,MAAMC,QAAQH,MAAMI,QAAQ,CAACC,UAAU,CAAE;oBAC5C,IAAIF,KAAKG,GAAG,KAAK,kBAAkB,iBAAiBH,KAAKI,KAAK,EAAE;wBAC9DL,cAAcC,KAAKI,KAAK,CAACC,WAAW;wBACpC;oBACF;gBACF;oBAEcd;gBAAd,MAAMe,QAAQf,CAAAA,4BAAAA,YAAY,CAACQ,YAAY,cAAzBR,uCAAAA,4BAA6B;oBAAEgB,WAAW;gBAAE;gBAC1D,KAAK,MAAMC,aAAaX,MAAMY,UAAU,CAAE;oBACxCH,MAAMC,SAAS,IAAIC,UAAUE,KAAK,CAACpB,MAAM;oBACzC,KAAK,MAAMqB,QAAQH,UAAUE,KAAK,CAAE;4BAC9BC;wBAAJ,IAAIA,EAAAA,eAAAA,KAAKC,MAAM,cAAXD,mCAAAA,aAAaE,IAAI,MAAK7C,iBAAiB;gCACrBsC;4BAApBA,MAAMQ,UAAU,GAAG,AAACR,CAAAA,CAAAA,oBAAAA,MAAMQ,UAAU,cAAhBR,+BAAAA,oBAAoB,CAAA,IAAK;wBAC/C;oBACF;gBACF;gBACAf,YAAY,CAACQ,YAAY,GAAGO;YAC9B;YAEA,OAAO;gBACL,GAAGX,KAAK;gBACRJ;YACF;QACF;IAEJ;AACF"}
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,EAA6D,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/G,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAyB/D,eAAO,MAAM,eAAe,EAAE,gBAAgB,CAAC,mBAAmB,EAAE,WAAW,CAK9E,CAAC"}
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 { searchTraceQuery, searchTraceID, searchTraceQueryFallback } from '../model/tempo-client';
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
- searchTraceQuery: (params, queryOptions)=>searchTraceQuery(params, queryOptions),
29
- searchTraceQueryFallback: (params, queryOptions)=>searchTraceQueryFallback(params, queryOptions),
30
- searchTraceID: (traceID, queryOptions)=>searchTraceID(traceID, queryOptions)
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 { searchTraceQuery, searchTraceID, searchTraceQueryFallback, TempoClient } 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 } = 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 return {\n options: {\n datasourceUrl,\n },\n searchTraceQuery: (params, queryOptions) => searchTraceQuery(params, queryOptions),\n searchTraceQueryFallback: (params, queryOptions) => searchTraceQueryFallback(params, queryOptions),\n searchTraceID: (traceID, queryOptions) => searchTraceID(traceID, queryOptions),\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":["searchTraceQuery","searchTraceID","searchTraceQueryFallback","createClient","spec","options","directUrl","proxyUrl","datasourceUrl","undefined","Error","params","queryOptions","traceID","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,SAASA,gBAAgB,EAAEC,aAAa,EAAEC,wBAAwB,QAAqB,wBAAwB;AAG/G;;CAEC,GACD,MAAMC,eAAmF,CAACC,MAAMC;IAC9F,MAAM,EAAEC,SAAS,EAAE,GAAGF;IACtB,MAAM,EAAEG,QAAQ,EAAE,GAAGF;IAErB,4FAA4F;IAC5F,MAAMG,gBAAgBF,sBAAAA,uBAAAA,YAAaC;IACnC,IAAIC,kBAAkBC,WAAW;QAC/B,MAAM,IAAIC,MAAM;IAClB;IAEA,OAAO;QACLL,SAAS;YACPG;QACF;QACAR,kBAAkB,CAACW,QAAQC,eAAiBZ,iBAAiBW,QAAQC;QACrEV,0BAA0B,CAACS,QAAQC,eAAiBV,yBAAyBS,QAAQC;QACrFX,eAAe,CAACY,SAASD,eAAiBX,cAAcY,SAASD;IACnE;AACF;AAEA,OAAO,MAAME,kBAAsE;IACjFX;IACA,2DAA2D;IAC3D,iDAAiD;IACjDY,sBAAsB,IAAO,CAAA;YAAET,WAAW;QAAG,CAAA;AAC/C,EAAE"}
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;AAG7F,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,2CAoBxF"}
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 './TraceQLEditor';
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 './TraceQLEditor';\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\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 value={query} onChange={handleQueryChange} onBlur={handleQueryBlur} />\n </Stack>\n );\n}\n"],"names":["Stack","FormControl","InputLabel","DatasourceSelect","TEMPO_DATASOURCE_KIND","TraceQLEditor","DashboardTempoTraceQueryEditor","props","selectedDatasource","handleDatasourceChange","query","handleQueryChange","handleQueryBlur","spacing","margin","fullWidth","id","datasourcePluginKind","value","onChange","labelId","label","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,QAAQ,4BAA4B;AAE7D,SAAkCC,qBAAqB,QAAQ,8BAA8B;AAC7F,SAASC,aAAa,QAAQ,kBAAkB;AAWhD,OAAO,SAASC,+BAA+BC,KAA0C;IACvF,MAAM,EAAEC,kBAAkB,EAAEC,sBAAsB,EAAEC,KAAK,EAAEC,iBAAiB,EAAEC,eAAe,EAAE,GAAGL;IAElG,qBACE,MAACP;QAAMa,SAAS;;0BACd,MAACZ;gBAAYa,QAAO;gBAAQC,WAAW;;kCAGrC,KAACb;wBAAWc,IAAG;kCAAyB;;kCACxC,KAACb;wBACCc,sBAAsBb;wBACtBc,OAAOV;wBACPW,UAAUV;wBACVW,SAAQ;wBACRC,OAAM;;;;0BAGV,KAAChB;gBAAca,OAAOR;gBAAOS,UAAUR;gBAAmBW,QAAQV;;;;AAGxE"}
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,CAyD9E,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.searchTraceID(spec.query, {
66
- datasourceUrl
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.searchTraceQueryFallback(getQuery(), {
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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"}
@@ -1,9 +1,10 @@
1
1
  import { TraceData } from '@perses-dev/core';
2
- import { SearchTraceIDResponse, SearchTraceQueryResponse } from '../model/api-types';
3
- export declare const MOCK_TRACE_RESPONSE: SearchTraceIDResponse;
4
- export declare const MOCK_TRACE_RESPONSE_SMALL: SearchTraceIDResponse;
5
- export declare const MOCK_SEARCH_RESPONSE_VPARQUET3: SearchTraceQueryResponse;
6
- export declare const MOCK_SEARCH_RESPONSE_VPARQUET4: SearchTraceQueryResponse;
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,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAErF,eAAO,MAAM,mBAAmB,EAAE,qBA2gEjC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,qBA+IvC,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,wBAkD5C,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,wBAmE5C,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,SA4B1C,CAAC;AA6JF,eAAO,MAAM,qBAAqB,EAAE,SAKnC,CAAC"}
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"}
@@ -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
  {