mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 19:00:54 -06:00
TraceToLogs: Enable trace-to-log feature for cloud-logging-data-source-plugin (#65614)
* TraceToLogs: Enable trace-to-log feature for cloud-logging-data-source-plugin * TraceToLogs: Add tests for googlecloud-logging-datasource
This commit is contained in:
parent
8ca9a89cf1
commit
111118dd68
@ -78,6 +78,7 @@ export function TraceToLogsSettings({ options, onOptionsChange }: Props) {
|
|||||||
'grafana-splunk-datasource', // external
|
'grafana-splunk-datasource', // external
|
||||||
'grafana-opensearch-datasource', // external
|
'grafana-opensearch-datasource', // external
|
||||||
'grafana-falconlogscale-datasource', // external
|
'grafana-falconlogscale-datasource', // external
|
||||||
|
'googlecloud-logging-datasource', // external
|
||||||
];
|
];
|
||||||
|
|
||||||
const traceToLogs = useMemo(
|
const traceToLogs = useMemo(
|
||||||
|
@ -810,6 +810,189 @@ describe('createSpanLinkFactory', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('google cloud link', () => {
|
||||||
|
const searchUID = 'searchUID';
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
setDataSourceSrv({
|
||||||
|
getInstanceSettings() {
|
||||||
|
return {
|
||||||
|
uid: searchUID,
|
||||||
|
name: 'Google Cloud Logging',
|
||||||
|
type: 'googlecloud-logging-datasource',
|
||||||
|
} as unknown as DataSourceInstanceSettings;
|
||||||
|
},
|
||||||
|
} as unknown as DataSourceSrv);
|
||||||
|
|
||||||
|
setLinkSrv(new LinkSrv());
|
||||||
|
setTemplateSrv(new TemplateSrv());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('creates link with correct simple query', () => {
|
||||||
|
const createLink = setupSpanLinkFactory({
|
||||||
|
datasourceUid: searchUID,
|
||||||
|
});
|
||||||
|
const links = createLink!(createTraceSpan());
|
||||||
|
|
||||||
|
const linkDef = links?.logLinks?.[0];
|
||||||
|
expect(linkDef).toBeDefined();
|
||||||
|
expect(decodeURIComponent(linkDef!.href)).toContain(
|
||||||
|
`datasource":"${searchUID}","queries":[{"query":"cluster=\\"cluster1\\" AND hostname=\\"hostname1\\"","refId":""}]`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('automatically timeshifts the time range by one second in a query', () => {
|
||||||
|
const createLink = setupSpanLinkFactory({
|
||||||
|
datasourceUid: searchUID,
|
||||||
|
});
|
||||||
|
const links = createLink!(createTraceSpan());
|
||||||
|
|
||||||
|
const linkDef = links?.logLinks?.[0];
|
||||||
|
expect(linkDef).toBeDefined();
|
||||||
|
expect(linkDef!.href).toContain(
|
||||||
|
`${encodeURIComponent('{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"}')}`
|
||||||
|
);
|
||||||
|
expect(linkDef!.href).not.toContain(
|
||||||
|
`${encodeURIComponent('{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:00.000Z"}')}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats query correctly if filterByTraceID and or filterBySpanID is true', () => {
|
||||||
|
const createLink = setupSpanLinkFactory(
|
||||||
|
{
|
||||||
|
datasourceUid: searchUID,
|
||||||
|
filterByTraceID: true,
|
||||||
|
filterBySpanID: true,
|
||||||
|
},
|
||||||
|
searchUID
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(createLink).toBeDefined();
|
||||||
|
const links = createLink!(createTraceSpan());
|
||||||
|
|
||||||
|
const linkDef = links?.logLinks?.[0];
|
||||||
|
expect(linkDef).toBeDefined();
|
||||||
|
expect(linkDef!.href).toBe(
|
||||||
|
`/explore?left=${encodeURIComponent(
|
||||||
|
`{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${searchUID}","queries":[{"query":"\\"6605c7b08e715d6c\\" AND \\"7946b05c2e2e4e5a\\" AND cluster=\\"cluster1\\" AND hostname=\\"hostname1\\"","refId":""}]}`
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats query correctly if only filterByTraceID is true', () => {
|
||||||
|
const createLink = setupSpanLinkFactory(
|
||||||
|
{
|
||||||
|
datasourceUid: searchUID,
|
||||||
|
filterByTraceID: true,
|
||||||
|
},
|
||||||
|
searchUID
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(createLink).toBeDefined();
|
||||||
|
const links = createLink!(
|
||||||
|
createTraceSpan({
|
||||||
|
process: {
|
||||||
|
serviceName: 'service',
|
||||||
|
tags: [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const linkDef = links?.logLinks?.[0];
|
||||||
|
expect(linkDef).toBeDefined();
|
||||||
|
expect(decodeURIComponent(linkDef!.href)).toBe(
|
||||||
|
`/explore?left={"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"searchUID","queries":[{"query":"\\"7946b05c2e2e4e5a\\"","refId":""}]}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format one tag correctly', () => {
|
||||||
|
const createLink = setupSpanLinkFactory(
|
||||||
|
{
|
||||||
|
tags: [{ key: 'ip' }],
|
||||||
|
},
|
||||||
|
searchUID
|
||||||
|
);
|
||||||
|
expect(createLink).toBeDefined();
|
||||||
|
const links = createLink!(
|
||||||
|
createTraceSpan({
|
||||||
|
process: {
|
||||||
|
serviceName: 'service',
|
||||||
|
tags: [{ key: 'ip', value: '192.168.0.1' }],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const linkDef = links?.logLinks?.[0];
|
||||||
|
expect(linkDef).toBeDefined();
|
||||||
|
expect(linkDef!.href).toBe(
|
||||||
|
`/explore?left=${encodeURIComponent(
|
||||||
|
`{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${searchUID}","queries":[{"query":"ip=\\"192.168.0.1\\"","refId":""}]}`
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format multiple tags correctly', () => {
|
||||||
|
const createLink = setupSpanLinkFactory(
|
||||||
|
{
|
||||||
|
tags: [{ key: 'ip' }, { key: 'hostname' }],
|
||||||
|
},
|
||||||
|
searchUID
|
||||||
|
);
|
||||||
|
expect(createLink).toBeDefined();
|
||||||
|
const links = createLink!(
|
||||||
|
createTraceSpan({
|
||||||
|
process: {
|
||||||
|
serviceName: 'service',
|
||||||
|
tags: [
|
||||||
|
{ key: 'hostname', value: 'hostname1' },
|
||||||
|
{ key: 'ip', value: '192.168.0.1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const linkDef = links?.logLinks?.[0];
|
||||||
|
expect(linkDef).toBeDefined();
|
||||||
|
expect(linkDef!.href).toBe(
|
||||||
|
`/explore?left=${encodeURIComponent(
|
||||||
|
`{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${searchUID}","queries":[{"query":"hostname=\\"hostname1\\" AND ip=\\"192.168.0.1\\"","refId":""}]}`
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles renamed tags', () => {
|
||||||
|
const createLink = setupSpanLinkFactory(
|
||||||
|
{
|
||||||
|
tags: [
|
||||||
|
{ key: 'service.name', value: 'service' },
|
||||||
|
{ key: 'k8s.pod.name', value: 'pod' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
searchUID
|
||||||
|
);
|
||||||
|
expect(createLink).toBeDefined();
|
||||||
|
const links = createLink!(
|
||||||
|
createTraceSpan({
|
||||||
|
process: {
|
||||||
|
serviceName: 'service',
|
||||||
|
tags: [
|
||||||
|
{ key: 'service.name', value: 'serviceName' },
|
||||||
|
{ key: 'k8s.pod.name', value: 'podName' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const linkDef = links?.logLinks?.[0];
|
||||||
|
expect(linkDef).toBeDefined();
|
||||||
|
expect(linkDef!.href).toBe(
|
||||||
|
`/explore?left=${encodeURIComponent(
|
||||||
|
`{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${searchUID}","queries":[{"query":"service=\\"serviceName\\" AND pod=\\"podName\\"","refId":""}]}`
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('custom query', () => {
|
describe('custom query', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
setDataSourceSrv({
|
setDataSourceSrv({
|
||||||
|
@ -165,6 +165,10 @@ function legacyCreateSpanLinkFactory(
|
|||||||
case 'grafana-falconlogscale-datasource':
|
case 'grafana-falconlogscale-datasource':
|
||||||
tags = getFormattedTags(span, tagsToUse, { joinBy: ' OR ' });
|
tags = getFormattedTags(span, tagsToUse, { joinBy: ' OR ' });
|
||||||
query = getQueryForFalconLogScale(span, traceToLogsOptions, tags, customQuery);
|
query = getQueryForFalconLogScale(span, traceToLogsOptions, tags, customQuery);
|
||||||
|
break;
|
||||||
|
case 'googlecloud-logging-datasource':
|
||||||
|
tags = getFormattedTags(span, tagsToUse, { joinBy: ' AND ' });
|
||||||
|
query = getQueryForGoogleCloudLogging(span, traceToLogsOptions, tags, customQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
// query can be false in case the simple UI tag mapping is used but none of them are present in the span.
|
// query can be false in case the simple UI tag mapping is used but none of them are present in the span.
|
||||||
@ -406,6 +410,37 @@ function getQueryForSplunk(span: TraceSpan, options: TraceToLogsOptionsV2, tags:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getQueryForGoogleCloudLogging(
|
||||||
|
span: TraceSpan,
|
||||||
|
options: TraceToLogsOptionsV2,
|
||||||
|
tags: string,
|
||||||
|
customQuery?: string
|
||||||
|
) {
|
||||||
|
const { filterByTraceID, filterBySpanID } = options;
|
||||||
|
|
||||||
|
if (customQuery) {
|
||||||
|
return { query: customQuery, refId: '' };
|
||||||
|
}
|
||||||
|
|
||||||
|
let queryArr = [];
|
||||||
|
if (filterBySpanID && span.spanID) {
|
||||||
|
queryArr.push('"${__span.spanId}"');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filterByTraceID && span.traceID) {
|
||||||
|
queryArr.push('"${__span.traceId}"');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags) {
|
||||||
|
queryArr.push('${__tags}');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
query: queryArr.join(' AND '),
|
||||||
|
refId: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function getQueryForFalconLogScale(span: TraceSpan, options: TraceToLogsOptionsV2, tags: string, customQuery?: string) {
|
function getQueryForFalconLogScale(span: TraceSpan, options: TraceToLogsOptionsV2, tags: string, customQuery?: string) {
|
||||||
const { filterByTraceID, filterBySpanID } = options;
|
const { filterByTraceID, filterBySpanID } = options;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user