Jaeger: Run traceID queries through backend when node graph is enabled (#104029)
* Refactor current solution * Run traceid queries with enabled node graph through backend * Update test * Fix lint * Uodate based on feedback, don't spread
This commit is contained in:
@@ -9,7 +9,7 @@ import {
|
|||||||
PluginType,
|
PluginType,
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { BackendSrv } from '@grafana/runtime';
|
import { BackendSrv, config, DataSourceWithBackend } from '@grafana/runtime';
|
||||||
|
|
||||||
import { ALL_OPERATIONS_KEY } from './components/SearchForm';
|
import { ALL_OPERATIONS_KEY } from './components/SearchForm';
|
||||||
import { JaegerDatasource, JaegerJsonData } from './datasource';
|
import { JaegerDatasource, JaegerJsonData } from './datasource';
|
||||||
@@ -307,6 +307,102 @@ describe('JaegerDatasource', () => {
|
|||||||
url: `${defaultSettings.url}/api/traces?service=interpolationText&operation=interpolationText&minDuration=interpolationText&maxDuration=interpolationText&${defaultSearchRangeParams}&lookback=custom`,
|
url: `${defaultSettings.url}/api/traces?service=interpolationText&operation=interpolationText&minDuration=interpolationText&maxDuration=interpolationText&${defaultSearchRangeParams}&lookback=custom`,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when jaegerBackendMigration feature toggle is enabled', () => {
|
||||||
|
let originalFeatureToggleValue: boolean | undefined;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
originalFeatureToggleValue = config.featureToggles.jaegerBackendMigration;
|
||||||
|
config.featureToggles.jaegerBackendMigration = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
config.featureToggles.jaegerBackendMigration = originalFeatureToggleValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add node graph frames to response when nodeGraph is enabled and query is a trace ID query', async () => {
|
||||||
|
// Create a datasource with nodeGraph enabled
|
||||||
|
const settings = {
|
||||||
|
...defaultSettings,
|
||||||
|
jsonData: {
|
||||||
|
...defaultSettings.jsonData,
|
||||||
|
nodeGraph: { enabled: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const ds = new JaegerDatasource(settings);
|
||||||
|
|
||||||
|
// Mock the super.query method to return our mock response
|
||||||
|
jest.spyOn(DataSourceWithBackend.prototype, 'query').mockImplementation(() => {
|
||||||
|
return of({
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
fields: testResponseDataFrameFields,
|
||||||
|
values: testResponseDataFrameFields.values,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a query without queryType (trace ID query)
|
||||||
|
const query = {
|
||||||
|
...defaultQuery,
|
||||||
|
targets: [
|
||||||
|
{
|
||||||
|
query: '12345',
|
||||||
|
refId: '1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Execute the query
|
||||||
|
const response = await lastValueFrom(ds.query(query));
|
||||||
|
// Verify that the response contains the original data plus node graph frames
|
||||||
|
expect(response.data.length).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not add node graph frames when nodeGraph is disabled', async () => {
|
||||||
|
// Create a datasource with nodeGraph disabled
|
||||||
|
const settings = {
|
||||||
|
...defaultSettings,
|
||||||
|
jsonData: {
|
||||||
|
...defaultSettings.jsonData,
|
||||||
|
nodeGraph: { enabled: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const ds = new JaegerDatasource(settings);
|
||||||
|
|
||||||
|
// Mock the super.query method to return our mock response
|
||||||
|
jest.spyOn(DataSourceWithBackend.prototype, 'query').mockImplementation(() => {
|
||||||
|
return of({
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
fields: testResponseDataFrameFields,
|
||||||
|
values: testResponseDataFrameFields.values,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a query without queryType (trace ID query)
|
||||||
|
const query = {
|
||||||
|
...defaultQuery,
|
||||||
|
targets: [
|
||||||
|
{
|
||||||
|
query: '12345',
|
||||||
|
refId: '1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Execute the query
|
||||||
|
const response = await lastValueFrom(ds.query(query));
|
||||||
|
// Verify that the response contains only the original data
|
||||||
|
expect(response.data.length).toBe(1);
|
||||||
|
expect(response.data[0].fields).toMatchObject(testResponseDataFrameFields);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when performing testDataSource', () => {
|
describe('when performing testDataSource', () => {
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ import {
|
|||||||
getDefaultTimeRange,
|
getDefaultTimeRange,
|
||||||
MutableDataFrame,
|
MutableDataFrame,
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
|
toDataFrame,
|
||||||
urlUtil,
|
urlUtil,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { NodeGraphOptions, SpanBarOptions } from '@grafana/o11y-ds-frontend';
|
import { createNodeGraphFrames, NodeGraphOptions, SpanBarOptions } from '@grafana/o11y-ds-frontend';
|
||||||
import {
|
import {
|
||||||
BackendSrvRequest,
|
BackendSrvRequest,
|
||||||
config,
|
config,
|
||||||
@@ -69,29 +70,29 @@ export class JaegerDatasource extends DataSourceWithBackend<JaegerQuery, JaegerJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
query(options: DataQueryRequest<JaegerQuery>): Observable<DataQueryResponse> {
|
query(options: DataQueryRequest<JaegerQuery>): Observable<DataQueryResponse> {
|
||||||
// No query type means that the query is a trace ID query
|
|
||||||
// If all targets are trace ID queries, we can use the backend querying
|
|
||||||
const allTargetsTraceIdQuery = options.targets.every((target) => !target.queryType);
|
|
||||||
const allTargetsDependencyGraph = options.targets.every((target) => target.queryType === 'dependencyGraph');
|
|
||||||
// We have not migrated the node graph to the backend
|
|
||||||
// If the node graph is disabled, we can use the backend migration
|
|
||||||
const nodeGraphDisabled = !this.nodeGraph?.enabled;
|
|
||||||
if (
|
|
||||||
config.featureToggles.jaegerBackendMigration &&
|
|
||||||
(allTargetsTraceIdQuery || allTargetsDependencyGraph) &&
|
|
||||||
nodeGraphDisabled
|
|
||||||
) {
|
|
||||||
return super.query(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this moment we expect only one target. In case we somehow change the UI to be able to show multiple
|
// At this moment we expect only one target. In case we somehow change the UI to be able to show multiple
|
||||||
// traces at one we need to change this.
|
// traces at one we need to change this.
|
||||||
const target: JaegerQuery = options.targets[0];
|
const target: JaegerQuery = options.targets[0];
|
||||||
|
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return of({ data: [emptyTraceDataFrame] });
|
return of({ data: [emptyTraceDataFrame] });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
config.featureToggles.jaegerBackendMigration &&
|
||||||
|
// No query type means that the query is a trace ID query
|
||||||
|
(!target.queryType || target.queryType === 'dependencyGraph')
|
||||||
|
) {
|
||||||
|
return super.query({ ...options, targets: [target] }).pipe(
|
||||||
|
map((response) => {
|
||||||
|
// If the node graph is enabled and the query is a trace ID query, add the node graph frames to the response
|
||||||
|
if (this.nodeGraph?.enabled && !target.queryType) {
|
||||||
|
return addNodeGraphFramesToResponse(response);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Use the internal Jaeger /dependencies API for rendering the dependency graph.
|
// Use the internal Jaeger /dependencies API for rendering the dependency graph.
|
||||||
if (target.queryType === 'dependencyGraph') {
|
if (target.queryType === 'dependencyGraph') {
|
||||||
const timeRange = options.range ?? getDefaultTimeRange();
|
const timeRange = options.range ?? getDefaultTimeRange();
|
||||||
@@ -309,3 +310,18 @@ const emptyTraceDataFrame = new MutableDataFrame({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function addNodeGraphFramesToResponse(response: DataQueryResponse): DataQueryResponse {
|
||||||
|
if (!response.data || response.data.length === 0) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the first frame to a DataFrame for node graph processing
|
||||||
|
const frame = toDataFrame(response.data[0]);
|
||||||
|
// Add the node graph frames to the response
|
||||||
|
const data = response.data.concat(createNodeGraphFrames(frame));
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user