@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.
Files changed (181) hide show
  1. package/__mf/js/Tempo.2f6d49a1.js +5 -0
  2. package/__mf/js/async/1101.0dae4724.js +73 -0
  3. package/__mf/js/async/1576.83b7de56.js +1 -0
  4. package/__mf/js/async/1964.e6c5b93b.js +2 -0
  5. package/__mf/js/async/2292.75e9aa11.js +2 -0
  6. package/__mf/js/async/2913.f73e6635.js +7 -0
  7. package/__mf/js/async/2913.f73e6635.js.LICENSE.txt +21 -0
  8. package/__mf/js/async/2981.8fe4ed12.js +2 -0
  9. package/__mf/js/async/3224.ce173388.js +1 -0
  10. package/__mf/js/async/3863.8d56ecec.js +2 -0
  11. package/__mf/js/async/3960.401ff0b0.js +2 -0
  12. package/__mf/js/async/3980.4d5490b2.js +2 -0
  13. package/__mf/js/async/4075.4c5ac93a.js +1 -0
  14. package/__mf/js/async/4238.7962a7a1.js +1 -0
  15. package/__mf/js/async/4269.0cfaf9bb.js +2 -0
  16. package/__mf/js/async/4368.bd6fd0e7.js +2 -0
  17. package/__mf/js/async/4368.bd6fd0e7.js.LICENSE.txt +15 -0
  18. package/__mf/js/async/4421.14238d27.js +1 -0
  19. package/__mf/js/async/4535.7c92d3fd.js +1 -0
  20. package/__mf/js/async/5214.c44cbfe5.js +1 -0
  21. package/__mf/js/async/5266.1c520126.js +10 -0
  22. package/__mf/js/async/5409.676a5f3f.js +1 -0
  23. package/__mf/js/async/5790.b4d4134d.js +1 -0
  24. package/__mf/js/async/5876.47f40562.js +2 -0
  25. package/__mf/js/async/{7832.9f2a70d0.js.LICENSE.txt → 5876.47f40562.js.LICENSE.txt} +1 -23
  26. package/__mf/js/async/5981.c6edce96.js +2 -0
  27. package/__mf/js/async/6292.463b4f49.js +1 -0
  28. package/__mf/js/async/6333.367d6758.js +2 -0
  29. package/__mf/js/async/6495.eae3d4b4.js +1 -0
  30. package/__mf/js/async/6527.5341d09f.js +2 -0
  31. package/__mf/js/async/6751.03514b88.js +1 -0
  32. package/__mf/js/async/6770.d9c238f2.js +1 -0
  33. package/__mf/js/async/694.c2c37771.js +1 -0
  34. package/__mf/js/async/7127.a0877987.js +38 -0
  35. package/__mf/js/async/7376.588b7a17.js +1 -0
  36. package/__mf/js/async/738.93d35dc9.js +1 -0
  37. package/__mf/js/async/7740.0500bfc6.js +1 -0
  38. package/__mf/js/async/8216.2f92a883.js +1 -0
  39. package/__mf/js/async/8488.6c9a25e4.js +1 -0
  40. package/__mf/js/async/8597.d5ba4ca7.js +1 -0
  41. package/__mf/js/async/8930.dee9777e.js +1 -0
  42. package/__mf/js/async/9173.69dc268d.js +2 -0
  43. package/__mf/js/async/9314.4b8565a0.js +2 -0
  44. package/__mf/js/async/9368.f0418d24.js +101 -0
  45. package/__mf/js/async/__federation_expose_TempoDatasource.fa3e24f9.js +2 -0
  46. package/__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js +2 -0
  47. package/__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js +1 -0
  48. package/__mf/js/async/lib-router.312ca028.js +2 -0
  49. package/__mf/js/main.edbb7a5a.js +5 -0
  50. package/lib/cjs/components/AttributeFilters.js +274 -0
  51. package/lib/cjs/components/TraceQLEditor.js +9 -3
  52. package/lib/cjs/components/complete.js +29 -13
  53. package/lib/cjs/components/filter/filter.js +25 -0
  54. package/lib/cjs/components/filter/filter_to_traceql.js +66 -0
  55. package/lib/cjs/components/filter/index.js +32 -0
  56. package/lib/cjs/components/filter/traceql_to_filter.js +113 -0
  57. package/lib/cjs/components/index.js +1 -0
  58. package/lib/cjs/explore/TempoExplorer.js +25 -12
  59. package/lib/cjs/explore/links.js +77 -0
  60. package/lib/cjs/plugins/tempo-trace-query/TempoTraceQueryEditor.js +94 -30
  61. package/lib/cjs/plugins/tempo-trace-query/get-trace-data.js +8 -0
  62. package/lib/cjs/plugins/tempo-trace-query/query-editor-model.js +3 -44
  63. package/lib/components/AttributeFilters.d.ts +9 -0
  64. package/lib/components/AttributeFilters.d.ts.map +1 -0
  65. package/lib/components/AttributeFilters.js +261 -0
  66. package/lib/components/AttributeFilters.js.map +1 -0
  67. package/lib/components/TraceQLEditor.d.ts +3 -3
  68. package/lib/components/TraceQLEditor.d.ts.map +1 -1
  69. package/lib/components/TraceQLEditor.js +9 -3
  70. package/lib/components/TraceQLEditor.js.map +1 -1
  71. package/lib/components/complete.d.ts +10 -1
  72. package/lib/components/complete.d.ts.map +1 -1
  73. package/lib/components/complete.js +26 -7
  74. package/lib/components/complete.js.map +1 -1
  75. package/lib/components/filter/filter.d.ts +17 -0
  76. package/lib/components/filter/filter.d.ts.map +1 -0
  77. package/lib/components/filter/filter.js +17 -0
  78. package/lib/components/filter/filter.js.map +1 -0
  79. package/lib/components/filter/filter_to_traceql.d.ts +9 -0
  80. package/lib/components/filter/filter_to_traceql.d.ts.map +1 -0
  81. package/lib/components/filter/filter_to_traceql.js +63 -0
  82. package/lib/components/filter/filter_to_traceql.js.map +1 -0
  83. package/lib/components/filter/index.d.ts +4 -0
  84. package/lib/components/filter/index.d.ts.map +1 -0
  85. package/lib/components/filter/index.js +17 -0
  86. package/lib/components/filter/index.js.map +1 -0
  87. package/lib/components/filter/traceql_to_filter.d.ts +9 -0
  88. package/lib/components/filter/traceql_to_filter.d.ts.map +1 -0
  89. package/lib/components/filter/traceql_to_filter.js +110 -0
  90. package/lib/components/filter/traceql_to_filter.js.map +1 -0
  91. package/lib/components/index.d.ts +1 -0
  92. package/lib/components/index.d.ts.map +1 -1
  93. package/lib/components/index.js +1 -0
  94. package/lib/components/index.js.map +1 -1
  95. package/lib/explore/TempoExplorer.d.ts.map +1 -1
  96. package/lib/explore/TempoExplorer.js +25 -12
  97. package/lib/explore/TempoExplorer.js.map +1 -1
  98. package/lib/explore/links.d.ts +3 -0
  99. package/lib/explore/links.d.ts.map +1 -0
  100. package/lib/explore/links.js +63 -0
  101. package/lib/explore/links.js.map +1 -0
  102. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts +6 -0
  103. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts.map +1 -1
  104. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js +87 -31
  105. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js.map +1 -1
  106. package/lib/plugins/tempo-trace-query/get-trace-data.js +8 -0
  107. package/lib/plugins/tempo-trace-query/get-trace-data.js.map +1 -1
  108. package/lib/plugins/tempo-trace-query/query-editor-model.d.ts +0 -9
  109. package/lib/plugins/tempo-trace-query/query-editor-model.d.ts.map +1 -1
  110. package/lib/plugins/tempo-trace-query/query-editor-model.js +0 -35
  111. package/lib/plugins/tempo-trace-query/query-editor-model.js.map +1 -1
  112. package/mf-manifest.json +104 -265
  113. package/mf-stats.json +112 -270
  114. package/package.json +6 -6
  115. package/__mf/js/1096.c549c391.js +0 -5
  116. package/__mf/js/Tempo.e7d268a6.js +0 -5
  117. package/__mf/js/async/1465.21c847e0.js +0 -1
  118. package/__mf/js/async/1540.089c4f28.js +0 -74
  119. package/__mf/js/async/1620.45989def.js +0 -2
  120. package/__mf/js/async/1964.75933dd4.js +0 -2
  121. package/__mf/js/async/2114.28503adb.js +0 -1
  122. package/__mf/js/async/2823.df67fd4b.js +0 -2
  123. package/__mf/js/async/3044.8b419ccf.js +0 -1
  124. package/__mf/js/async/3090.90251187.js +0 -2
  125. package/__mf/js/async/3224.8d499a63.js +0 -1
  126. package/__mf/js/async/3355.8bd6f6bd.js +0 -1
  127. package/__mf/js/async/3828.d981b319.js +0 -2
  128. package/__mf/js/async/3960.2228bf7e.js +0 -2
  129. package/__mf/js/async/3980.c94e78cd.js +0 -2
  130. package/__mf/js/async/4075.4c40db9f.js +0 -1
  131. package/__mf/js/async/4238.db631f1f.js +0 -1
  132. package/__mf/js/async/4289.5e2073e0.js +0 -1
  133. package/__mf/js/async/4421.07335985.js +0 -1
  134. package/__mf/js/async/4758.cb86850e.js +0 -1
  135. package/__mf/js/async/5207.e63b049c.js +0 -2
  136. package/__mf/js/async/5214.fb1215df.js +0 -1
  137. package/__mf/js/async/5220.80e3b05e.js +0 -10
  138. package/__mf/js/async/528.2759052c.js +0 -1
  139. package/__mf/js/async/5503.6e47fa95.js +0 -1
  140. package/__mf/js/async/5790.949d8d1c.js +0 -1
  141. package/__mf/js/async/5913.d10c6185.js +0 -73
  142. package/__mf/js/async/5924.bfb4b2fd.js +0 -2
  143. package/__mf/js/async/5981.4700ddf6.js +0 -2
  144. package/__mf/js/async/6292.2481b399.js +0 -1
  145. package/__mf/js/async/6770.4b9911ea.js +0 -1
  146. package/__mf/js/async/694.91676c53.js +0 -1
  147. package/__mf/js/async/7127.ccd78bd8.js +0 -38
  148. package/__mf/js/async/7376.a69c2e5a.js +0 -1
  149. package/__mf/js/async/738.2cdddba7.js +0 -1
  150. package/__mf/js/async/7740.1ecb3732.js +0 -1
  151. package/__mf/js/async/7832.9f2a70d0.js +0 -7
  152. package/__mf/js/async/8485.434a672e.js +0 -28
  153. package/__mf/js/async/8488.d3005164.js +0 -1
  154. package/__mf/js/async/8597.07c3a890.js +0 -1
  155. package/__mf/js/async/8930.ae855fbe.js +0 -1
  156. package/__mf/js/async/9173.83562213.js +0 -2
  157. package/__mf/js/async/9478.57f45cd9.js +0 -2
  158. package/__mf/js/async/__federation_expose_TempoDatasource.4f96e206.js +0 -2
  159. package/__mf/js/async/__federation_expose_TempoExplorer.eb09c758.js +0 -2
  160. package/__mf/js/async/__federation_expose_TempoTraceQuery.4183e294.js +0 -1
  161. package/__mf/js/async/lib-router.46460b13.js +0 -2
  162. package/__mf/js/main.4498dd88.js +0 -1
  163. /package/__mf/css/async/{4758.c10cf504.css → 1576.c10cf504.css} +0 -0
  164. /package/__mf/css/async/{5207.c10cf504.css → 9314.c10cf504.css} +0 -0
  165. /package/__mf/js/async/{5913.d10c6185.js.LICENSE.txt → 1101.0dae4724.js.LICENSE.txt} +0 -0
  166. /package/__mf/js/async/{1964.75933dd4.js.LICENSE.txt → 1964.e6c5b93b.js.LICENSE.txt} +0 -0
  167. /package/__mf/js/async/{3090.90251187.js.LICENSE.txt → 2292.75e9aa11.js.LICENSE.txt} +0 -0
  168. /package/__mf/js/async/{1620.45989def.js.LICENSE.txt → 2981.8fe4ed12.js.LICENSE.txt} +0 -0
  169. /package/__mf/js/async/{2823.df67fd4b.js.LICENSE.txt → 3863.8d56ecec.js.LICENSE.txt} +0 -0
  170. /package/__mf/js/async/{3960.2228bf7e.js.LICENSE.txt → 3960.401ff0b0.js.LICENSE.txt} +0 -0
  171. /package/__mf/js/async/{3980.c94e78cd.js.LICENSE.txt → 3980.4d5490b2.js.LICENSE.txt} +0 -0
  172. /package/__mf/js/async/{3828.d981b319.js.LICENSE.txt → 4269.0cfaf9bb.js.LICENSE.txt} +0 -0
  173. /package/__mf/js/async/{5220.80e3b05e.js.LICENSE.txt → 5266.1c520126.js.LICENSE.txt} +0 -0
  174. /package/__mf/js/async/{5981.4700ddf6.js.LICENSE.txt → 5981.c6edce96.js.LICENSE.txt} +0 -0
  175. /package/__mf/js/async/{5207.e63b049c.js.LICENSE.txt → 6333.367d6758.js.LICENSE.txt} +0 -0
  176. /package/__mf/js/async/{5924.bfb4b2fd.js.LICENSE.txt → 6527.5341d09f.js.LICENSE.txt} +0 -0
  177. /package/__mf/js/async/{9173.83562213.js.LICENSE.txt → 9173.69dc268d.js.LICENSE.txt} +0 -0
  178. /package/__mf/js/async/{9478.57f45cd9.js.LICENSE.txt → 9314.4b8565a0.js.LICENSE.txt} +0 -0
  179. /package/__mf/js/async/{__federation_expose_TempoDatasource.4f96e206.js.LICENSE.txt → __federation_expose_TempoDatasource.fa3e24f9.js.LICENSE.txt} +0 -0
  180. /package/__mf/js/async/{__federation_expose_TempoExplorer.eb09c758.js.LICENSE.txt → __federation_expose_TempoExplorer.9949b25e.js.LICENSE.txt} +0 -0
  181. /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,3 +1,4 @@
