Zipkin: Run queries with node graph enabled through backend (#97472)

* Add processing to node graph frames from backend response

* Add tests
This commit is contained in:
Ivana Huckova 2024-12-07 11:06:45 +01:00 committed by GitHub
parent 5f39d2eeb0
commit faa4b683a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 299 additions and 6 deletions

View File

@ -1,11 +1,18 @@
import { lastValueFrom, of } from 'rxjs';
import { createFetchResponse } from 'test/helpers/createFetchResponse';
import { DataQueryRequest, DataSourceInstanceSettings, DataSourcePluginMeta, FieldType } from '@grafana/data';
import {
DataFrameView,
DataQueryRequest,
DataSourceInstanceSettings,
DataSourcePluginMeta,
FieldType,
} from '@grafana/data';
import { BackendSrv, TemplateSrv } from '@grafana/runtime';
import { ZipkinDatasource } from './datasource';
import mockJson from './mockJsonResponse.json';
import { addNodeGraphFramesToResponse, ZipkinDatasource } from './datasource';
import mockJson from './mocks/mockJsonResponse.json';
import { mockTraceDataFrame } from './mocks/mockTraceDataFrame';
import { ZipkinQuery, ZipkinSpan } from './types';
import { traceFrameFields, zipkinResponse } from './utils/testData';
@ -82,6 +89,35 @@ describe('ZipkinDatasource', () => {
});
});
describe('addNodeGraphFramesToResponse', () => {
it('transforms basic response into nodes and edges frame', () => {
const responseWithNodeFrames = addNodeGraphFramesToResponse({ data: mockTraceDataFrame });
let view = new DataFrameView(responseWithNodeFrames.data[1]);
expect(view.get(0)).toMatchObject({
id: '4322526419282105830',
title: 'service1',
subtitle: 'store.validateQueryTimeRange',
mainstat: '0ms (1.6%)',
secondarystat: '0ms (100%)',
color: 0.016,
});
expect(view.get(3)).toMatchObject({
id: '1853508259384889601',
title: 'service1',
subtitle: 'Shipper.Uploads.Query',
mainstat: '0.05ms (18.8%)',
secondarystat: '0.05ms (100%)',
color: 0.188,
});
});
it('handles empty response', () => {
const response = { data: [] };
const responseWithNodeFrames = addNodeGraphFramesToResponse(response);
expect(responseWithNodeFrames).toBe(response);
});
});
function setupBackendSrv(response: ZipkinSpan[]) {
const defaultMock = () => of(createFetchResponse(response));

View File

@ -10,8 +10,9 @@ import {
createDataFrame,
ScopedVars,
urlUtil,
toDataFrame,
} from '@grafana/data';
import { NodeGraphOptions, SpanBarOptions } from '@grafana/o11y-ds-frontend';
import { createNodeGraphFrames, NodeGraphOptions, SpanBarOptions } from '@grafana/o11y-ds-frontend';
import {
BackendSrvRequest,
config,
@ -60,8 +61,15 @@ export class ZipkinDatasource extends DataSourceWithBackend<ZipkinQuery, ZipkinJ
}
if (target.query) {
if (config.featureToggles.zipkinBackendMigration && !this.nodeGraph?.enabled) {
return super.query(options);
if (config.featureToggles.zipkinBackendMigration) {
return super.query(options).pipe(
map((response) => {
if (this.nodeGraph?.enabled) {
return addNodeGraphFramesToResponse(response);
}
return response;
})
);
}
const query = this.applyTemplateVariables(target, options.scopedVars);
return this.request<ZipkinSpan[]>(`${apiPrefix}/trace/${encodeURIComponent(query.query)}`).pipe(
@ -142,6 +150,21 @@ function responseToDataQueryResponse(response: { data: ZipkinSpan[] }, nodeGraph
};
}
export function addNodeGraphFramesToResponse(response: DataQueryResponse): DataQueryResponse {
if (!response.data || response.data.length === 0) {
return response;
}
// This is frame, but it is not typed, so we use toDataFrame to convert it to DataFrame
const frame = toDataFrame(response.data[0]);
const data = [...response.data];
data.push(...createNodeGraphFrames(frame));
return {
...response,
data,
};
}
const emptyDataQueryResponse = {
data: [
createDataFrame({

View File

@ -0,0 +1,234 @@
import { createDataFrame } from '@grafana/data';
export const mockTraceDataFrame = [
createDataFrame({
fields: [
{
name: 'traceID',
values: ['04450900759028499335', '04450900759028499335', '04450900759028499335', '04450900759028499335'],
},
{
name: 'spanID',
values: ['4322526419282105830', '3095626263385822295', '6397320272727147889', '1853508259384889601'],
},
{
name: 'parentSpanID',
values: ['3095626263385822295', '3198122728676260175', '7501257416198979329', ''],
},
{
name: 'operationName',
values: [
'store.validateQueryTimeRange',
'store.validateQuery',
'cachingIndexClient.cacheFetch',
'Shipper.Uploads.Query',
],
},
{
name: 'serviceName',
values: ['service1', 'service1', 'service1', 'service1'],
},
{
name: 'serviceTags',
values: [
[
{
value: 'service1',
key: 'service.name',
},
{
value: 'Zipkin-Go-2.25.0',
key: 'opencensus.exporterversion',
},
{
value: '708c78ea08c1',
key: 'host.hostname',
},
{
value: '172.18.0.3',
key: 'ip',
},
{
value: '632583de9a4a497b',
key: 'client-uuid',
},
],
[
{
value: 'service1',
key: 'service.name',
},
{
value: 'Zipkin-Go-2.25.0',
key: 'opencensus.exporterversion',
},
{
value: '708c78ea08c1',
key: 'host.hostname',
},
{
value: '172.18.0.3',
key: 'ip',
},
{
value: '632583de9a4a497b',
key: 'client-uuid',
},
],
[
{
value: 'service1',
key: 'service.name',
},
{
value: 'Zipkin-Go-2.25.0',
key: 'opencensus.exporterversion',
},
{
value: '708c78ea08c1',
key: 'host.hostname',
},
{
value: '172.18.0.3',
key: 'ip',
},
{
value: '632583de9a4a497b',
key: 'client-uuid',
},
],
[
{
value: 'service1',
key: 'service.name',
},
{
value: 'Zipkin-Go-2.25.0',
key: 'opencensus.exporterversion',
},
{
value: '708c78ea08c1',
key: 'host.hostname',
},
{
value: '172.18.0.3',
key: 'ip',
},
{
value: '632583de9a4a497b',
key: 'client-uuid',
},
],
],
},
{
name: 'startTime',
values: [1619712655875.4539, 1619712655875.4502, 1619712655875.592, 1619712655875.653],
},
{
name: 'duration',
values: [0.004, 0.016, 0.039, 0.047],
},
{
name: 'logs',
values: [
null,
null,
[
{
timestamp: 1619712655875.631,
fields: [
{
value: 'debug',
key: 'level',
},
{
value: 0,
key: 'hits',
},
{
value: 16,
key: 'misses',
},
],
},
],
[
{
timestamp: 1619712655875.738,
fields: [
{
value: 'debug',
key: 'level',
},
{
value: 'index_18746',
key: 'table-name',
},
{
value: 16,
key: 'query-count',
},
],
},
{
timestamp: 1619712655875.773,
fields: [
{
value: 'debug',
key: 'level',
},
{
value: 'compactor-1619711145.gz',
key: 'queried-db',
},
],
},
{
timestamp: 1619712655875.794,
fields: [
{
value: 'debug',
key: 'level',
},
{
value: '708c78ea08c1-1619516350042748959-1619711100.gz',
key: 'queried-db',
},
],
},
],
],
},
{
name: 'tags',
values: [
[
{
value: 0,
key: 'status.code',
},
],
[
{
value: 0,
key: 'status.code',
},
],
[
{
value: 0,
key: 'status.code',
},
],
[
{
value: 0,
key: 'status.code',
},
],
],
},
],
}),
];