Tempo: Fix type errors that appeared when removing the "any" type from DataQueryResponseData (#75600)

* Tempo: Improving typing of data types

* last fix

* Fix
This commit is contained in:
Torkel Ödegaard 2023-10-11 18:04:54 +02:00 committed by GitHub
parent 7329e2dc62
commit bf7fae4bd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 580 additions and 528 deletions

View File

@ -193,9 +193,7 @@
"footer": { "footer": {
"countRows": false, "countRows": false,
"fields": "", "fields": "",
"reducer": [ "reducer": ["sum"],
"sum"
],
"show": false "show": false
}, },
"showHeader": true "showHeader": true

View File

@ -1,425 +1,425 @@
{ {
"annotations": { "annotations": {
"list": [ "list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 2312,
"links": [],
"liveNow": false,
"panels": [
{ {
"builtIn": 1,
"datasource": { "datasource": {
"type": "grafana-testdata-datasource", "type": "grafana",
"uid": "gdev-testdata" "uid": "-- Grafana --"
}, },
"fieldConfig": { "enable": true,
"defaults": { "hide": true,
"color": { "iconColor": "rgba(0, 211, 255, 1)",
"mode": "palette-classic" "name": "Annotations & Alerts",
}, "type": "dashboard"
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Panel 1",
"type": "timeseries"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 8
},
"id": 2,
"panels": [],
"title": "Expanded row",
"type": "row"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 9
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"refId": "B",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Panel 2",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 9
},
"id": 6,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"refId": "C",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Panel 3",
"type": "timeseries"
},
{
"collapsed": true,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 17
},
"id": 4,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 10
},
"id": 5,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel inside colapsed row",
"type": "timeseries"
}
],
"title": "Collapsed row",
"type": "row"
} }
], ]
"refresh": "", },
"schemaVersion": 38, "editable": true,
"tags": [], "fiscalYearStartMonth": 0,
"templating": { "graphTooltip": 0,
"list": [] "id": 2312,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Panel 1",
"type": "timeseries"
}, },
"time": { {
"from": "now-6h", "collapsed": false,
"to": "now" "gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 8
},
"id": 2,
"panels": [],
"title": "Expanded row",
"type": "row"
}, },
"timepicker": {}, {
"timezone": "", "datasource": {
"title": "Snapshots - basic rows", "type": "grafana-testdata-datasource",
"uid": "a3b23921-287d-4f90-9a14-c04228057dfa", "uid": "gdev-testdata"
"version": 4, },
"weekStart": "" "fieldConfig": {
} "defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 9
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"refId": "B",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Panel 2",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 9
},
"id": 6,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"refId": "C",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Panel 3",
"type": "timeseries"
},
{
"collapsed": true,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 17
},
"id": 4,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 10
},
"id": 5,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel inside colapsed row",
"type": "timeseries"
}
],
"title": "Collapsed row",
"type": "row"
}
],
"refresh": "",
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Snapshots - basic rows",
"uid": "a3b23921-287d-4f90-9a14-c04228057dfa",
"version": 4,
"weekStart": ""
}

View File

