Tracing: Prevent createSpanLink from returning an invalid Loki query (#46864)

This commit is contained in:
Connor Lindsey 2022-03-23 10:48:11 -06:00 committed by GitHub
parent aabafee90a
commit 78c23d8dab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 3 deletions

View File

@ -195,6 +195,25 @@ describe('createSpanLinkFactory', () => {
)}` )}`
); );
}); });
it('handles empty queries', () => {
const createLink = setupSpanLinkFactory({
tags: [],
});
expect(createLink).toBeDefined();
const linkDef = createLink!(
createTraceSpan({
process: {
serviceName: 'service',
tags: [
{ key: 'service.name', value: 'serviceName' },
{ key: 'k8s.pod.name', value: 'podName' },
],
},
})
);
expect(linkDef).toBeUndefined();
});
}); });
}); });

View File

@ -75,12 +75,17 @@ function legacyCreateSpanLinkFactory(splitOpenFn: SplitOpen, traceToLogsOptions?
return undefined; return undefined;
} }
return function SpanLink(span: TraceSpan): SpanLinkDef { return function SpanLink(span: TraceSpan): SpanLinkDef | undefined {
// This is reusing existing code from derived fields which may not be ideal match so some data is a bit faked at // This is reusing existing code from derived fields which may not be ideal match so some data is a bit faked at
// the moment. Issue is that the trace itself isn't clearly mapped to dataFrame (right now it's just a json blob // the moment. Issue is that the trace itself isn't clearly mapped to dataFrame (right now it's just a json blob
// inside a single field) so the dataLinks as config of that dataFrame abstraction breaks down a bit and we do // inside a single field) so the dataLinks as config of that dataFrame abstraction breaks down a bit and we do
// it manually here instead of leaving it for the data source to supply the config. // it manually here instead of leaving it for the data source to supply the config.
const expr = getLokiQueryFromSpan(span, traceToLogsOptions);
if (!expr) {
return undefined;
}
const dataLink: DataLink<LokiQuery> = { const dataLink: DataLink<LokiQuery> = {
title: dataSourceSettings.name, title: dataSourceSettings.name,
url: '', url: '',
@ -88,7 +93,7 @@ function legacyCreateSpanLinkFactory(splitOpenFn: SplitOpen, traceToLogsOptions?
datasourceUid: dataSourceSettings.uid, datasourceUid: dataSourceSettings.uid,
datasourceName: dataSourceSettings.name, datasourceName: dataSourceSettings.name,
query: { query: {
expr: getLokiQueryFromSpan(span, traceToLogsOptions), expr,
refId: '', refId: '',
}, },
}, },
@ -122,7 +127,7 @@ function legacyCreateSpanLinkFactory(splitOpenFn: SplitOpen, traceToLogsOptions?
*/ */
const defaultKeys = ['cluster', 'hostname', 'namespace', 'pod']; const defaultKeys = ['cluster', 'hostname', 'namespace', 'pod'];
function getLokiQueryFromSpan(span: TraceSpan, options: TraceToLogsOptions): string { function getLokiQueryFromSpan(span: TraceSpan, options: TraceToLogsOptions): string | undefined {
const { tags: keys, filterByTraceID, filterBySpanID, mapTagNamesEnabled, mappedTags } = options; const { tags: keys, filterByTraceID, filterBySpanID, mapTagNamesEnabled, mappedTags } = options;
// In order, try to use mapped tags -> tags -> default tags // In order, try to use mapped tags -> tags -> default tags
@ -143,6 +148,11 @@ function getLokiQueryFromSpan(span: TraceSpan, options: TraceToLogsOptions): str
return acc; return acc;
}, [] as string[]); }, [] as string[]);
// If no tags found, return undefined to prevent an invalid Loki query
if (!tags.length) {
return undefined;
}
let query = `{${tags.join(', ')}}`; let query = `{${tags.join(', ')}}`;
if (filterByTraceID && span.traceID) { if (filterByTraceID && span.traceID) {