1
+ export * from './filter';
1
2
  export * from './TraceQLEditor';
2
3
  export * from './TraceQLExtension';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -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;AAyErC,wBAAgB,aAAa,IAAI,YAAY,CAwC5C"}
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({ queries }) {
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
- // Cannot cast to TempoTraceQuerySpec because 'tempo-plugin' types are not accessible in @perses-dev/explore
123
- const isSingleTrace = queries.length === 1 && queries[0]?.kind === 'TraceQuery' && queries[0]?.spec.plugin.kind === 'TempoTraceQuery' && isValidTraceId((queries[0]?.spec.plugin.spec).query ?? ''); // eslint-disable-line @typescript-eslint/no-explicit-any
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: { queries, display: { name: '' }, plugin: { kind: 'ScatterChart', spec: {} } },\n }}\n />\n </Box>\n <Panel\n sx={{ flexGrow: 1 }}\n panelOptions={{\n hideHeader: true,\n }}\n definition={{\n kind: 'Panel',\n spec: { queries, display: { name: '' }, plugin: { kind: 'TraceTable', spec: {} } },\n }}\n />\n </Stack>\n );\n}\n\nfunction TracingGanttChartPanel({ queries }: { queries: QueryDefinition[] }): ReactElement {\n return (\n <Panel\n panelOptions={{\n hideHeader: true,\n }}\n definition={{\n kind: 'Panel',\n spec: { queries, display: { name: '' }, plugin: { kind: 'TracingGanttChart', spec: {} } },\n }}\n />\n );\n}\n\nexport function TempoExplorer(): ReactElement {\n const {\n data: { queries = [] },\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 // Cannot cast to TempoTraceQuerySpec because 'tempo-plugin' types are not accessible in @perses-dev/explore\n const isSingleTrace =\n queries.length === 1 &&\n queries[0]?.kind === 'TraceQuery' &&\n queries[0]?.spec.plugin.kind === 'TempoTraceQuery' &&\n isValidTraceId((queries[0]?.spec.plugin.spec as any).query ?? ''); // eslint-disable-line @typescript-eslint/no-explicit-any\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 ? <TracingGanttChartPanel queries={queries} /> : <SearchResultsPanel queries={queries} />}\n </Box>\n </DataQueriesProvider>\n </ErrorBoundary>\n </Stack>\n );\n}\n"],"names":["Box","Stack","ErrorAlert","ErrorBoundary","LoadingOverlay","NoDataOverlay","isValidTraceId","Panel","useExplorerManagerContext","DataQueriesProvider","MultiQueryEditor","useDataQueries","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","flexGrow","TracingGanttChartPanel","TempoExplorer","setData","definitions","map","query","isSingleTrace","width","queryTypes","onChange","newQueries","FallbackComponent","resetKeys"],"mappings":"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"}
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,3 @@
1
+ export declare const linkToTrace: string;
2
+ export declare const linkToSpan: string;
3
+ //# sourceMappingURL=links.d.ts.map
@@ -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":"AAuBA,OAAO,EAAE,YAAY,EAAW,MAAM,OAAO,CAAC;AAS9C,OAAO,EAAE,qBAAqB,EAAgC,MAAM,sBAAsB,CAAC;AAE3F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CA8DhF"}
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, Stack, TextField } from '@mui/material';
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, useTimeRange } from '@perses-dev/plugin-system';
16
+ import { DatasourceSelect, useDatasourceClient, useDatasourceSelectValueToSelector } from '@perses-dev/plugin-system';
17
17
  import { produce } from 'immer';
18
- import { useMemo } from 'react';
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 { useLimitState, useQueryState } from './query-editor-model';
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 { limit, handleLimitChange, handleLimitBlur, limitHasError } = useLimitState(props);
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(TraceQLEditor, {
72
- completionConfig: completionConfig,
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: handleQueryChange,
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(TextField, {
78
- size: "small",
79
- label: "Max Traces",
80
- value: limit,
81
- error: limitHasError,
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\n if (span.spanId.length != 16) {\n span.spanId = base64ToHex(span.spanId);\n }\n\n if (span.parentSpanId && span.parentSpanId.length != 16) {\n span.parentSpanId = base64ToHex(span.parentSpanId);\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","str","atob","split","map","char","charCodeAt","toString","padStart","toUpperCase","join","traces","startTimeUnixMs","parseInt","startTimeUnixNano","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 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;AAED;;GAEG;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;IAC5B,aAAa,EAAE,OAAO,CAAC;CACxB,CAmCA"}
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"}