@ -232,11 +232,11 @@ describe('Tempo data source', () => {
expect(response.data).toHaveLength(2); expect(response.data).toHaveLength(2);
const nodesFrame = response.data[0]; const nodesFrame = response.data[0];
expect(nodesFrame.name).toBe('Nodes'); expect(nodesFrame.name).toBe('Nodes');
expect(nodesFrame.meta.preferredVisualisationType).toBe('nodeGraph'); expect(nodesFrame.meta?.preferredVisualisationType).toBe('nodeGraph');
const edgesFrame = response.data[1]; const edgesFrame = response.data[1];
expect(edgesFrame.name).toBe('Edges'); expect(edgesFrame.name).toBe('Edges');
expect(edgesFrame.meta.preferredVisualisationType).toBe('nodeGraph'); expect(edgesFrame.meta?.preferredVisualisationType).toBe('nodeGraph');
}); });
it('should build search query correctly', () => { it('should build search query correctly', () => {
@ -486,67 +486,67 @@ describe('Tempo service graph view', () => {
expect(response.data[0].fields[1].values.length).toBe(2); expect(response.data[0].fields[1].values.length).toBe(2);
expect(response.data[0].fields[1].values[0]).toBe(12.75164671814457); expect(response.data[0].fields[1].values[0]).toBe(12.75164671814457);
expect(response.data[0].fields[1].values[1]).toBe(12.121331111401608); expect(response.data[0].fields[1].values[1]).toBe(12.121331111401608);
expect(response.data[0].fields[1].config.decimals).toBe(2); expect(response.data[0].fields[1]?.config?.decimals).toBe(2);
expect(response.data[0].fields[1].config.links[0].title).toBe('Rate'); expect(response.data[0].fields[1]?.config?.links?.[0]?.title).toBe('Rate');
expect(response.data[0].fields[1].config.links[0].internal.query.expr).toBe( expect(response.data[0].fields[1]?.config?.links?.[0]?.internal?.query.expr).toBe(
'sum(rate(traces_spanmetrics_calls_total{span_name="${__data.fields[0]}"}[$__rate_interval]))' 'sum(rate(traces_spanmetrics_calls_total{span_name="${__data.fields[0]}"}[$__rate_interval]))'
); );
expect(response.data[0].fields[1].config.links[0].internal.query.range).toBe(true); expect(response.data[0].fields[1]?.config?.links?.[0]?.internal?.query.range).toBe(true);
expect(response.data[0].fields[1].config.links[0].internal.query.exemplar).toBe(true); expect(response.data[0].fields[1]?.config?.links?.[0]?.internal?.query.exemplar).toBe(true);
expect(response.data[0].fields[1].config.links[0].internal.query.instant).toBe(false); expect(response.data[0].fields[1]?.config?.links?.[0]?.internal?.query.instant).toBe(false);
expect(response.data[0].fields[2].values.length).toBe(2); expect(response.data[0].fields[2].values.length).toBe(2);
expect(response.data[0].fields[2].values[0]).toBe(12.75164671814457); expect(response.data[0].fields[2].values[0]).toBe(12.75164671814457);
expect(response.data[0].fields[2].values[1]).toBe(12.121331111401608); expect(response.data[0].fields[2].values[1]).toBe(12.121331111401608);
expect(response.data[0].fields[2].config.color.mode).toBe('continuous-BlPu'); expect(response.data[0].fields[2]?.config?.color?.mode).toBe('continuous-BlPu');
expect(response.data[0].fields[2].config.custom.cellOptions.mode).toBe(BarGaugeDisplayMode.Lcd); expect(response.data[0].fields[2]?.config?.custom.cellOptions.mode).toBe(BarGaugeDisplayMode.Lcd);
expect(response.data[0].fields[2].config.custom.cellOptions.type).toBe(TableCellDisplayMode.Gauge); expect(response.data[0].fields[2]?.config?.custom.cellOptions.type).toBe(TableCellDisplayMode.Gauge);
expect(response.data[0].fields[2].config.decimals).toBe(3); expect(response.data[0].fields[2]?.config?.decimals).toBe(3);
expect(response.data[0].fields[3].name).toBe('Error Rate'); expect(response.data[0].fields[3].name).toBe('Error Rate');
expect(response.data[0].fields[3].values.length).toBe(2); expect(response.data[0].fields[3].values.length).toBe(2);
expect(response.data[0].fields[3].values[0]).toBe(3.75164671814457); expect(response.data[0].fields[3].values[0]).toBe(3.75164671814457);
expect(response.data[0].fields[3].values[1]).toBe(3.121331111401608); expect(response.data[0].fields[3].values[1]).toBe(3.121331111401608);
expect(response.data[0].fields[3].config.decimals).toBe(2); expect(response.data[0].fields[3]?.config?.decimals).toBe(2);
expect(response.data[0].fields[3].config.links[0].title).toBe('Error Rate'); expect(response.data[0].fields[3]?.config?.links?.[0]?.title).toBe('Error Rate');
expect(response.data[0].fields[3].config.links[0].internal.query.expr).toBe( expect(response.data[0].fields[3]?.config?.links?.[0]?.internal?.query.expr).toBe(
'sum(rate(traces_spanmetrics_calls_total{status_code="STATUS_CODE_ERROR",span_name="${__data.fields[0]}"}[$__rate_interval]))' 'sum(rate(traces_spanmetrics_calls_total{status_code="STATUS_CODE_ERROR",span_name="${__data.fields[0]}"}[$__rate_interval]))'
); );
expect(response.data[0].fields[3].config.links[0].internal.query.range).toBe(true); expect(response.data[0].fields[3]?.config?.links?.[0]?.internal?.query.range).toBe(true);
expect(response.data[0].fields[3].config.links[0].internal.query.exemplar).toBe(true); expect(response.data[0].fields[3]?.config?.links?.[0]?.internal?.query.exemplar).toBe(true);
expect(response.data[0].fields[3].config.links[0].internal.query.instant).toBe(false); expect(response.data[0].fields[3]?.config?.links?.[0]?.internal?.query.instant).toBe(false);
expect(response.data[0].fields[4].values.length).toBe(2); expect(response.data[0].fields[4].values.length).toBe(2);
expect(response.data[0].fields[4].values[0]).toBe(3.75164671814457); expect(response.data[0].fields[4].values[0]).toBe(3.75164671814457);
expect(response.data[0].fields[4].values[1]).toBe(3.121331111401608); expect(response.data[0].fields[4].values[1]).toBe(3.121331111401608);
expect(response.data[0].fields[4].config.color.mode).toBe('continuous-RdYlGr'); expect(response.data[0].fields[4]?.config?.color?.mode).toBe('continuous-RdYlGr');
expect(response.data[0].fields[4].config.custom.cellOptions.mode).toBe(BarGaugeDisplayMode.Lcd); expect(response.data[0].fields[4]?.config?.custom.cellOptions.mode).toBe(BarGaugeDisplayMode.Lcd);
expect(response.data[0].fields[4].config.custom.cellOptions.type).toBe(TableCellDisplayMode.Gauge); expect(response.data[0].fields[4]?.config?.custom.cellOptions.type).toBe(TableCellDisplayMode.Gauge);
expect(response.data[0].fields[4].config.decimals).toBe(3); expect(response.data[0].fields[4]?.config?.decimals).toBe(3);
expect(response.data[0].fields[5].name).toBe('Duration (p90)'); expect(response.data[0].fields[5].name).toBe('Duration (p90)');
expect(response.data[0].fields[5].values.length).toBe(2); expect(response.data[0].fields[5].values.length).toBe(2);
expect(response.data[0].fields[5].values[0]).toBe('0'); expect(response.data[0].fields[5].values[0]).toBe('0');
expect(response.data[0].fields[5].values[1]).toBe(0.12003505696757232); expect(response.data[0].fields[5].values[1]).toBe(0.12003505696757232);
expect(response.data[0].fields[5].config.unit).toBe('s'); expect(response.data[0].fields[5]?.config?.unit).toBe('s');
expect(response.data[0].fields[5].config.links[0].title).toBe('Duration'); expect(response.data[0].fields[5]?.config?.links?.[0]?.title).toBe('Duration');
expect(response.data[0].fields[5].config.links[0].internal.query.expr).toBe( expect(response.data[0].fields[5]?.config?.links?.[0]?.internal?.query.expr).toBe(
'histogram_quantile(.9, sum(rate(traces_spanmetrics_latency_bucket{span_name="${__data.fields[0]}"}[$__rate_interval])) by (le))' 'histogram_quantile(.9, sum(rate(traces_spanmetrics_latency_bucket{span_name="${__data.fields[0]}"}[$__rate_interval])) by (le))'
); );
expect(response.data[0].fields[5].config.links[0].internal.query.range).toBe(true); expect(response.data[0].fields[5]?.config?.links?.[0]?.internal?.query.range).toBe(true);
expect(response.data[0].fields[5].config.links[0].internal.query.exemplar).toBe(true); expect(response.data[0].fields[5]?.config?.links?.[0]?.internal?.query.exemplar).toBe(true);
expect(response.data[0].fields[5].config.links[0].internal.query.instant).toBe(false); expect(response.data[0].fields[5]?.config?.links?.[0]?.internal?.query.instant).toBe(false);
expect(response.data[0].fields[6].config.links[0].url).toBe(''); expect(response.data[0].fields[6]?.config?.links?.[0].url).toBe('');
expect(response.data[0].fields[6].config.links[0].title).toBe('Tempo'); expect(response.data[0].fields[6]?.config?.links?.[0].title).toBe('Tempo');
expect(response.data[0].fields[6].config.links[0].internal.query.queryType).toBe('traceqlSearch'); expect(response.data[0].fields[6]?.config?.links?.[0].internal.query.queryType).toBe('traceqlSearch');
expect(response.data[0].fields[6].config.links[0].internal.query.filters[0].value).toBe('${__data.fields[0]}'); expect(response.data[0].fields[6]?.config?.links?.[0].internal.query.filters[0].value).toBe('${__data.fields[0]}');
// Service graph // Service graph
expect(response.data[1].name).toBe('Nodes'); expect(response.data[1].name).toBe('Nodes');
expect(response.data[1].fields[0].values.length).toBe(3); expect(response.data[1].fields[0].values.length).toBe(3);
expect(response.data[1].fields[0].config.links.length).toBeGreaterThan(0); expect(response.data[1].fields[0]?.config?.links?.length).toBeGreaterThan(0);
expect(response.data[1].fields[0].config.links).toEqual(serviceGraphLinks); expect(response.data[1].fields[0]?.config?.links).toEqual(serviceGraphLinks);
expect(response.data[2].name).toBe('Edges'); expect(response.data[2].name).toBe('Edges');
expect(response.data[2].fields[0].values.length).toBe(2); expect(response.data[2].fields[0].values.length).toBe(2);
@ -804,7 +804,7 @@ describe('Tempo service graph view', () => {
fields: [ fields: [
{ {
name: 'Time', name: 'Time',
type: 'time', type: FieldType.time,
config: {}, config: {},
values: [1653828275000, 1653828275000, 1653828275000, 1653828275000, 1653828275000], values: [1653828275000, 1653828275000, 1653828275000, 1653828275000, 1653828275000],
}, },
@ -813,12 +813,14 @@ describe('Tempo service graph view', () => {
config: { config: {
filterable: true, filterable: true,
}, },
type: 'string', type: FieldType.string,
values: ['HTTP Client', 'HTTP GET', 'HTTP GET - root', 'HTTP POST', 'HTTP POST - post'], values: ['HTTP Client', 'HTTP GET', 'HTTP GET - root', 'HTTP POST', 'HTTP POST - post'],
}, },
], ],
values: [],
}, },
]; ];
const objToAlign = { const objToAlign = {
'HTTP GET - root': { 'HTTP GET - root': {
value: '0.1234', value: '0.1234',

View File

@ -6,13 +6,13 @@ import semver from 'semver';
import { import {
CoreApp, CoreApp,
DataFrame, DataFrame,
DataFrameDTO,
DataQueryRequest, DataQueryRequest,
DataQueryResponse, DataQueryResponse,
DataQueryResponseData, DataQueryResponseData,
DataSourceApi, DataSourceApi,
DataSourceInstanceSettings, DataSourceInstanceSettings,
dateTime, dateTime,
Field,
FieldType, FieldType,
isValidGoDuration, isValidGoDuration,
LoadingState, LoadingState,
@ -86,6 +86,17 @@ const featuresToTempoVersion = {
// This is the last minor version of Tempo that does not expose the endpoint for build information. // This is the last minor version of Tempo that does not expose the endpoint for build information.
const defaultTempoVersion = '2.1.0'; const defaultTempoVersion = '2.1.0';
interface ServiceMapQueryResponse {
nodes: DataFrame;
edges: DataFrame;
}
interface ServiceMapQueryResponseWithRates {
rates: Array<DataFrame | DataFrameDTO>;
nodes: DataFrame;
edges: DataFrame;
}
export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJsonData> { export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJsonData> {
tracesToLogs?: TraceToLogsOptions; tracesToLogs?: TraceToLogsOptions;
serviceMap?: { serviceMap?: {
@ -783,7 +794,11 @@ function queryPrometheus(request: DataQueryRequest<PromQuery>, datasourceUid: st
); );
} }
function serviceMapQuery(request: DataQueryRequest<TempoQuery>, datasourceUid: string, tempoDatasourceUid: string) { function serviceMapQuery(
request: DataQueryRequest<TempoQuery>,
datasourceUid: string,
tempoDatasourceUid: string
): Observable<ServiceMapQueryResponse> {
const serviceMapRequest = makePromServiceMapRequest(request); const serviceMapRequest = makePromServiceMapRequest(request);
return queryPrometheus(serviceMapRequest, datasourceUid).pipe( return queryPrometheus(serviceMapRequest, datasourceUid).pipe(
@ -849,7 +864,8 @@ function serviceMapQuery(request: DataQueryRequest<TempoQuery>, datasourceUid: s
} }
return { return {
data: [nodes, edges], nodes,
edges,
state: LoadingState.Done, state: LoadingState.Done,
}; };
}) })
@ -858,9 +874,9 @@ function serviceMapQuery(request: DataQueryRequest<TempoQuery>, datasourceUid: s
function rateQuery( function rateQuery(
request: DataQueryRequest<TempoQuery>, request: DataQueryRequest<TempoQuery>,
serviceMapResponse: DataQueryResponse, serviceMapResponse: ServiceMapQueryResponse,
datasourceUid: string datasourceUid: string
) { ): Observable<ServiceMapQueryResponseWithRates> {
const serviceMapRequest = makePromServiceMapRequest(request); const serviceMapRequest = makePromServiceMapRequest(request);
serviceMapRequest.targets = makeServiceGraphViewRequest([buildExpr(rateMetric, defaultTableFilter, request)]); serviceMapRequest.targets = makeServiceGraphViewRequest([buildExpr(rateMetric, defaultTableFilter, request)]);
@ -872,8 +888,9 @@ function rateQuery(
throw new Error(getErrorMessage(errorRes.error?.message)); throw new Error(getErrorMessage(errorRes.error?.message));
} }
return { return {
data: [responses[0]?.data ?? [], serviceMapResponse.data[0], serviceMapResponse.data[1]], rates: responses[0]?.data ?? [],
state: LoadingState.Done, nodes: serviceMapResponse.nodes,
edges: serviceMapResponse.edges,
}; };
}) })
); );
@ -883,7 +900,7 @@ function rateQuery(
// -> which determine the errorRate/duration span_name(s) we need to query // -> which determine the errorRate/duration span_name(s) we need to query
function errorAndDurationQuery( function errorAndDurationQuery(
request: DataQueryRequest<TempoQuery>, request: DataQueryRequest<TempoQuery>,
rateResponse: DataQueryResponse, rateResponse: ServiceMapQueryResponseWithRates,
datasourceUid: string, datasourceUid: string,
tempoDatasourceUid: string tempoDatasourceUid: string
) { ) {
@ -892,14 +909,14 @@ function errorAndDurationQuery(
let durationsBySpanName: string[] = []; let durationsBySpanName: string[] = [];
let labels = []; let labels = [];
if (rateResponse.data[0][0] && request.app === CoreApp.Explore) { if (rateResponse.rates[0] && request.app === CoreApp.Explore) {
const spanNameField = rateResponse.data[0][0].fields.find((field: Field) => field.name === 'span_name'); const spanNameField = rateResponse.rates[0].fields.find((field) => field.name === 'span_name');
if (spanNameField && spanNameField.values) { if (spanNameField && spanNameField.values) {
labels = spanNameField.values; labels = spanNameField.values;
} }
} else if (rateResponse.data[0]) { } else if (rateResponse.rates) {
rateResponse.data[0].map((df: DataFrame) => { rateResponse.rates.map((df: DataFrame | DataFrameDTO) => {
const spanNameLabels = df.fields.find((field: Field) => field.labels?.['span_name']); const spanNameLabels = df.fields.find((field) => field.labels?.['span_name']);
if (spanNameLabels) { if (spanNameLabels) {
labels.push(spanNameLabels.labels?.['span_name']); labels.push(spanNameLabels.labels?.['span_name']);
} }
@ -941,13 +958,13 @@ function errorAndDurationQuery(
if (serviceGraphView.fields.length === 0) { if (serviceGraphView.fields.length === 0) {
return { return {
data: [rateResponse.data[1], rateResponse.data[2]], data: [rateResponse.nodes, rateResponse.edges],
state: LoadingState.Done, state: LoadingState.Done,
}; };
} }
return { return {
data: [serviceGraphView, rateResponse.data[1], rateResponse.data[2]], data: [serviceGraphView, rateResponse.nodes, rateResponse.edges],
state: LoadingState.Done, state: LoadingState.Done,
}; };
}) })
@ -1078,7 +1095,7 @@ function makePromServiceMapRequest(options: DataQueryRequest<TempoQuery>): DataQ
function getServiceGraphView( function getServiceGraphView(
request: DataQueryRequest<TempoQuery>, request: DataQueryRequest<TempoQuery>,
rateResponse: DataQueryResponse, rateResponse: ServiceMapQueryResponseWithRates,
secondResponse: DataQueryResponse, secondResponse: DataQueryResponse,
errorRateBySpanName: string, errorRateBySpanName: string,
durationsBySpanName: string[], durationsBySpanName: string[],
@ -1086,14 +1103,15 @@ function getServiceGraphView(
tempoDatasourceUid: string tempoDatasourceUid: string
) { ) {
let df: any = { fields: [] }; let df: any = { fields: [] };
const rate = rateResponse.data[0]?.filter((x: { refId: string }) => {
const rate = rateResponse.rates.filter((x) => {
return x.refId === buildExpr(rateMetric, defaultTableFilter, request); return x.refId === buildExpr(rateMetric, defaultTableFilter, request);
}); });
const errorRate = secondResponse.data.filter((x) => { const errorRate = secondResponse.data.filter((x) => {
return x.refId === errorRateBySpanName; return x.refId === errorRateBySpanName;
}); });
const duration = secondResponse.data.filter((x) => { const duration = secondResponse.data.filter((x) => {
return durationsBySpanName.includes(x.refId); return durationsBySpanName.includes(x.refId ?? '');
}); });
if (rate.length > 0 && rate[0].fields?.length > 2) { if (rate.length > 0 && rate[0].fields?.length > 2) {
@ -1193,7 +1211,7 @@ function getServiceGraphView(
if (d.fields.length > 1) { if (d.fields.length > 1) {
const delimiter = d.refId?.includes('span_name=~"') ? 'span_name=~"' : 'span_name="'; const delimiter = d.refId?.includes('span_name=~"') ? 'span_name=~"' : 'span_name="';
const name = d.refId?.split(delimiter)[1].split('"}')[0]; const name = d.refId?.split(delimiter)[1].split('"}')[0];
durationObj[name] = { value: d.fields[1].values[0] }; durationObj[name!] = { value: d.fields[1].values[0] };
} }
}); });
if (Object.keys(durationObj).length > 0) { if (Object.keys(durationObj).length > 0) {

View File

@ -8,6 +8,7 @@ import {
NodeGraphDataFrameFieldNames as Fields, NodeGraphDataFrameFieldNames as Fields,
TimeRange, TimeRange,
FieldType, FieldType,
toDataFrame,
} from '@grafana/data'; } from '@grafana/data';
import { getNonOverlappingDuration, getStats, makeFrames, makeSpanMap } from '../../../core/utils/tracing'; import { getNonOverlappingDuration, getStats, makeFrames, makeSpanMap } from '../../../core/utils/tracing';
@ -189,39 +190,53 @@ function createServiceMapDataFrames() {
} }
const nodes = createDF('Nodes', [ const nodes = createDF('Nodes', [
{ name: Fields.id, type: FieldType.string }, { name: Fields.id, type: FieldType.string, values: [] },
{ name: Fields.title, type: FieldType.string, config: { displayName: 'Service name' } }, { name: Fields.title, type: FieldType.string, config: { displayName: 'Service name' }, values: [] },
{ name: Fields.subTitle, type: FieldType.string, config: { displayName: 'Service namespace' } }, { name: Fields.subTitle, type: FieldType.string, config: { displayName: 'Service namespace' }, values: [] },
{ name: Fields.mainStat, type: FieldType.number, config: { unit: 'ms/r', displayName: 'Average response time' } }, {
name: Fields.mainStat,
type: FieldType.number,
config: { unit: 'ms/r', displayName: 'Average response time' },
values: [],
},
{ {
name: Fields.secondaryStat, name: Fields.secondaryStat,
type: FieldType.number, type: FieldType.number,
config: { unit: 'r/sec', displayName: 'Requests per second' }, config: { unit: 'r/sec', displayName: 'Requests per second' },
values: [],
}, },
{ {
name: Fields.arc + 'success', name: Fields.arc + 'success',
type: FieldType.number, type: FieldType.number,
config: { displayName: 'Success', color: { fixedColor: 'green', mode: FieldColorModeId.Fixed } }, config: { displayName: 'Success', color: { fixedColor: 'green', mode: FieldColorModeId.Fixed } },
values: [],
}, },
{ {
name: Fields.arc + 'failed', name: Fields.arc + 'failed',
type: FieldType.number, type: FieldType.number,
config: { displayName: 'Failed', color: { fixedColor: 'red', mode: FieldColorModeId.Fixed } }, config: { displayName: 'Failed', color: { fixedColor: 'red', mode: FieldColorModeId.Fixed } },
values: [],
}, },
]); ]);
const edges = createDF('Edges', [ const edges = createDF('Edges', [
{ name: Fields.id, type: FieldType.string }, { name: Fields.id, type: FieldType.string, values: [] },
{ name: Fields.source, type: FieldType.string }, { name: Fields.source, type: FieldType.string, values: [] },
{ name: AdditionalEdgeFields.sourceName, type: FieldType.string }, { name: AdditionalEdgeFields.sourceName, type: FieldType.string, values: [] },
{ name: AdditionalEdgeFields.sourceNamespace, type: FieldType.string }, { name: AdditionalEdgeFields.sourceNamespace, type: FieldType.string, values: [] },
{ name: Fields.target, type: FieldType.string }, { name: Fields.target, type: FieldType.string, values: [] },
{ name: AdditionalEdgeFields.targetName, type: FieldType.string }, { name: AdditionalEdgeFields.targetName, type: FieldType.string, values: [] },
{ name: AdditionalEdgeFields.targetNamespace, type: FieldType.string }, { name: AdditionalEdgeFields.targetNamespace, type: FieldType.string, values: [] },
{ name: Fields.mainStat, type: FieldType.number, config: { unit: 'ms/r', displayName: 'Average response time' } }, {
name: Fields.mainStat,
type: FieldType.number,
config: { unit: 'ms/r', displayName: 'Average response time' },
values: [],
},
{ {
name: Fields.secondaryStat, name: Fields.secondaryStat,
type: FieldType.number, type: FieldType.number,
config: { unit: 'r/sec', displayName: 'Requests per second' }, config: { unit: 'r/sec', displayName: 'Requests per second' },
values: [],
}, },
]); ]);
@ -234,8 +249,9 @@ function createServiceMapDataFrames() {
* @param responses * @param responses
*/ */
function getMetricFrames(responses: DataQueryResponse[]): Record<string, DataFrameView> { function getMetricFrames(responses: DataQueryResponse[]): Record<string, DataFrameView> {
return responses[0].data.reduce<Record<string, DataFrameView>>((acc, frame) => { return responses[0].data.reduce<Record<string, DataFrameView>>((acc, frameDTO) => {
acc[frame.refId] = new DataFrameView(frame); const frame = toDataFrame(frameDTO);
acc[frame.refId ?? 'A'] = new DataFrameView(frame);
return acc; return acc;
}, {}); }, {});
} }

View File

@ -60,6 +60,7 @@ export function createTableFrameFromMetricsSummaryQuery(
name: `${series.key}`, name: `${series.key}`,
type: FieldType.string, type: FieldType.string,
config: getConfig(series, configQuery, instanceSettings), config: getConfig(series, configQuery, instanceSettings),
values: [],
}; };
}); });
}); });

View File

@ -16,6 +16,8 @@ import {
createDataFrame, createDataFrame,
getDisplayProcessor, getDisplayProcessor,
createTheme, createTheme,
DataFrameDTO,
toDataFrame,
} from '@grafana/data'; } from '@grafana/data';
import { SearchTableType } from './dataquery.gen'; import { SearchTableType } from './dataquery.gen';
@ -23,7 +25,7 @@ import { createGraphFrames } from './graphTransform';
import { Span, SpanAttributes, Spanset, TraceSearchMetadata } from './types'; import { Span, SpanAttributes, Spanset, TraceSearchMetadata } from './types';
export function createTableFrame( export function createTableFrame(
logsFrame: DataFrame, logsFrame: DataFrame | DataFrameDTO,
datasourceUid: string, datasourceUid: string,
datasourceName: string, datasourceName: string,
traceRegexs: string[] traceRegexs: string[]
@ -38,6 +40,7 @@ export function createTableFrame(
width: 200, width: 200,
}, },
}, },
values: [],
}, },
{ {
name: 'traceID', name: 'traceID',
@ -59,10 +62,12 @@ export function createTableFrame(
}, },
], ],
}, },
values: [],
}, },
{ {
name: 'Message', name: 'Message',
type: FieldType.string, type: FieldType.string,
values: [],
}, },
], ],
meta: { meta: {
@ -80,7 +85,7 @@ export function createTableFrame(
for (let field of logsFrame.fields) { for (let field of logsFrame.fields) {
let hasMatch = false; let hasMatch = false;
if (field.type === FieldType.string) { if (field.type === FieldType.string) {
const values = field.values; const values = field.values!;
for (let i = 0; i < values.length; i++) { for (let i = 0; i < values.length; i++) {
const line = values[i]; const line = values[i];
if (line) { if (line) {
@ -88,7 +93,7 @@ export function createTableFrame(
const match = line.match(traceRegex); const match = line.match(traceRegex);
if (match) { if (match) {
const traceId = match[1]; const traceId = match[1];
const time = timeField ? timeField.values[i] : null; const time = timeField ? timeField.values![i] : null;
tableFrame.fields[0].values.push(time); tableFrame.fields[0].values.push(time);
tableFrame.fields[1].values.push(traceId); tableFrame.fields[1].values.push(traceId);
tableFrame.fields[2].values.push(line); tableFrame.fields[2].values.push(line);
@ -226,23 +231,23 @@ export function transformFromOTLP(
): DataQueryResponse { ): DataQueryResponse {
const frame = new MutableDataFrame({ const frame = new MutableDataFrame({
fields: [ fields: [
{ name: 'traceID', type: FieldType.string }, { name: 'traceID', type: FieldType.string, values: [] },
{ name: 'spanID', type: FieldType.string }, { name: 'spanID', type: FieldType.string, values: [] },
{ name: 'parentSpanID', type: FieldType.string }, { name: 'parentSpanID', type: FieldType.string, values: [] },
{ name: 'operationName', type: FieldType.string }, { name: 'operationName', type: FieldType.string, values: [] },
{ name: 'serviceName', type: FieldType.string }, { name: 'serviceName', type: FieldType.string, values: [] },
{ name: 'kind', type: FieldType.string }, { name: 'kind', type: FieldType.string, values: [] },
{ name: 'statusCode', type: FieldType.number }, { name: 'statusCode', type: FieldType.number, values: [] },
{ name: 'statusMessage', type: FieldType.string }, { name: 'statusMessage', type: FieldType.string, values: [] },
{ name: 'instrumentationLibraryName', type: FieldType.string }, { name: 'instrumentationLibraryName', type: FieldType.string, values: [] },
{ name: 'instrumentationLibraryVersion', type: FieldType.string }, { name: 'instrumentationLibraryVersion', type: FieldType.string, values: [] },
{ name: 'traceState', type: FieldType.string }, { name: 'traceState', type: FieldType.string, values: [] },
{ name: 'serviceTags', type: FieldType.other }, { name: 'serviceTags', type: FieldType.other, values: [] },
{ name: 'startTime', type: FieldType.number }, { name: 'startTime', type: FieldType.number, values: [] },
{ name: 'duration', type: FieldType.number }, { name: 'duration', type: FieldType.number, values: [] },
{ name: 'logs', type: FieldType.other }, { name: 'logs', type: FieldType.other, values: [] },
{ name: 'references', type: FieldType.other }, { name: 'references', type: FieldType.other, values: [] },
{ name: 'tags', type: FieldType.other }, { name: 'tags', type: FieldType.other, values: [] },
], ],
meta: { meta: {
preferredVisualisationType: 'trace', preferredVisualisationType: 'trace',
@ -487,7 +492,7 @@ function getOTLPReferences(
} }
export function transformTrace(response: DataQueryResponse, nodeGraph = false): DataQueryResponse { export function transformTrace(response: DataQueryResponse, nodeGraph = false): DataQueryResponse {
const frame: DataFrame = response.data[0]; const frame = response.data[0];
if (!frame) { if (!frame) {
return emptyDataQueryResponse; return emptyDataQueryResponse;
@ -495,7 +500,7 @@ export function transformTrace(response: DataQueryResponse, nodeGraph = false):
let data = [...response.data]; let data = [...response.data];
if (nodeGraph) { if (nodeGraph) {
data.push(...createGraphFrames(frame)); data.push(...createGraphFrames(toDataFrame(frame)));
} }
return { return {
@ -512,6 +517,7 @@ export function createTableFrameFromSearch(data: TraceSearchMetadata[], instance
{ {
name: 'traceID', name: 'traceID',
type: FieldType.string, type: FieldType.string,
values: [],
config: { config: {
unit: 'string', unit: 'string',
displayNameFromDS: 'Trace ID', displayNameFromDS: 'Trace ID',
@ -531,10 +537,15 @@ export function createTableFrameFromSearch(data: TraceSearchMetadata[], instance
], ],
}, },
}, },
{ name: 'traceService', type: FieldType.string, config: { displayNameFromDS: 'Trace service' } }, { name: 'traceService', type: FieldType.string, config: { displayNameFromDS: 'Trace service' }, values: [] },
{ name: 'traceName', type: FieldType.string, config: { displayNameFromDS: 'Trace name' } }, { name: 'traceName', type: FieldType.string, config: { displayNameFromDS: 'Trace name' }, values: [] },
{ name: 'startTime', type: FieldType.time, config: { displayNameFromDS: 'Start time' } }, { name: 'startTime', type: FieldType.time, config: { displayNameFromDS: 'Start time' }, values: [] },
{ name: 'traceDuration', type: FieldType.number, config: { displayNameFromDS: 'Duration', unit: 'ms' } }, {
name: 'traceDuration',
type: FieldType.number,
config: { displayNameFromDS: 'Duration', unit: 'ms' },
values: [],
},
], ],
meta: { meta: {
preferredVisualisationType: 'table', preferredVisualisationType: 'table',
@ -826,6 +837,7 @@ const traceSubFrame = (
name: attr.key, name: attr.key,
type: FieldType.string, type: FieldType.string,
config: { displayNameFromDS: attr.key }, config: { displayNameFromDS: attr.key },
values: [],
}; };
}); });
spanSet.spans.forEach((span) => { spanSet.spans.forEach((span) => {
@ -837,6 +849,7 @@ const traceSubFrame = (
name: attr.key, name: attr.key,
type: FieldType.string, type: FieldType.string,
config: { displayNameFromDS: attr.key }, config: { displayNameFromDS: attr.key },
values: [],
}; };
}); });
}); });
@ -849,10 +862,12 @@ const traceSubFrame = (
config: { config: {
custom: { hidden: true }, custom: { hidden: true },
}, },
values: [],
}, },
{ {
name: 'spanID', name: 'spanID',
type: FieldType.string, type: FieldType.string,
values: [],
config: { config: {
unit: 'string', unit: 'string',
displayNameFromDS: 'Span ID', displayNameFromDS: 'Span ID',
@ -893,12 +908,14 @@ const traceSubFrame = (
{ {
name: 'name', name: 'name',
type: FieldType.string, type: FieldType.string,
values: [],
config: { displayNameFromDS: 'Name', custom: { hidden: !hasNameAttribute } }, config: { displayNameFromDS: 'Name', custom: { hidden: !hasNameAttribute } },
}, },
...Object.values(spanDynamicAttrs).sort((a, b) => a.name.localeCompare(b.name)), ...Object.values(spanDynamicAttrs).sort((a, b) => a.name.localeCompare(b.name)),
{ {
name: 'duration', name: 'duration',
type: FieldType.number, type: FieldType.number,
values: [],
config: { config: {
displayNameFromDS: 'Duration', displayNameFromDS: 'Duration',
unit: 'ns', unit: 'ns',

View File

@ -1,7 +1,7 @@
import { from, Observable } from 'rxjs'; import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { DataQueryRequest, DataQueryResponse, CustomVariableSupport } from '@grafana/data'; import { DataQueryRequest, CustomVariableSupport, MetricFindValue } from '@grafana/data';
import { TempoVariableQuery, TempoVariableQueryEditor } from './VariableQueryEditor'; import { TempoVariableQuery, TempoVariableQueryEditor } from './VariableQueryEditor';
import { TempoDatasource } from './datasource'; import { TempoDatasource } from './datasource';
@ -13,7 +13,7 @@ export class TempoVariableSupport extends CustomVariableSupport<TempoDatasource,
super(); super();
} }
query(request: DataQueryRequest<TempoVariableQuery>): Observable<DataQueryResponse> { query(request: DataQueryRequest<TempoVariableQuery>): Observable<{ data: MetricFindValue[] }> {
if (!this.datasource) { if (!this.datasource) {
throw new Error('Datasource not initialized'); throw new Error('Datasource not initialized');
} }

View File

@ -9,16 +9,16 @@ export function transformResponse(zSpans: ZipkinSpan[]): DataFrame {
const spanRows = zSpans.map(transformSpan); const spanRows = zSpans.map(transformSpan);
const frame = new MutableDataFrame({ const frame = new MutableDataFrame({
fields: [ fields: [
{ name: 'traceID', type: FieldType.string }, { name: 'traceID', type: FieldType.string, values: [] },
{ name: 'spanID', type: FieldType.string }, { name: 'spanID', type: FieldType.string, values: [] },
{ name: 'parentSpanID', type: FieldType.string }, { name: 'parentSpanID', type: FieldType.string, values: [] },
{ name: 'operationName', type: FieldType.string }, { name: 'operationName', type: FieldType.string, values: [] },
{ name: 'serviceName', type: FieldType.string }, { name: 'serviceName', type: FieldType.string, values: [] },
{ name: 'serviceTags', type: FieldType.other }, { name: 'serviceTags', type: FieldType.other, values: [] },
{ name: 'startTime', type: FieldType.number }, { name: 'startTime', type: FieldType.number, values: [] },
{ name: 'duration', type: FieldType.number }, { name: 'duration', type: FieldType.number, values: [] },
{ name: 'logs', type: FieldType.other }, { name: 'logs', type: FieldType.other, values: [] },
{ name: 'tags', type: FieldType.other }, { name: 'tags', type: FieldType.other, values: [] },
], ],
meta: { meta: {
preferredVisualisationType: 'trace', preferredVisualisationType: 'trace',