@perses-dev/tempo-plugin 0.52.0 → 0.53.0
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/__mf/js/Tempo.2f6d49a1.js +5 -0
- package/__mf/js/async/1101.0dae4724.js +73 -0
- package/__mf/js/async/1576.83b7de56.js +1 -0
- package/__mf/js/async/1964.e6c5b93b.js +2 -0
- package/__mf/js/async/2292.75e9aa11.js +2 -0
- package/__mf/js/async/2913.f73e6635.js +7 -0
- package/__mf/js/async/2913.f73e6635.js.LICENSE.txt +21 -0
- package/__mf/js/async/2981.8fe4ed12.js +2 -0
- package/__mf/js/async/3224.ce173388.js +1 -0
- package/__mf/js/async/3863.8d56ecec.js +2 -0
- package/__mf/js/async/3960.401ff0b0.js +2 -0
- package/__mf/js/async/3980.4d5490b2.js +2 -0
- package/__mf/js/async/4075.4c5ac93a.js +1 -0
- package/__mf/js/async/4238.7962a7a1.js +1 -0
- package/__mf/js/async/4269.0cfaf9bb.js +2 -0
- package/__mf/js/async/4368.bd6fd0e7.js +2 -0
- package/__mf/js/async/4368.bd6fd0e7.js.LICENSE.txt +15 -0
- package/__mf/js/async/4421.14238d27.js +1 -0
- package/__mf/js/async/4535.7c92d3fd.js +1 -0
- package/__mf/js/async/5214.c44cbfe5.js +1 -0
- package/__mf/js/async/5266.1c520126.js +10 -0
- package/__mf/js/async/5409.676a5f3f.js +1 -0
- package/__mf/js/async/5790.b4d4134d.js +1 -0
- package/__mf/js/async/5876.47f40562.js +2 -0
- package/__mf/js/async/{7832.9f2a70d0.js.LICENSE.txt → 5876.47f40562.js.LICENSE.txt} +1 -23
- package/__mf/js/async/5981.c6edce96.js +2 -0
- package/__mf/js/async/6292.463b4f49.js +1 -0
- package/__mf/js/async/6333.367d6758.js +2 -0
- package/__mf/js/async/6495.eae3d4b4.js +1 -0
- package/__mf/js/async/6527.5341d09f.js +2 -0
- package/__mf/js/async/6751.03514b88.js +1 -0
- package/__mf/js/async/6770.d9c238f2.js +1 -0
- package/__mf/js/async/694.c2c37771.js +1 -0
- package/__mf/js/async/7127.a0877987.js +38 -0
- package/__mf/js/async/7376.588b7a17.js +1 -0
- package/__mf/js/async/738.93d35dc9.js +1 -0
- package/__mf/js/async/7740.0500bfc6.js +1 -0
- package/__mf/js/async/8216.2f92a883.js +1 -0
- package/__mf/js/async/8488.6c9a25e4.js +1 -0
- package/__mf/js/async/8597.d5ba4ca7.js +1 -0
- package/__mf/js/async/8930.dee9777e.js +1 -0
- package/__mf/js/async/9173.69dc268d.js +2 -0
- package/__mf/js/async/9314.4b8565a0.js +2 -0
- package/__mf/js/async/9368.f0418d24.js +101 -0
- package/__mf/js/async/__federation_expose_TempoDatasource.fa3e24f9.js +2 -0
- package/__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js +2 -0
- package/__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js +1 -0
- package/__mf/js/async/lib-router.312ca028.js +2 -0
- package/__mf/js/main.edbb7a5a.js +5 -0
- package/lib/cjs/components/AttributeFilters.js +274 -0
- package/lib/cjs/components/TraceQLEditor.js +9 -3
- package/lib/cjs/components/complete.js +29 -13
- package/lib/cjs/components/filter/filter.js +25 -0
- package/lib/cjs/components/filter/filter_to_traceql.js +66 -0
- package/lib/cjs/components/filter/index.js +32 -0
- package/lib/cjs/components/filter/traceql_to_filter.js +113 -0
- package/lib/cjs/components/index.js +1 -0
- package/lib/cjs/explore/TempoExplorer.js +25 -12
- package/lib/cjs/explore/links.js +77 -0
- package/lib/cjs/plugins/tempo-trace-query/TempoTraceQueryEditor.js +94 -30
- package/lib/cjs/plugins/tempo-trace-query/get-trace-data.js +8 -0
- package/lib/cjs/plugins/tempo-trace-query/query-editor-model.js +3 -44
- package/lib/components/AttributeFilters.d.ts +9 -0
- package/lib/components/AttributeFilters.d.ts.map +1 -0
- package/lib/components/AttributeFilters.js +261 -0
- package/lib/components/AttributeFilters.js.map +1 -0
- package/lib/components/TraceQLEditor.d.ts +3 -3
- package/lib/components/TraceQLEditor.d.ts.map +1 -1
- package/lib/components/TraceQLEditor.js +9 -3
- package/lib/components/TraceQLEditor.js.map +1 -1
- package/lib/components/complete.d.ts +10 -1
- package/lib/components/complete.d.ts.map +1 -1
- package/lib/components/complete.js +26 -7
- package/lib/components/complete.js.map +1 -1
- package/lib/components/filter/filter.d.ts +17 -0
- package/lib/components/filter/filter.d.ts.map +1 -0
- package/lib/components/filter/filter.js +17 -0
- package/lib/components/filter/filter.js.map +1 -0
- package/lib/components/filter/filter_to_traceql.d.ts +9 -0
- package/lib/components/filter/filter_to_traceql.d.ts.map +1 -0
- package/lib/components/filter/filter_to_traceql.js +63 -0
- package/lib/components/filter/filter_to_traceql.js.map +1 -0
- package/lib/components/filter/index.d.ts +4 -0
- package/lib/components/filter/index.d.ts.map +1 -0
- package/lib/components/filter/index.js +17 -0
- package/lib/components/filter/index.js.map +1 -0
- package/lib/components/filter/traceql_to_filter.d.ts +9 -0
- package/lib/components/filter/traceql_to_filter.d.ts.map +1 -0
- package/lib/components/filter/traceql_to_filter.js +110 -0
- package/lib/components/filter/traceql_to_filter.js.map +1 -0
- package/lib/components/index.d.ts +1 -0
- package/lib/components/index.d.ts.map +1 -1
- package/lib/components/index.js +1 -0
- package/lib/components/index.js.map +1 -1
- package/lib/explore/TempoExplorer.d.ts.map +1 -1
- package/lib/explore/TempoExplorer.js +25 -12
- package/lib/explore/TempoExplorer.js.map +1 -1
- package/lib/explore/links.d.ts +3 -0
- package/lib/explore/links.d.ts.map +1 -0
- package/lib/explore/links.js +63 -0
- package/lib/explore/links.js.map +1 -0
- package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts +6 -0
- package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts.map +1 -1
- package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js +87 -31
- package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js.map +1 -1
- package/lib/plugins/tempo-trace-query/get-trace-data.js +8 -0
- package/lib/plugins/tempo-trace-query/get-trace-data.js.map +1 -1
- package/lib/plugins/tempo-trace-query/query-editor-model.d.ts +0 -9
- package/lib/plugins/tempo-trace-query/query-editor-model.d.ts.map +1 -1
- package/lib/plugins/tempo-trace-query/query-editor-model.js +0 -35
- package/lib/plugins/tempo-trace-query/query-editor-model.js.map +1 -1
- package/mf-manifest.json +104 -265
- package/mf-stats.json +112 -270
- package/package.json +6 -6
- package/__mf/js/1096.c549c391.js +0 -5
- package/__mf/js/Tempo.e7d268a6.js +0 -5
- package/__mf/js/async/1465.21c847e0.js +0 -1
- package/__mf/js/async/1540.089c4f28.js +0 -74
- package/__mf/js/async/1620.45989def.js +0 -2
- package/__mf/js/async/1964.75933dd4.js +0 -2
- package/__mf/js/async/2114.28503adb.js +0 -1
- package/__mf/js/async/2823.df67fd4b.js +0 -2
- package/__mf/js/async/3044.8b419ccf.js +0 -1
- package/__mf/js/async/3090.90251187.js +0 -2
- package/__mf/js/async/3224.8d499a63.js +0 -1
- package/__mf/js/async/3355.8bd6f6bd.js +0 -1
- package/__mf/js/async/3828.d981b319.js +0 -2
- package/__mf/js/async/3960.2228bf7e.js +0 -2
- package/__mf/js/async/3980.c94e78cd.js +0 -2
- package/__mf/js/async/4075.4c40db9f.js +0 -1
- package/__mf/js/async/4238.db631f1f.js +0 -1
- package/__mf/js/async/4289.5e2073e0.js +0 -1
- package/__mf/js/async/4421.07335985.js +0 -1
- package/__mf/js/async/4758.cb86850e.js +0 -1
- package/__mf/js/async/5207.e63b049c.js +0 -2
- package/__mf/js/async/5214.fb1215df.js +0 -1
- package/__mf/js/async/5220.80e3b05e.js +0 -10
- package/__mf/js/async/528.2759052c.js +0 -1
- package/__mf/js/async/5503.6e47fa95.js +0 -1
- package/__mf/js/async/5790.949d8d1c.js +0 -1
- package/__mf/js/async/5913.d10c6185.js +0 -73
- package/__mf/js/async/5924.bfb4b2fd.js +0 -2
- package/__mf/js/async/5981.4700ddf6.js +0 -2
- package/__mf/js/async/6292.2481b399.js +0 -1
- package/__mf/js/async/6770.4b9911ea.js +0 -1
- package/__mf/js/async/694.91676c53.js +0 -1
- package/__mf/js/async/7127.ccd78bd8.js +0 -38
- package/__mf/js/async/7376.a69c2e5a.js +0 -1
- package/__mf/js/async/738.2cdddba7.js +0 -1
- package/__mf/js/async/7740.1ecb3732.js +0 -1
- package/__mf/js/async/7832.9f2a70d0.js +0 -7
- package/__mf/js/async/8485.434a672e.js +0 -28
- package/__mf/js/async/8488.d3005164.js +0 -1
- package/__mf/js/async/8597.07c3a890.js +0 -1
- package/__mf/js/async/8930.ae855fbe.js +0 -1
- package/__mf/js/async/9173.83562213.js +0 -2
- package/__mf/js/async/9478.57f45cd9.js +0 -2
- package/__mf/js/async/__federation_expose_TempoDatasource.4f96e206.js +0 -2
- package/__mf/js/async/__federation_expose_TempoExplorer.eb09c758.js +0 -2
- package/__mf/js/async/__federation_expose_TempoTraceQuery.4183e294.js +0 -1
- package/__mf/js/async/lib-router.46460b13.js +0 -2
- package/__mf/js/main.4498dd88.js +0 -1
- /package/__mf/css/async/{4758.c10cf504.css → 1576.c10cf504.css} +0 -0
- /package/__mf/css/async/{5207.c10cf504.css → 9314.c10cf504.css} +0 -0
- /package/__mf/js/async/{5913.d10c6185.js.LICENSE.txt → 1101.0dae4724.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{1964.75933dd4.js.LICENSE.txt → 1964.e6c5b93b.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{3090.90251187.js.LICENSE.txt → 2292.75e9aa11.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{1620.45989def.js.LICENSE.txt → 2981.8fe4ed12.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{2823.df67fd4b.js.LICENSE.txt → 3863.8d56ecec.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{3960.2228bf7e.js.LICENSE.txt → 3960.401ff0b0.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{3980.c94e78cd.js.LICENSE.txt → 3980.4d5490b2.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{3828.d981b319.js.LICENSE.txt → 4269.0cfaf9bb.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{5220.80e3b05e.js.LICENSE.txt → 5266.1c520126.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{5981.4700ddf6.js.LICENSE.txt → 5981.c6edce96.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{5207.e63b049c.js.LICENSE.txt → 6333.367d6758.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{5924.bfb4b2fd.js.LICENSE.txt → 6527.5341d09f.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{9173.83562213.js.LICENSE.txt → 9173.69dc268d.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{9478.57f45cd9.js.LICENSE.txt → 9314.4b8565a0.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{__federation_expose_TempoDatasource.4f96e206.js.LICENSE.txt → __federation_expose_TempoDatasource.fa3e24f9.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{__federation_expose_TempoExplorer.eb09c758.js.LICENSE.txt → __federation_expose_TempoExplorer.9949b25e.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{lib-router.46460b13.js.LICENSE.txt → lib-router.312ca028.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/filter/traceql_to_filter.ts"],"sourcesContent":["import { AttributeField, FieldExpression, FieldOp, IntrinsicField, Static, parser } from '@grafana/lezer-traceql';\nimport { DurationField, Filter } from './filter';\n\ninterface Matcher {\n operator: string;\n value: string;\n}\n\n/**\n * Construct a Filter from a TraceQL query.\n * 1. Parse the query (using Lezer library) and extract all matchers, e.g. 'some_attribute = \"some_value\"'\n * 2. Create the filter attribute values, a string array with a single value (for 'x = \"y\"') or multiple values (for 'x =~ \"y|z\"')\n * 3. Add the remaining matchers to the set of custom matchers.\n */\nexport function traceQLToFilter(query: string): Filter {\n const matchers = parseQuery(query);\n return {\n serviceName: reverseStringMatcher(matchers['resource.service.name']),\n spanName: reverseStringMatcher(matchers['name']),\n namespace: reverseStringMatcher(matchers['resource.k8s.namespace.name']),\n status: reverseIntrinsicMatcher(matchers['status']),\n spanDuration: reverseDurationMatcher(matchers['duration']),\n traceDuration: reverseDurationMatcher(matchers['traceDuration']),\n customMatchers: reverseCustomMatcher(\n matchers,\n new Set(['resource.service.name', 'name', 'resource.k8s.namespace.name', 'status', 'duration', 'traceDuration'])\n ),\n };\n}\n\nfunction parseQuery(query: string) {\n const matchers: Record<string, Matcher[]> = {};\n let attribute = '';\n let operator = '';\n let value = '';\n\n const syntaxTree = parser.parse(query);\n syntaxTree.iterate({\n enter(node) {\n switch (node.type.id) {\n case AttributeField:\n attribute = query.slice(node.from, node.to);\n return false;\n case IntrinsicField:\n attribute = query.slice(node.from, node.to);\n return false;\n case FieldOp:\n operator = query.slice(node.from, node.to);\n return false;\n case Static:\n value = query.slice(node.from, node.to);\n return false;\n }\n },\n leave(node) {\n if (node.type.id === FieldExpression && node.node.getChild(FieldOp)) {\n const newMatchers = matchers[attribute] ?? [];\n newMatchers.push({ operator, value });\n matchers[attribute] = newMatchers;\n }\n },\n });\n\n return matchers;\n}\n\nfunction unescape(q: string) {\n return q.replaceAll('\\\\\"', '\"').replaceAll('\\\\\\\\', '\\\\');\n}\n\nfunction reverseStringMatcher(matches?: Matcher[]) {\n const values: string[] = [];\n for (const { operator, value } of matches ?? []) {\n const unescaped = unescape(value.slice(1, -1));\n if (operator == '=') {\n values.push(unescaped);\n } else if (operator == '=~') {\n values.push(...unescaped.split('|'));\n }\n }\n return values;\n}\n\nfunction reverseIntrinsicMatcher(matches?: Matcher[]) {\n const values: string[] = [];\n for (const { operator, value } of matches ?? []) {\n if (operator == '=') {\n values.push(value);\n }\n }\n return values;\n}\n\nfunction reverseDurationMatcher(matches?: Matcher[]) {\n const duration: DurationField = {};\n for (const { operator, value } of matches ?? []) {\n if (operator == '>=') {\n duration.min = value;\n } else if (operator == '<=') {\n duration.max = value;\n }\n }\n return duration;\n}\n\nfunction reverseCustomMatcher(matchers: Record<string, Matcher[]>, skipAttrs: Set<string>) {\n const customMatchers: string[] = [];\n for (const [attribute, matches] of Object.entries(matchers)) {\n if (skipAttrs.has(attribute)) {\n continue;\n }\n\n for (const { operator, value } of matches) {\n customMatchers.push(`${attribute}${operator}${value}`);\n }\n }\n return customMatchers;\n}\n"],"names":["AttributeField","FieldExpression","FieldOp","IntrinsicField","Static","parser","traceQLToFilter","query","matchers","parseQuery","serviceName","reverseStringMatcher","spanName","namespace","status","reverseIntrinsicMatcher","spanDuration","reverseDurationMatcher","traceDuration","customMatchers","reverseCustomMatcher","Set","attribute","operator","value","syntaxTree","parse","iterate","enter","node","type","id","slice","from","to","leave","getChild","newMatchers","push","unescape","q","replaceAll","matches","values","unescaped","split","duration","min","max","skipAttrs","Object","entries","has"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"AAaA,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"AAaA,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC"}
|
package/lib/components/index.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
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
|
+
export * from './filter';
|
|
13
14
|
export * from './TraceQLEditor';
|
|
14
15
|
export * from './TraceQLExtension';
|
|
15
16
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/index.ts"],"sourcesContent":["// Copyright 2024 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\nexport * from './TraceQLEditor';\nexport * from './TraceQLExtension';\n"],"names":[],"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,cAAc,kBAAkB;AAChC,cAAc,qBAAqB"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/index.ts"],"sourcesContent":["// Copyright 2024 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\nexport * from './filter';\nexport * from './TraceQLEditor';\nexport * from './TraceQLExtension';\n"],"names":[],"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,cAAc,WAAW;AACzB,cAAc,kBAAkB;AAChC,cAAc,qBAAqB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TempoExplorer.d.ts","sourceRoot":"","sources":["../../../src/explore/TempoExplorer.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"TempoExplorer.d.ts","sourceRoot":"","sources":["../../../src/explore/TempoExplorer.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAkHrC,wBAAgB,aAAa,IAAI,YAAY,CAwC5C"}
|
|
@@ -17,6 +17,7 @@ import { isValidTraceId } from '@perses-dev/core';
|
|
|
17
17
|
import { Panel } from '@perses-dev/dashboards';
|
|
18
18
|
import { useExplorerManagerContext } from '@perses-dev/explore';
|
|
19
19
|
import { DataQueriesProvider, MultiQueryEditor, useDataQueries } from '@perses-dev/plugin-system';
|
|
20
|
+
import { linkToSpan, linkToTrace } from './links';
|
|
20
21
|
function SearchResultsPanel({ queries }) {
|
|
21
22
|
const { isFetching, isLoading, queryResults } = useDataQueries('TraceQuery');
|
|
22
23
|
// no query executed, show empty panel
|
|
@@ -60,7 +61,9 @@ function SearchResultsPanel({ queries }) {
|
|
|
60
61
|
},
|
|
61
62
|
plugin: {
|
|
62
63
|
kind: 'ScatterChart',
|
|
63
|
-
spec: {
|
|
64
|
+
spec: {
|
|
65
|
+
link: linkToTrace
|
|
66
|
+
}
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
69
|
}
|
|
@@ -82,7 +85,11 @@ function SearchResultsPanel({ queries }) {
|
|
|
82
85
|
},
|
|
83
86
|
plugin: {
|
|
84
87
|
kind: 'TraceTable',
|
|
85
|
-
spec: {
|
|
88
|
+
spec: {
|
|
89
|
+
links: {
|
|
90
|
+
trace: linkToTrace
|
|
91
|
+
}
|
|
92
|
+
}
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
95
|
}
|
|
@@ -90,28 +97,33 @@ function SearchResultsPanel({ queries }) {
|
|
|
90
97
|
]
|
|
91
98
|
});
|
|
92
99
|
}
|
|
93
|
-
function TracingGanttChartPanel(
|
|
100
|
+
function TracingGanttChartPanel(props) {
|
|
101
|
+
const { queries, selectedSpanId } = props;
|
|
102
|
+
const firstQuery = queries[0]?.spec.plugin.spec?.query;
|
|
94
103
|
return /*#__PURE__*/ _jsx(Panel, {
|
|
95
|
-
panelOptions: {
|
|
96
|
-
hideHeader: true
|
|
97
|
-
},
|
|
98
104
|
definition: {
|
|
99
105
|
kind: 'Panel',
|
|
100
106
|
spec: {
|
|
101
107
|
queries,
|
|
102
108
|
display: {
|
|
103
|
-
name:
|
|
109
|
+
name: `Trace ${firstQuery}`
|
|
104
110
|
},
|
|
105
111
|
plugin: {
|
|
106
112
|
kind: 'TracingGanttChart',
|
|
107
|
-
spec: {
|
|
113
|
+
spec: {
|
|
114
|
+
links: {
|
|
115
|
+
trace: linkToTrace,
|
|
116
|
+
span: linkToSpan
|
|
117
|
+
},
|
|
118
|
+
selectedSpanId
|
|
119
|
+
}
|
|
108
120
|
}
|
|
109
121
|
}
|
|
110
122
|
}
|
|
111
123
|
});
|
|
112
124
|
}
|
|
113
125
|
export function TempoExplorer() {
|
|
114
|
-
const { data: { queries = [] }, setData } = useExplorerManagerContext();
|
|
126
|
+
const { data: { queries = [], spanId: selectedSpanId }, setData } = useExplorerManagerContext();
|
|
115
127
|
// map TraceQueryDefinition to Definition<UnknownSpec>
|
|
116
128
|
const definitions = queries.length ? queries.map((query)=>{
|
|
117
129
|
return {
|
|
@@ -119,8 +131,8 @@ export function TempoExplorer() {
|
|
|
119
131
|
spec: query.spec.plugin.spec
|
|
120
132
|
};
|
|
121
133
|
}) : [];
|
|
122
|
-
|
|
123
|
-
const isSingleTrace =
|
|
134
|
+
const firstQuery = queries[0]?.spec.plugin.spec?.query;
|
|
135
|
+
const isSingleTrace = isValidTraceId(firstQuery ?? '');
|
|
124
136
|
return /*#__PURE__*/ _jsxs(Stack, {
|
|
125
137
|
gap: 2,
|
|
126
138
|
sx: {
|
|
@@ -146,7 +158,8 @@ export function TempoExplorer() {
|
|
|
146
158
|
children: /*#__PURE__*/ _jsx(Box, {
|
|
147
159
|
height: 700,
|
|
148
160
|
children: isSingleTrace ? /*#__PURE__*/ _jsx(TracingGanttChartPanel, {
|
|
149
|
-
queries: queries
|
|
161
|
+
queries: queries,
|
|
162
|
+
selectedSpanId: selectedSpanId
|
|
150
163
|
}) : /*#__PURE__*/ _jsx(SearchResultsPanel, {
|
|
151
164
|
queries: queries
|
|
152
165
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/explore/TempoExplorer.tsx"],"sourcesContent":["// Copyright 2024 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 { Box, Stack } from '@mui/material';\nimport { ErrorAlert, ErrorBoundary, LoadingOverlay, NoDataOverlay } from '@perses-dev/components';\nimport { QueryDefinition, isValidTraceId } from '@perses-dev/core';\nimport { Panel } from '@perses-dev/dashboards';\nimport { useExplorerManagerContext } from '@perses-dev/explore';\nimport { DataQueriesProvider, MultiQueryEditor, useDataQueries } from '@perses-dev/plugin-system';\nimport { ReactElement } from 'react';\n\ninterface TracesExplorerQueryParams {\n queries?: QueryDefinition[];\n}\n\ninterface SearchResultsPanelProps {\n queries: QueryDefinition[];\n}\n\nfunction SearchResultsPanel({ queries }: SearchResultsPanelProps): ReactElement {\n const { isFetching, isLoading, queryResults } = useDataQueries('TraceQuery');\n\n // no query executed, show empty panel\n if (queryResults.length === 0) {\n return <></>;\n }\n\n if (isLoading || isFetching) {\n return <LoadingOverlay />;\n }\n\n const queryError = queryResults.find((d) => d.error);\n if (queryError) {\n throw queryError.error;\n }\n\n const tracesFound = queryResults.some((traceData) => (traceData.data?.searchResult ?? []).length > 0);\n if (!tracesFound) {\n return <NoDataOverlay resource=\"traces\" />;\n }\n\n return (\n <Stack sx={{ height: '100%' }} gap={2}>\n <Box sx={{ height: '35%', flexShrink: 0 }}>\n <Panel\n panelOptions={{\n hideHeader: true,\n }}\n definition={{\n kind: 'Panel',\n spec: {
|
|
1
|
+
{"version":3,"sources":["../../../src/explore/TempoExplorer.tsx"],"sourcesContent":["// Copyright 2024 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 { Box, Stack } from '@mui/material';\nimport { ErrorAlert, ErrorBoundary, LoadingOverlay, NoDataOverlay } from '@perses-dev/components';\nimport { QueryDefinition, isValidTraceId } from '@perses-dev/core';\nimport { Panel } from '@perses-dev/dashboards';\nimport { useExplorerManagerContext } from '@perses-dev/explore';\nimport { DataQueriesProvider, MultiQueryEditor, useDataQueries } from '@perses-dev/plugin-system';\nimport { ReactElement } from 'react';\nimport { TempoTraceQuerySpec } from '../model';\nimport { linkToSpan, linkToTrace } from './links';\n\ninterface TracesExplorerQueryParams {\n queries?: QueryDefinition[];\n spanId?: string;\n}\n\ninterface SearchResultsPanelProps {\n queries: QueryDefinition[];\n}\n\nfunction SearchResultsPanel({ queries }: SearchResultsPanelProps): ReactElement {\n const { isFetching, isLoading, queryResults } = useDataQueries('TraceQuery');\n\n // no query executed, show empty panel\n if (queryResults.length === 0) {\n return <></>;\n }\n\n if (isLoading || isFetching) {\n return <LoadingOverlay />;\n }\n\n const queryError = queryResults.find((d) => d.error);\n if (queryError) {\n throw queryError.error;\n }\n\n const tracesFound = queryResults.some((traceData) => (traceData.data?.searchResult ?? []).length > 0);\n if (!tracesFound) {\n return <NoDataOverlay resource=\"traces\" />;\n }\n\n return (\n <Stack sx={{ height: '100%' }} gap={2}>\n <Box sx={{ height: '35%', flexShrink: 0 }}>\n <Panel\n panelOptions={{\n hideHeader: true,\n }}\n definition={{\n kind: 'Panel',\n spec: {\n queries,\n display: { name: '' },\n plugin: {\n kind: 'ScatterChart',\n spec: {\n link: linkToTrace,\n },\n },\n },\n }}\n />\n </Box>\n <Panel\n sx={{ flexGrow: 1 }}\n panelOptions={{\n hideHeader: true,\n }}\n definition={{\n kind: 'Panel',\n spec: {\n queries,\n display: { name: '' },\n plugin: {\n kind: 'TraceTable',\n spec: {\n links: {\n trace: linkToTrace,\n },\n },\n },\n },\n }}\n />\n </Stack>\n );\n}\n\ninterface TracingGanttChartPanelProps {\n queries: QueryDefinition[];\n selectedSpanId?: string;\n}\n\nfunction TracingGanttChartPanel(props: TracingGanttChartPanelProps): ReactElement {\n const { queries, selectedSpanId } = props;\n const firstQuery = (queries[0]?.spec.plugin.spec as TempoTraceQuerySpec | undefined)?.query;\n\n return (\n <Panel\n definition={{\n kind: 'Panel',\n spec: {\n queries,\n display: { name: `Trace ${firstQuery}` },\n plugin: {\n kind: 'TracingGanttChart',\n spec: {\n links: {\n trace: linkToTrace,\n span: linkToSpan,\n },\n selectedSpanId,\n },\n },\n },\n }}\n />\n );\n}\n\nexport function TempoExplorer(): ReactElement {\n const {\n data: { queries = [], spanId: selectedSpanId },\n setData,\n } = useExplorerManagerContext<TracesExplorerQueryParams>();\n\n // map TraceQueryDefinition to Definition<UnknownSpec>\n const definitions = queries.length\n ? queries.map((query: QueryDefinition) => {\n return {\n kind: query.spec.plugin.kind,\n spec: query.spec.plugin.spec,\n };\n })\n : [];\n\n const firstQuery = (queries[0]?.spec.plugin.spec as TempoTraceQuerySpec | undefined)?.query;\n const isSingleTrace = isValidTraceId(firstQuery ?? '');\n\n return (\n <Stack gap={2} sx={{ width: '100%' }}>\n <MultiQueryEditor\n queryTypes={['TraceQuery']}\n onChange={(newQueries) => setData({ queries: newQueries })}\n queries={queries}\n />\n\n <ErrorBoundary FallbackComponent={ErrorAlert} resetKeys={[queries]}>\n <DataQueriesProvider definitions={definitions}>\n <Box height={700}>\n {isSingleTrace ? (\n <TracingGanttChartPanel queries={queries} selectedSpanId={selectedSpanId} />\n ) : (\n <SearchResultsPanel queries={queries} />\n )}\n </Box>\n </DataQueriesProvider>\n </ErrorBoundary>\n </Stack>\n );\n}\n"],"names":["Box","Stack","ErrorAlert","ErrorBoundary","LoadingOverlay","NoDataOverlay","isValidTraceId","Panel","useExplorerManagerContext","DataQueriesProvider","MultiQueryEditor","useDataQueries","linkToSpan","linkToTrace","SearchResultsPanel","queries","isFetching","isLoading","queryResults","length","queryError","find","d","error","tracesFound","some","traceData","data","searchResult","resource","sx","height","gap","flexShrink","panelOptions","hideHeader","definition","kind","spec","display","name","plugin","link","flexGrow","links","trace","TracingGanttChartPanel","props","selectedSpanId","firstQuery","query","span","TempoExplorer","spanId","setData","definitions","map","isSingleTrace","width","queryTypes","onChange","newQueries","FallbackComponent","resetKeys"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../../src/explore/links.ts"],"names":[],"mappings":"AA6DA,eAAO,MAAM,WAAW,QAEW,CAAC;AAGpC,eAAO,MAAM,UAAU,QAGU,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Copyright 2025 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
const linkToTraceParams = new URLSearchParams({
|
|
14
|
+
explorer: 'Tempo-TempoExplorer',
|
|
15
|
+
data: JSON.stringify({
|
|
16
|
+
queries: [
|
|
17
|
+
{
|
|
18
|
+
kind: 'TraceQuery',
|
|
19
|
+
spec: {
|
|
20
|
+
plugin: {
|
|
21
|
+
kind: 'TempoTraceQuery',
|
|
22
|
+
spec: {
|
|
23
|
+
query: 'TRACEID',
|
|
24
|
+
datasource: {
|
|
25
|
+
kind: 'TempoDatasource',
|
|
26
|
+
name: 'DATASOURCENAME'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
const linkToSpanParams = new URLSearchParams({
|
|
36
|
+
explorer: 'Tempo-TempoExplorer',
|
|
37
|
+
data: JSON.stringify({
|
|
38
|
+
queries: [
|
|
39
|
+
{
|
|
40
|
+
kind: 'TraceQuery',
|
|
41
|
+
spec: {
|
|
42
|
+
plugin: {
|
|
43
|
+
kind: 'TempoTraceQuery',
|
|
44
|
+
spec: {
|
|
45
|
+
query: 'TRACEID',
|
|
46
|
+
datasource: {
|
|
47
|
+
kind: 'TempoDatasource',
|
|
48
|
+
name: 'DATASOURCENAME'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
spanId: 'SPANID'
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
// add ${...} syntax after the URL is URL-encoded, because the characters ${} must not be URL-encoded
|
|
59
|
+
export const linkToTrace = `/explore?${linkToTraceParams}`.replace('DATASOURCENAME', '${datasourceName}').replace('TRACEID', '${traceId}');
|
|
60
|
+
// add ${...} syntax after the URL is URL-encoded, because the characters ${} must not be URL-encoded
|
|
61
|
+
export const linkToSpan = `/explore?${linkToSpanParams}`.replace('DATASOURCENAME', '${datasourceName}').replace('TRACEID', '${traceId}').replace('SPANID', '${spanId}');
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/explore/links.ts"],"sourcesContent":["// Copyright 2025 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\nconst linkToTraceParams = new URLSearchParams({\n explorer: 'Tempo-TempoExplorer',\n data: JSON.stringify({\n queries: [\n {\n kind: 'TraceQuery',\n spec: {\n plugin: {\n kind: 'TempoTraceQuery',\n spec: {\n query: 'TRACEID',\n datasource: {\n kind: 'TempoDatasource',\n name: 'DATASOURCENAME',\n },\n },\n },\n },\n },\n ],\n }),\n});\n\nconst linkToSpanParams = new URLSearchParams({\n explorer: 'Tempo-TempoExplorer',\n data: JSON.stringify({\n queries: [\n {\n kind: 'TraceQuery',\n spec: {\n plugin: {\n kind: 'TempoTraceQuery',\n spec: {\n query: 'TRACEID',\n datasource: {\n kind: 'TempoDatasource',\n name: 'DATASOURCENAME',\n },\n },\n },\n },\n },\n ],\n spanId: 'SPANID',\n }),\n});\n\n// add ${...} syntax after the URL is URL-encoded, because the characters ${} must not be URL-encoded\nexport const linkToTrace = `/explore?${linkToTraceParams}`\n .replace('DATASOURCENAME', '${datasourceName}')\n .replace('TRACEID', '${traceId}');\n\n// add ${...} syntax after the URL is URL-encoded, because the characters ${} must not be URL-encoded\nexport const linkToSpan = `/explore?${linkToSpanParams}`\n .replace('DATASOURCENAME', '${datasourceName}')\n .replace('TRACEID', '${traceId}')\n .replace('SPANID', '${spanId}');\n"],"names":["linkToTraceParams","URLSearchParams","explorer","data","JSON","stringify","queries","kind","spec","plugin","query","datasource","name","linkToSpanParams","spanId","linkToTrace","replace","linkToSpan"],"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,MAAMA,oBAAoB,IAAIC,gBAAgB;IAC5CC,UAAU;IACVC,MAAMC,KAAKC,SAAS,CAAC;QACnBC,SAAS;YACP;gBACEC,MAAM;gBACNC,MAAM;oBACJC,QAAQ;wBACNF,MAAM;wBACNC,MAAM;4BACJE,OAAO;4BACPC,YAAY;gCACVJ,MAAM;gCACNK,MAAM;4BACR;wBACF;oBACF;gBACF;YACF;SACD;IACH;AACF;AAEA,MAAMC,mBAAmB,IAAIZ,gBAAgB;IAC3CC,UAAU;IACVC,MAAMC,KAAKC,SAAS,CAAC;QACnBC,SAAS;YACP;gBACEC,MAAM;gBACNC,MAAM;oBACJC,QAAQ;wBACNF,MAAM;wBACNC,MAAM;4BACJE,OAAO;4BACPC,YAAY;gCACVJ,MAAM;gCACNK,MAAM;4BACR;wBACF;oBACF;gBACF;YACF;SACD;QACDE,QAAQ;IACV;AACF;AAEA,qGAAqG;AACrG,OAAO,MAAMC,cAAc,CAAC,SAAS,EAAEf,mBAAmB,CACvDgB,OAAO,CAAC,kBAAkB,qBAC1BA,OAAO,CAAC,WAAW,cAAc;AAEpC,qGAAqG;AACrG,OAAO,MAAMC,aAAa,CAAC,SAAS,EAAEJ,kBAAkB,CACrDG,OAAO,CAAC,kBAAkB,qBAC1BA,OAAO,CAAC,WAAW,cACnBA,OAAO,CAAC,UAAU,aAAa"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
import { TraceQueryEditorProps } from './query-editor-model';
|
|
3
3
|
export declare function TempoTraceQueryEditor(props: TraceQueryEditorProps): ReactElement;
|
|
4
|
+
interface LimitSelectProps {
|
|
5
|
+
value: number;
|
|
6
|
+
setValue: (x: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function LimitSelect(props: LimitSelectProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
4
10
|
//# sourceMappingURL=TempoTraceQueryEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TempoTraceQueryEditor.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tempo-trace-query/TempoTraceQueryEditor.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TempoTraceQueryEditor.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tempo-trace-query/TempoTraceQueryEditor.tsx"],"names":[],"mappings":"AAsBA,OAAO,EAAE,YAAY,EAAyB,MAAM,OAAO,CAAC;AAY5D,OAAO,EAAE,qBAAqB,EAAiB,MAAM,sBAAsB,CAAC;AAE5E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CA2FhF;AASD,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CAyBlD"}
|
|
@@ -11,33 +11,25 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
import { FormControl,
|
|
14
|
+
import { Box, Button, FormControl, InputLabel, MenuItem, Select, Stack } from '@mui/material';
|
|
15
15
|
import { useId } from '@perses-dev/components';
|
|
16
|
-
import { DatasourceSelect, useDatasourceClient, useDatasourceSelectValueToSelector
|
|
16
|
+
import { DatasourceSelect, useDatasourceClient, useDatasourceSelectValueToSelector } from '@perses-dev/plugin-system';
|
|
17
17
|
import { produce } from 'immer';
|
|
18
|
-
import {
|
|
18
|
+
import { useCallback, useState } from 'react';
|
|
19
19
|
import { TraceQLEditor } from '../../components';
|
|
20
20
|
import { DEFAULT_TEMPO, isDefaultTempoSelector, isTempoDatasourceSelector, TEMPO_DATASOURCE_KIND } from '../../model/tempo-selectors';
|
|
21
|
-
import {
|
|
21
|
+
import { AttributeFilters } from '../../components/AttributeFilters';
|
|
22
|
+
import { filterToTraceQL } from '../../components/filter/filter_to_traceql';
|
|
23
|
+
import { traceQLToFilter } from '../../components/filter/traceql_to_filter';
|
|
24
|
+
import { useQueryState } from './query-editor-model';
|
|
22
25
|
export function TempoTraceQueryEditor(props) {
|
|
23
|
-
const { onChange, value } = props;
|
|
24
|
-
const { datasource } = value;
|
|
26
|
+
const { onChange, value, value: { datasource, limit }, queryHandlerSettings } = props;
|
|
25
27
|
const datasourceSelectValue = datasource ?? DEFAULT_TEMPO;
|
|
26
28
|
const selectedDatasource = useDatasourceSelectValueToSelector(datasourceSelectValue, TEMPO_DATASOURCE_KIND);
|
|
27
29
|
const datasourceSelectLabelID = useId('tempo-datasource-label'); // for panels with multiple queries, this component is rendered multiple times on the same page
|
|
28
30
|
const { data: client } = useDatasourceClient(selectedDatasource);
|
|
29
|
-
const { timeRange } = useTimeRange();
|
|
30
|
-
const completionConfig = useMemo(()=>{
|
|
31
|
-
return {
|
|
32
|
-
client,
|
|
33
|
-
timeRange
|
|
34
|
-
};
|
|
35
|
-
}, [
|
|
36
|
-
client,
|
|
37
|
-
timeRange
|
|
38
|
-
]);
|
|
39
31
|
const { query, handleQueryChange, handleQueryBlur } = useQueryState(props);
|
|
40
|
-
const
|
|
32
|
+
const [showAttributeFilters, setShowAttributeFilters] = useState(()=>isSimpleTraceQLQuery(query));
|
|
41
33
|
const handleDatasourceChange = (next)=>{
|
|
42
34
|
if (isTempoDatasourceSelector(next)) {
|
|
43
35
|
onChange(produce(value, (draft)=>{
|
|
@@ -49,6 +41,23 @@ export function TempoTraceQueryEditor(props) {
|
|
|
49
41
|
}
|
|
50
42
|
throw new Error('Got unexpected non-Tempo datasource selector');
|
|
51
43
|
};
|
|
44
|
+
const runQuery = (newQuery)=>{
|
|
45
|
+
if (queryHandlerSettings?.watchQueryChanges) {
|
|
46
|
+
queryHandlerSettings.watchQueryChanges(newQuery);
|
|
47
|
+
}
|
|
48
|
+
onChange(produce(value, (draft)=>{
|
|
49
|
+
draft.query = newQuery;
|
|
50
|
+
}));
|
|
51
|
+
};
|
|
52
|
+
const handleTraceQueryChange = useCallback((e)=>{
|
|
53
|
+
handleQueryChange(e);
|
|
54
|
+
if (queryHandlerSettings?.watchQueryChanges) {
|
|
55
|
+
queryHandlerSettings.watchQueryChanges(e);
|
|
56
|
+
}
|
|
57
|
+
}, [
|
|
58
|
+
handleQueryChange,
|
|
59
|
+
queryHandlerSettings
|
|
60
|
+
]);
|
|
52
61
|
return /*#__PURE__*/ _jsxs(Stack, {
|
|
53
62
|
spacing: 2,
|
|
54
63
|
children: [
|
|
@@ -67,28 +76,75 @@ export function TempoTraceQueryEditor(props) {
|
|
|
67
76
|
/*#__PURE__*/ _jsxs(Stack, {
|
|
68
77
|
direction: "row",
|
|
69
78
|
spacing: 2,
|
|
79
|
+
sx: {
|
|
80
|
+
alignItems: 'flex-start'
|
|
81
|
+
},
|
|
70
82
|
children: [
|
|
71
|
-
/*#__PURE__*/ _jsx(
|
|
72
|
-
|
|
83
|
+
showAttributeFilters ? /*#__PURE__*/ _jsx(AttributeFilters, {
|
|
84
|
+
client: client,
|
|
85
|
+
query: query,
|
|
86
|
+
setQuery: runQuery
|
|
87
|
+
}) : /*#__PURE__*/ _jsx(TraceQLEditor, {
|
|
88
|
+
client: client,
|
|
73
89
|
value: query,
|
|
74
|
-
onChange:
|
|
75
|
-
onBlur: handleQueryBlur
|
|
90
|
+
onChange: handleTraceQueryChange,
|
|
91
|
+
onBlur: queryHandlerSettings?.runWithOnBlur ? handleQueryBlur : undefined
|
|
92
|
+
}),
|
|
93
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
94
|
+
onClick: ()=>setShowAttributeFilters(!showAttributeFilters),
|
|
95
|
+
children: showAttributeFilters ? 'Show query' : 'Hide query'
|
|
76
96
|
}),
|
|
77
|
-
/*#__PURE__*/ _jsx(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
onChange: (e)=>handleLimitChange(e.target.value),
|
|
83
|
-
onBlur: handleLimitBlur,
|
|
84
|
-
sx: {
|
|
85
|
-
width: '110px'
|
|
86
|
-
}
|
|
97
|
+
/*#__PURE__*/ _jsx(LimitSelect, {
|
|
98
|
+
value: limit ?? 20,
|
|
99
|
+
setValue: (newLimit)=>onChange(produce(value, (draft)=>{
|
|
100
|
+
draft.limit = newLimit;
|
|
101
|
+
}))
|
|
87
102
|
})
|
|
88
103
|
]
|
|
89
104
|
})
|
|
90
105
|
]
|
|
91
106
|
});
|
|
92
107
|
}
|
|
108
|
+
function isSimpleTraceQLQuery(query) {
|
|
109
|
+
// if a query can be transformed to a filter and back to the original query, we can show the attribute filter toolbar
|
|
110
|
+
return query == '' || filterToTraceQL(traceQLToFilter(query)) === query;
|
|
111
|
+
}
|
|
112
|
+
const limitOptions = [
|
|
113
|
+
20,
|
|
114
|
+
50,
|
|
115
|
+
100,
|
|
116
|
+
500,
|
|
117
|
+
1000,
|
|
118
|
+
5000
|
|
119
|
+
];
|
|
120
|
+
export function LimitSelect(props) {
|
|
121
|
+
const { value, setValue } = props;
|
|
122
|
+
// the outer <Box> is required, because <FormControl> has display: inline-flex, which doesn't work with the parent <Stack> of the query editor
|
|
123
|
+
return /*#__PURE__*/ _jsx(Box, {
|
|
124
|
+
children: /*#__PURE__*/ _jsxs(FormControl, {
|
|
125
|
+
size: "small",
|
|
126
|
+
children: [
|
|
127
|
+
/*#__PURE__*/ _jsx(InputLabel, {
|
|
128
|
+
id: "max-traces-label",
|
|
129
|
+
children: "Max Traces"
|
|
130
|
+
}),
|
|
131
|
+
/*#__PURE__*/ _jsx(Select, {
|
|
132
|
+
labelId: "max-traces-label",
|
|
133
|
+
id: "max-traces-select",
|
|
134
|
+
value: value,
|
|
135
|
+
label: "Max Traces",
|
|
136
|
+
onChange: (e)=>setValue(typeof e.target.value === 'number' ? e.target.value : parseInt(e.target.value)),
|
|
137
|
+
sx: {
|
|
138
|
+
width: 110
|
|
139
|
+
},
|
|
140
|
+
children: limitOptions.map((option)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
141
|
+
value: option,
|
|
142
|
+
children: option
|
|
143
|
+
}, option))
|
|
144
|
+
})
|
|
145
|
+
]
|
|
146
|
+
})
|
|
147
|
+
});
|
|
148
|
+
}
|
|
93
149
|
|
|
94
150
|
//# sourceMappingURL=TempoTraceQueryEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/plugins/tempo-trace-query/TempoTraceQueryEditor.tsx"],"sourcesContent":["// Copyright 2025 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 { FormControl, Stack, TextField } from '@mui/material';\nimport { useId } from '@perses-dev/components';\nimport {\n DatasourceSelect,\n DatasourceSelectProps,\n useDatasourceClient,\n useDatasourceSelectValueToSelector,\n useTimeRange,\n} from '@perses-dev/plugin-system';\nimport { produce } from 'immer';\nimport { ReactElement, useMemo } from 'react';\nimport { TraceQLEditor } from '../../components';\nimport { TempoClient } from '../../model/tempo-client';\nimport {\n DEFAULT_TEMPO,\n isDefaultTempoSelector,\n isTempoDatasourceSelector,\n TEMPO_DATASOURCE_KIND,\n} from '../../model/tempo-selectors';\nimport { TraceQueryEditorProps, useLimitState, useQueryState } from './query-editor-model';\n\nexport function TempoTraceQueryEditor(props: TraceQueryEditorProps): ReactElement {\n const { onChange, value } = props;\n const { datasource } = value;\n const datasourceSelectValue = datasource ?? DEFAULT_TEMPO;\n const selectedDatasource = useDatasourceSelectValueToSelector(datasourceSelectValue, TEMPO_DATASOURCE_KIND);\n const datasourceSelectLabelID = useId('tempo-datasource-label'); // for panels with multiple queries, this component is rendered multiple times on the same page\n\n const { data: client } = useDatasourceClient<TempoClient>(selectedDatasource);\n const { timeRange } = useTimeRange();\n const completionConfig = useMemo(() => {\n return { client, timeRange };\n }, [client, timeRange]);\n\n const { query, handleQueryChange, handleQueryBlur } = useQueryState(props);\n const { limit, handleLimitChange, handleLimitBlur, limitHasError } = useLimitState(props);\n\n const handleDatasourceChange: DatasourceSelectProps['onChange'] = (next) => {\n if (isTempoDatasourceSelector(next)) {\n onChange(\n produce(value, (draft) => {\n // If they're using the default, just omit the datasource prop (i.e. set to undefined)\n const nextDatasource = isDefaultTempoSelector(next) ? undefined : next;\n draft.datasource = nextDatasource;\n })\n );\n return;\n }\n\n throw new Error('Got unexpected non-Tempo datasource selector');\n };\n\n return (\n <Stack spacing={2}>\n <FormControl margin=\"dense\" fullWidth={false}>\n <DatasourceSelect\n datasourcePluginKind={TEMPO_DATASOURCE_KIND}\n value={datasourceSelectValue}\n onChange={handleDatasourceChange}\n labelId={datasourceSelectLabelID}\n label=\"Tempo Datasource\"\n notched\n />\n </FormControl>\n <Stack direction=\"row\" spacing={2}>\n <TraceQLEditor\n completionConfig={completionConfig}\n value={query}\n onChange={handleQueryChange}\n onBlur={handleQueryBlur}\n />\n <TextField\n size=\"small\"\n label=\"Max Traces\"\n value={limit}\n error={limitHasError}\n onChange={(e) => handleLimitChange(e.target.value)}\n onBlur={handleLimitBlur}\n sx={{ width: '110px' }}\n />\n </Stack>\n </Stack>\n );\n}\n"],"names":["FormControl","Stack","TextField","useId","DatasourceSelect","useDatasourceClient","useDatasourceSelectValueToSelector","useTimeRange","produce","useMemo","TraceQLEditor","DEFAULT_TEMPO","isDefaultTempoSelector","isTempoDatasourceSelector","TEMPO_DATASOURCE_KIND","useLimitState","useQueryState","TempoTraceQueryEditor","props","onChange","value","datasource","datasourceSelectValue","selectedDatasource","datasourceSelectLabelID","data","client","timeRange","completionConfig","query","handleQueryChange","handleQueryBlur","limit","handleLimitChange","handleLimitBlur","limitHasError","handleDatasourceChange","next","draft","nextDatasource","undefined","Error","spacing","margin","fullWidth","datasourcePluginKind","labelId","label","notched","direction","onBlur","size","error","e","target","sx","width"],"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,WAAW,EAAEC,KAAK,EAAEC,SAAS,QAAQ,gBAAgB;AAC9D,SAASC,KAAK,QAAQ,yBAAyB;AAC/C,SACEC,gBAAgB,EAEhBC,mBAAmB,EACnBC,kCAAkC,EAClCC,YAAY,QACP,4BAA4B;AACnC,SAASC,OAAO,QAAQ,QAAQ;AAChC,SAAuBC,OAAO,QAAQ,QAAQ;AAC9C,SAASC,aAAa,QAAQ,mBAAmB;AAEjD,SACEC,aAAa,EACbC,sBAAsB,EACtBC,yBAAyB,EACzBC,qBAAqB,QAChB,8BAA8B;AACrC,SAAgCC,aAAa,EAAEC,aAAa,QAAQ,uBAAuB;AAE3F,OAAO,SAASC,sBAAsBC,KAA4B;IAChE,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAE,GAAGF;IAC5B,MAAM,EAAEG,UAAU,EAAE,GAAGD;IACvB,MAAME,wBAAwBD,cAAcV;IAC5C,MAAMY,qBAAqBjB,mCAAmCgB,uBAAuBR;IACrF,MAAMU,0BAA0BrB,MAAM,2BAA2B,+FAA+F;IAEhK,MAAM,EAAEsB,MAAMC,MAAM,EAAE,GAAGrB,oBAAiCkB;IAC1D,MAAM,EAAEI,SAAS,EAAE,GAAGpB;IACtB,MAAMqB,mBAAmBnB,QAAQ;QAC/B,OAAO;YAAEiB;YAAQC;QAAU;IAC7B,GAAG;QAACD;QAAQC;KAAU;IAEtB,MAAM,EAAEE,KAAK,EAAEC,iBAAiB,EAAEC,eAAe,EAAE,GAAGf,cAAcE;IACpE,MAAM,EAAEc,KAAK,EAAEC,iBAAiB,EAAEC,eAAe,EAAEC,aAAa,EAAE,GAAGpB,cAAcG;IAEnF,MAAMkB,yBAA4D,CAACC;QACjE,IAAIxB,0BAA0BwB,OAAO;YACnClB,SACEX,QAAQY,OAAO,CAACkB;gBACd,sFAAsF;gBACtF,MAAMC,iBAAiB3B,uBAAuByB,QAAQG,YAAYH;gBAClEC,MAAMjB,UAAU,GAAGkB;YACrB;YAEF;QACF;QAEA,MAAM,IAAIE,MAAM;IAClB;IAEA,qBACE,MAACxC;QAAMyC,SAAS;;0BACd,KAAC1C;gBAAY2C,QAAO;gBAAQC,WAAW;0BACrC,cAAA,KAACxC;oBACCyC,sBAAsB/B;oBACtBM,OAAOE;oBACPH,UAAUiB;oBACVU,SAAStB;oBACTuB,OAAM;oBACNC,OAAO;;;0BAGX,MAAC/C;gBAAMgD,WAAU;gBAAMP,SAAS;;kCAC9B,KAAChC;wBACCkB,kBAAkBA;wBAClBR,OAAOS;wBACPV,UAAUW;wBACVoB,QAAQnB;;kCAEV,KAAC7B;wBACCiD,MAAK;wBACLJ,OAAM;wBACN3B,OAAOY;wBACPoB,OAAOjB;wBACPhB,UAAU,CAACkC,IAAMpB,kBAAkBoB,EAAEC,MAAM,CAAClC,KAAK;wBACjD8B,QAAQhB;wBACRqB,IAAI;4BAAEC,OAAO;wBAAQ;;;;;;AAK/B"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/plugins/tempo-trace-query/TempoTraceQueryEditor.tsx"],"sourcesContent":["// Copyright 2025 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 { Box, Button, FormControl, InputLabel, MenuItem, Select, Stack } from '@mui/material';\nimport { useId } from '@perses-dev/components';\nimport {\n DatasourceSelect,\n DatasourceSelectProps,\n useDatasourceClient,\n useDatasourceSelectValueToSelector,\n} from '@perses-dev/plugin-system';\nimport { produce } from 'immer';\nimport { ReactElement, useCallback, useState } from 'react';\nimport { TraceQLEditor } from '../../components';\nimport { TempoClient } from '../../model/tempo-client';\nimport {\n DEFAULT_TEMPO,\n isDefaultTempoSelector,\n isTempoDatasourceSelector,\n TEMPO_DATASOURCE_KIND,\n} from '../../model/tempo-selectors';\nimport { AttributeFilters } from '../../components/AttributeFilters';\nimport { filterToTraceQL } from '../../components/filter/filter_to_traceql';\nimport { traceQLToFilter } from '../../components/filter/traceql_to_filter';\nimport { TraceQueryEditorProps, useQueryState } from './query-editor-model';\n\nexport function TempoTraceQueryEditor(props: TraceQueryEditorProps): ReactElement {\n const {\n onChange,\n value,\n value: { datasource, limit },\n queryHandlerSettings,\n } = props;\n\n const datasourceSelectValue = datasource ?? DEFAULT_TEMPO;\n const selectedDatasource = useDatasourceSelectValueToSelector(datasourceSelectValue, TEMPO_DATASOURCE_KIND);\n const datasourceSelectLabelID = useId('tempo-datasource-label'); // for panels with multiple queries, this component is rendered multiple times on the same page\n\n const { data: client } = useDatasourceClient<TempoClient>(selectedDatasource);\n const { query, handleQueryChange, handleQueryBlur } = useQueryState(props);\n const [showAttributeFilters, setShowAttributeFilters] = useState(() => isSimpleTraceQLQuery(query));\n\n const handleDatasourceChange: DatasourceSelectProps['onChange'] = (next) => {\n if (isTempoDatasourceSelector(next)) {\n onChange(\n produce(value, (draft) => {\n // If they're using the default, just omit the datasource prop (i.e. set to undefined)\n const nextDatasource = isDefaultTempoSelector(next) ? undefined : next;\n draft.datasource = nextDatasource;\n })\n );\n return;\n }\n\n throw new Error('Got unexpected non-Tempo datasource selector');\n };\n\n const runQuery = (newQuery: string) => {\n if (queryHandlerSettings?.watchQueryChanges) {\n queryHandlerSettings.watchQueryChanges(newQuery);\n }\n onChange(\n produce(value, (draft) => {\n draft.query = newQuery;\n })\n );\n };\n\n const handleTraceQueryChange = useCallback(\n (e: string) => {\n handleQueryChange(e);\n if (queryHandlerSettings?.watchQueryChanges) {\n queryHandlerSettings.watchQueryChanges(e);\n }\n },\n [handleQueryChange, queryHandlerSettings]\n );\n\n return (\n <Stack spacing={2}>\n <FormControl margin=\"dense\" fullWidth={false}>\n <DatasourceSelect\n datasourcePluginKind={TEMPO_DATASOURCE_KIND}\n value={datasourceSelectValue}\n onChange={handleDatasourceChange}\n labelId={datasourceSelectLabelID}\n label=\"Tempo Datasource\"\n notched\n />\n </FormControl>\n <Stack direction=\"row\" spacing={2} sx={{ alignItems: 'flex-start' }}>\n {showAttributeFilters ? (\n <AttributeFilters client={client} query={query} setQuery={runQuery} />\n ) : (\n <TraceQLEditor\n client={client}\n value={query}\n onChange={handleTraceQueryChange}\n onBlur={queryHandlerSettings?.runWithOnBlur ? handleQueryBlur : undefined}\n />\n )}\n <Button onClick={() => setShowAttributeFilters(!showAttributeFilters)}>\n {showAttributeFilters ? 'Show query' : 'Hide query'}\n </Button>\n <LimitSelect\n value={limit ?? 20}\n setValue={(newLimit: number) =>\n onChange(\n produce(value, (draft) => {\n draft.limit = newLimit;\n })\n )\n }\n />\n </Stack>\n </Stack>\n );\n}\n\nfunction isSimpleTraceQLQuery(query: string) {\n // if a query can be transformed to a filter and back to the original query, we can show the attribute filter toolbar\n return query == '' || filterToTraceQL(traceQLToFilter(query)) === query;\n}\n\nconst limitOptions = [20, 50, 100, 500, 1000, 5000];\n\ninterface LimitSelectProps {\n value: number;\n setValue: (x: number) => void;\n}\n\nexport function LimitSelect(props: LimitSelectProps) {\n const { value, setValue } = props;\n\n // the outer <Box> is required, because <FormControl> has display: inline-flex, which doesn't work with the parent <Stack> of the query editor\n return (\n <Box>\n <FormControl size=\"small\">\n <InputLabel id=\"max-traces-label\">Max Traces</InputLabel>\n <Select\n labelId=\"max-traces-label\"\n id=\"max-traces-select\"\n value={value}\n label=\"Max Traces\"\n onChange={(e) => setValue(typeof e.target.value === 'number' ? e.target.value : parseInt(e.target.value))}\n sx={{ width: 110 }}\n >\n {limitOptions.map((option) => (\n <MenuItem key={option} value={option}>\n {option}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Box>\n );\n}\n"],"names":["Box","Button","FormControl","InputLabel","MenuItem","Select","Stack","useId","DatasourceSelect","useDatasourceClient","useDatasourceSelectValueToSelector","produce","useCallback","useState","TraceQLEditor","DEFAULT_TEMPO","isDefaultTempoSelector","isTempoDatasourceSelector","TEMPO_DATASOURCE_KIND","AttributeFilters","filterToTraceQL","traceQLToFilter","useQueryState","TempoTraceQueryEditor","props","onChange","value","datasource","limit","queryHandlerSettings","datasourceSelectValue","selectedDatasource","datasourceSelectLabelID","data","client","query","handleQueryChange","handleQueryBlur","showAttributeFilters","setShowAttributeFilters","isSimpleTraceQLQuery","handleDatasourceChange","next","draft","nextDatasource","undefined","Error","runQuery","newQuery","watchQueryChanges","handleTraceQueryChange","e","spacing","margin","fullWidth","datasourcePluginKind","labelId","label","notched","direction","sx","alignItems","setQuery","onBlur","runWithOnBlur","onClick","LimitSelect","setValue","newLimit","limitOptions","size","id","target","parseInt","width","map","option"],"mappings":"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"}
|
|
@@ -95,6 +95,14 @@ function parseTraceResponse(response) {
|
|
|
95
95
|
if (span.parentSpanId && span.parentSpanId.length != 16) {
|
|
96
96
|
span.parentSpanId = base64ToHex(span.parentSpanId);
|
|
97
97
|
}
|
|
98
|
+
for (const link of span.links ?? []){
|
|
99
|
+
if (link.traceId.length != 32) {
|
|
100
|
+
link.traceId = base64ToHex(link.traceId);
|
|
101
|
+
}
|
|
102
|
+
if (link.spanId.length != 16) {
|
|
103
|
+
link.spanId = base64ToHex(link.spanId);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
98
106
|
}
|
|
99
107
|
}
|
|
100
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/plugins/tempo-trace-query/get-trace-data.ts"],"sourcesContent":["// Copyright 2025 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 { AbsoluteTimeRange, isValidTraceId, otlptracev1, TraceSearchResult } from '@perses-dev/core';\nimport { datasourceSelectValueToSelector, TraceQueryPlugin } from '@perses-dev/plugin-system';\nimport { getUnixTime } from 'date-fns';\nimport { TEMPO_DATASOURCE_KIND, TempoDatasourceSelector, TempoTraceQuerySpec } from '../../model';\nimport { QueryResponse, SearchRequestParameters, SearchResponse } from '../../model/api-types';\nimport { TempoClient } from '../../model/tempo-client';\n\nexport function getUnixTimeRange(timeRange: AbsoluteTimeRange): { start: number; end: number } {\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 listDatasourceSelectItems = await context.datasourceStore.listDatasourceSelectItems(TEMPO_DATASOURCE_KIND);\n const datasourceSelector =\n datasourceSelectValueToSelector(spec.datasource, context.variableState, listDatasourceSelectItems) ??\n defaultTempoDatasource;\n\n const client = await context.datasourceStore.getDatasourceClient<TempoClient>(datasourceSelector);\n\n const getQuery = (): SearchRequestParameters => {\n const params: SearchRequestParameters = {\n q: spec.query,\n };\n\n // handle time range selection from UI drop down (e.g. last 5 minutes, last 1 hour )\n if (context.absoluteTimeRange) {\n const { start, end } = getUnixTimeRange(context.absoluteTimeRange);\n params.start = start;\n params.end = end;\n }\n\n if (spec.limit) {\n params.limit = spec.limit;\n }\n\n return params;\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 parseTraceResponse(response: QueryResponse): otlptracev1.TracesData {\n const trace = {\n resourceSpans: response.batches,\n };\n\n // Tempo returns Trace ID and Span ID base64-encoded.\n // The OTLP spec defines the encoding in the hex format:\n // Spec: https://opentelemetry.io/docs/specs/otlp/#json-protobuf-encoding\n // Example: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.7.0/examples/trace.json\n // Therefore, let's convert it to hex encoding.\n for (const resourceSpan of trace.resourceSpans) {\n for (const scopeSpan of resourceSpan.scopeSpans) {\n for (const span of scopeSpan.spans) {\n if (span.traceId.length != 32) {\n span.traceId = base64ToHex(span.traceId);\n }\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/plugins/tempo-trace-query/get-trace-data.ts"],"sourcesContent":["// Copyright 2025 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 { AbsoluteTimeRange, isValidTraceId, otlptracev1, TraceSearchResult } from '@perses-dev/core';\nimport { datasourceSelectValueToSelector, TraceQueryPlugin } from '@perses-dev/plugin-system';\nimport { getUnixTime } from 'date-fns';\nimport { TEMPO_DATASOURCE_KIND, TempoDatasourceSelector, TempoTraceQuerySpec } from '../../model';\nimport { QueryResponse, SearchRequestParameters, SearchResponse } from '../../model/api-types';\nimport { TempoClient } from '../../model/tempo-client';\n\nexport function getUnixTimeRange(timeRange: AbsoluteTimeRange): { start: number; end: number } {\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 listDatasourceSelectItems = await context.datasourceStore.listDatasourceSelectItems(TEMPO_DATASOURCE_KIND);\n const datasourceSelector =\n datasourceSelectValueToSelector(spec.datasource, context.variableState, listDatasourceSelectItems) ??\n defaultTempoDatasource;\n\n const client = await context.datasourceStore.getDatasourceClient<TempoClient>(datasourceSelector);\n\n const getQuery = (): SearchRequestParameters => {\n const params: SearchRequestParameters = {\n q: spec.query,\n };\n\n // handle time range selection from UI drop down (e.g. last 5 minutes, last 1 hour )\n if (context.absoluteTimeRange) {\n const { start, end } = getUnixTimeRange(context.absoluteTimeRange);\n params.start = start;\n params.end = end;\n }\n\n if (spec.limit) {\n params.limit = spec.limit;\n }\n\n return params;\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 parseTraceResponse(response: QueryResponse): otlptracev1.TracesData {\n const trace = {\n resourceSpans: response.batches,\n };\n\n // Tempo returns Trace ID and Span ID base64-encoded.\n // The OTLP spec defines the encoding in the hex format:\n // Spec: https://opentelemetry.io/docs/specs/otlp/#json-protobuf-encoding\n // Example: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.7.0/examples/trace.json\n // Therefore, let's convert it to hex encoding.\n for (const resourceSpan of trace.resourceSpans) {\n for (const scopeSpan of resourceSpan.scopeSpans) {\n for (const span of scopeSpan.spans) {\n if (span.traceId.length != 32) {\n span.traceId = base64ToHex(span.traceId);\n }\n if (span.spanId.length != 16) {\n span.spanId = base64ToHex(span.spanId);\n }\n if (span.parentSpanId && span.parentSpanId.length != 16) {\n span.parentSpanId = base64ToHex(span.parentSpanId);\n }\n\n for (const link of span.links ?? []) {\n if (link.traceId.length != 32) {\n link.traceId = base64ToHex(link.traceId);\n }\n if (link.spanId.length != 16) {\n link.spanId = base64ToHex(link.spanId);\n }\n }\n }\n }\n }\n\n return trace;\n}\n\nfunction base64ToHex(str: string) {\n try {\n return atob(str)\n .split('')\n .map((char) => char.charCodeAt(0).toString(16).padStart(2, '0').toUpperCase())\n .join('');\n } catch {\n return str;\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","datasourceSelectValueToSelector","getUnixTime","TEMPO_DATASOURCE_KIND","getUnixTimeRange","timeRange","start","end","Math","ceil","getTraceData","spec","context","query","undefined","console","error","searchResult","defaultTempoDatasource","kind","listDatasourceSelectItems","datasourceStore","datasourceSelector","datasource","variableState","client","getDatasourceClient","getQuery","params","q","absoluteTimeRange","limit","response","traceId","trace","parseTraceResponse","metadata","executedQueryString","searchWithFallback","parseSearchResponse","resourceSpans","batches","resourceSpan","scopeSpan","scopeSpans","span","spans","length","base64ToHex","spanId","parentSpanId","link","links","str","atob","split","map","char","charCodeAt","toString","padStart","toUpperCase","join","traces","startTimeUnixMs","parseInt","startTimeUnixNano","durationMs","traceID","rootServiceName","rootTraceName","serviceStats"],"mappings":"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"}
|
|
@@ -12,13 +12,4 @@ export declare function useQueryState(props: TraceQueryEditorProps): {
|
|
|
12
12
|
handleQueryChange: (e: string) => void;
|
|
13
13
|
handleQueryBlur: () => void;
|
|
14
14
|
};
|
|
15
|
-
/**
|
|
16
|
-
* Hook to manage `limit` state to ensure panel preview does not rerender until text input is blurred
|
|
17
|
-
*/
|
|
18
|
-
export declare function useLimitState(props: TraceQueryEditorProps): {
|
|
19
|
-
limit: string;
|
|
20
|
-
handleLimitChange: (e: string) => void;
|
|
21
|
-
handleLimitBlur: () => void;
|
|
22
|
-
limitHasError: boolean;
|
|
23
|
-
};
|
|
24
15
|
//# sourceMappingURL=query-editor-model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-editor-model.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tempo-trace-query/query-editor-model.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;AAE5E;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,qBAAqB,GAAG;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B,CA+BA
|
|
1
|
+
{"version":3,"file":"query-editor-model.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tempo-trace-query/query-editor-model.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;AAE5E;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,qBAAqB,GAAG;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B,CA+BA"}
|