From 5f27959a5e23095e95f5f4d6fa20a7072cb6fb91 Mon Sep 17 00:00:00 2001 From: Andrej Ocenas Date: Wed, 3 Nov 2021 15:56:39 +0100 Subject: [PATCH] Tempo: Add links to nodes in Service Graph pointing to Prometheus metrics (#41135) --- .../datasource/tempo/datasource.test.ts | 1 + .../plugins/datasource/tempo/datasource.ts | 26 +++++++++++++++++-- .../datasource/tempo/graphTransform.test.ts | 2 +- .../datasource/tempo/graphTransform.ts | 17 +++++++----- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/public/app/plugins/datasource/tempo/datasource.test.ts b/public/app/plugins/datasource/tempo/datasource.test.ts index 0e557d2b37b..b9c1abc8155 100644 --- a/public/app/plugins/datasource/tempo/datasource.test.ts +++ b/public/app/plugins/datasource/tempo/datasource.test.ts @@ -97,6 +97,7 @@ describe('Tempo data source', () => { expect(response.data).toHaveLength(2); expect(response.data[0].name).toBe('Nodes'); expect(response.data[0].fields[0].values.length).toBe(3); + expect(response.data[0].fields[0].config.links.length).toBeGreaterThan(0); expect(response.data[1].name).toBe('Edges'); expect(response.data[1].fields[0].values.length).toBe(2); diff --git a/public/app/plugins/datasource/tempo/datasource.ts b/public/app/plugins/datasource/tempo/datasource.ts index 51069ad85a0..998007b45b1 100644 --- a/public/app/plugins/datasource/tempo/datasource.ts +++ b/public/app/plugins/datasource/tempo/datasource.ts @@ -19,7 +19,7 @@ import Prism from 'prismjs'; import { LokiOptions, LokiQuery } from '../loki/types'; import { PrometheusDatasource } from '../prometheus/datasource'; import { PromQuery } from '../prometheus/types'; -import { mapPromMetricsToServiceMap, serviceMapMetrics } from './graphTransform'; +import { failedMetric, mapPromMetricsToServiceMap, serviceMapMetrics, totalsMetric } from './graphTransform'; import { transformTrace, transformTraceList, @@ -288,14 +288,36 @@ function serviceMapQuery(request: DataQueryRequest, datasourceUid: s throw new Error(errorRes.error!.message); } + const { nodes, edges } = mapPromMetricsToServiceMap(responses, request.range); + nodes.fields[0].config = { + links: [ + makePromLink('Total requests', totalsMetric, datasourceUid), + makePromLink('Failed requests', failedMetric, datasourceUid), + ], + }; + return { - data: mapPromMetricsToServiceMap(responses, request.range), + data: [nodes, edges], state: LoadingState.Done, }; }) ); } +function makePromLink(title: string, metric: string, datasourceUid: string) { + return { + url: '', + title, + internal: { + query: { + expr: metric, + } as PromQuery, + datasourceUid, + datasourceName: 'Prometheus', + }, + }; +} + function makePromServiceMapRequest(options: DataQueryRequest): DataQueryRequest { return { ...options, diff --git a/public/app/plugins/datasource/tempo/graphTransform.test.ts b/public/app/plugins/datasource/tempo/graphTransform.test.ts index 639fcd22852..990088eacae 100644 --- a/public/app/plugins/datasource/tempo/graphTransform.test.ts +++ b/public/app/plugins/datasource/tempo/graphTransform.test.ts @@ -64,7 +64,7 @@ describe('mapPromMetricsToServiceMap', () => { from: dateTime('2000-01-01T00:00:00'), to: dateTime('2000-01-01T00:01:00'), }; - const [nodes, edges] = mapPromMetricsToServiceMap( + const { nodes, edges } = mapPromMetricsToServiceMap( [{ data: [totalsPromMetric, secondsPromMetric, failedPromMetric] }], { ...range, diff --git a/public/app/plugins/datasource/tempo/graphTransform.ts b/public/app/plugins/datasource/tempo/graphTransform.ts index 5ce34e5806a..8164109f4c5 100644 --- a/public/app/plugins/datasource/tempo/graphTransform.ts +++ b/public/app/plugins/datasource/tempo/graphTransform.ts @@ -130,9 +130,9 @@ function findTraceDuration(view: DataFrameView): number { return traceEndTime - traceStartTime; } -const secondsMetric = 'traces_service_graph_request_server_seconds_sum'; -const totalsMetric = 'traces_service_graph_request_total'; -const failedMetric = 'traces_service_graph_request_failed_total'; +export const secondsMetric = 'traces_service_graph_request_server_seconds_sum'; +export const totalsMetric = 'traces_service_graph_request_total'; +export const failedMetric = 'traces_service_graph_request_failed_total'; export const serviceMapMetrics = [ secondsMetric, @@ -151,7 +151,10 @@ export const serviceMapMetrics = [ * @param responses * @param range */ -export function mapPromMetricsToServiceMap(responses: DataQueryResponse[], range: TimeRange): [DataFrame, DataFrame] { +export function mapPromMetricsToServiceMap( + responses: DataQueryResponse[], + range: TimeRange +): { nodes: DataFrame; edges: DataFrame } { const frames = getMetricFrames(responses); // First just collect data from the metrics into a map with nodes and edges as keys @@ -172,7 +175,7 @@ function createServiceMapDataFrames() { const nodes = createDF('Nodes', [ { name: Fields.id }, - { name: Fields.title }, + { name: Fields.title, config: { displayName: 'Service name' } }, { name: Fields.mainStat, config: { unit: 'ms/r', displayName: 'Average response time' } }, { name: Fields.secondaryStat, @@ -289,7 +292,7 @@ function convertToDataFrames( nodesMap: Record, edgesMap: Record, range: TimeRange -): [DataFrame, DataFrame] { +): { nodes: DataFrame; edges: DataFrame } { const rangeMs = range.to.valueOf() - range.from.valueOf(); const [nodes, edges] = createServiceMapDataFrames(); for (const nodeId of Object.keys(nodesMap)) { @@ -316,5 +319,5 @@ function convertToDataFrames( }); } - return [nodes, edges]; + return { nodes, edges }; }