Explore: Add filter by trace and span ID to trace to logs feature (#38943)

* Add filter by trace and span ID to trace to logs feature

* Update settings screenshot
This commit is contained in:
Connor Lindsey
2021-09-09 07:24:08 -06:00
committed by GitHub
parent dc36f15fbb
commit e3c11d2682
6 changed files with 108 additions and 7 deletions
+3 -1
View File
@@ -34,8 +34,10 @@ This is a configuration for the [trace to logs feature]({{< relref "../explore/t
- **Tags -** The tags that will be used in the Loki query. Default is `'cluster', 'hostname', 'namespace', 'pod'`.
- **Span start time shift -** Shift in the start time for the Loki query based on the span start time. In order to extend to the past, you need to use a negative value. Use time interval units like 5s, 1m, 3h. The default is 0.
- **Span end time shift -** Shift in the end time for the Loki query based on the span end time. Time units can be used here, for example, 5s, 1m, 3h. The default is 0.
- **Filter by Trace ID -** Toggle to append the trace ID to the Loki query.
- **Filter by Span ID -** Toggle to append the span ID to the Loki query.
![Trace to logs settings](/static/img/docs/explore/trace-to-logs-settings-8.png 'Screenshot of the trace to logs settings')
![Trace to logs settings](/static/img/docs/explore/trace-to-logs-settings-8-2.png 'Screenshot of the trace to logs settings')
## Query traces
+3 -1
View File
@@ -33,8 +33,10 @@ This is a configuration for the [trace to logs feature]({{< relref "../explore/t
- **Tags -** The tags that will be used in the Loki query. Default is `'cluster', 'hostname', 'namespace', 'pod'`.
- **Span start time shift -** A shift in the start time for the Loki query based on the start time for the span. To extend the time to the past, use a negative value. You can use time units, for example, 5s, 1m, 3h. The default is 0.
- **Span end time shift -** Shift in the end time for the Loki query based on the span end time. Time units can be used here, for example, 5s, 1m, 3h. The default is 0.
- **Filter by Trace ID -** Toggle to append the trace ID to the Loki query.
- **Filter by Span ID -** Toggle to append the span ID to the Loki query.
![Trace to logs settings](/static/img/docs/explore/trace-to-logs-settings-8.png 'Screenshot of the trace to logs settings')
![Trace to logs settings](/static/img/docs/explore/trace-to-logs-settings-8-2.png 'Screenshot of the trace to logs settings')
## Query traces
+3 -1
View File
@@ -34,8 +34,10 @@ This is a configuration for the [trace to logs feature]({{< relref "../explore/t
- **Tags -** The tags that will be used in the Loki query. Default is `'cluster', 'hostname', 'namespace', 'pod'`.
- **Span start time shift -** Shift in the start time for the Loki query based on the span start time. In order to extend to the past, you need to use a negative value. Use time interval units like 5s, 1m, 3h. The default is 0.
- **Span end time shift -** Shift in the end time for the Loki query based on the span end time. Time units can be used here, for example, 5s, 1m, 3h. The default is 0.
- **Filter by Trace ID -** Toggle to append the trace ID to the Loki query.
- **Filter by Span ID -** Toggle to append the span ID to the Loki query.
![Trace to logs settings](/static/img/docs/explore/trace-to-logs-settings-8.png 'Screenshot of the trace to logs settings')
![Trace to logs settings](/static/img/docs/explore/trace-to-logs-settings-8-2.png 'Screenshot of the trace to logs settings')
## Query traces
@@ -6,7 +6,7 @@ import {
updateDatasourcePluginJsonDataOption,
} from '@grafana/data';
import { DataSourcePicker } from '@grafana/runtime';
import { InlineField, InlineFieldRow, Input, TagsInput, useStyles } from '@grafana/ui';
import { InlineField, InlineFieldRow, Input, TagsInput, useStyles, InlineSwitch } from '@grafana/ui';
import React from 'react';
export interface TraceToLogsOptions {
@@ -14,6 +14,8 @@ export interface TraceToLogsOptions {
tags?: string[];
spanStartTimeShift?: string;
spanEndTimeShift?: string;
filterByTraceID?: boolean;
filterBySpanID?: boolean;
}
export interface TraceToLogsData extends DataSourceJsonData {
@@ -112,6 +114,44 @@ export function TraceToLogsSettings({ options, onOptionsChange }: Props) {
/>
</InlineField>
</InlineFieldRow>
<InlineFieldRow>
<InlineField
label="Filter by Trace ID"
labelWidth={26}
grow
tooltip="Filters logs by Trace ID. Appends '|=<trace id>' to the query."
>
<InlineSwitch
value={options.jsonData.tracesToLogs?.filterByTraceID}
onChange={(event: React.SyntheticEvent<HTMLInputElement>) =>
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToLogs', {
...options.jsonData.tracesToLogs,
filterByTraceID: event.currentTarget.checked,
})
}
/>
</InlineField>
</InlineFieldRow>
<InlineFieldRow>
<InlineField
label="Filter by Span ID"
labelWidth={26}
grow
tooltip="Filters logs by Span ID. Appends '|=<span id>' to the query."
>
<InlineSwitch
value={options.jsonData.tracesToLogs?.filterBySpanID}
onChange={(event: React.SyntheticEvent<HTMLInputElement>) =>
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToLogs', {
...options.jsonData.tracesToLogs,
filterBySpanID: event.currentTarget.checked,
})
}
/>
</InlineField>
</InlineFieldRow>
</div>
);
}
@@ -174,5 +174,49 @@ describe('createSpanLinkFactory', () => {
)}`
);
});
it('filters by trace and span ID', () => {
const splitOpenFn = jest.fn();
const createLink = createSpanLinkFactory(splitOpenFn, {
datasourceUid: 'lokiUid',
filterBySpanID: true,
filterByTraceID: true,
});
expect(createLink).toBeDefined();
const linkDef = createLink!({
spanID: '6605c7b08e715d6c',
traceID: '7946b05c2e2e4e5a',
startTime: new Date('2020-10-14T01:00:00Z').valueOf() * 1000,
duration: 1000 * 1000,
tags: [
{
key: 'host',
value: 'host',
},
],
process: {
tags: [
{
key: 'cluster',
value: 'cluster1',
},
{
key: 'hostname',
value: 'hostname1',
},
{
key: 'label2',
value: 'val2',
},
],
} as any,
} as any);
expect(linkDef.href).toBe(
`/explore?left=${encodeURIComponent(
'{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"loki1","queries":[{"expr":"{cluster=\\"cluster1\\", hostname=\\"hostname1\\"} |=\\"7946b05c2e2e4e5a\\" |=\\"6605c7b08e715d6c\\"","refId":""}]}'
)}`
);
});
});
});
@@ -38,7 +38,7 @@ export function createSpanLinkFactory(splitOpenFn: SplitOpen, traceToLogsOptions
datasourceUid: dataSourceSettings.uid,
datasourceName: dataSourceSettings.name,
query: {
expr: getLokiQueryFromSpan(span, traceToLogsOptions.tags),
expr: getLokiQueryFromSpan(span, traceToLogsOptions),
refId: '',
},
},
@@ -67,7 +67,8 @@ export function createSpanLinkFactory(splitOpenFn: SplitOpen, traceToLogsOptions
*/
const defaultKeys = ['cluster', 'hostname', 'namespace', 'pod'];
function getLokiQueryFromSpan(span: TraceSpan, keys?: string[]): string {
function getLokiQueryFromSpan(span: TraceSpan, options: TraceToLogsOptions): string {
const { tags: keys, filterByTraceID, filterBySpanID } = options;
const keysToCheck = keys?.length ? keys : defaultKeys;
const tags = [...span.process.tags, ...span.tags].reduce((acc, tag) => {
if (keysToCheck.includes(tag.key)) {
@@ -75,7 +76,17 @@ function getLokiQueryFromSpan(span: TraceSpan, keys?: string[]): string {
}
return acc;
}, [] as string[]);
return `{${tags.join(', ')}}`;
let query = `{${tags.join(', ')}}`;
if (filterByTraceID && span.traceID) {
query += ` |="${span.traceID}"`;
}
if (filterBySpanID && span.spanID) {
query += ` |="${span.spanID}"`;
}
return query;
}
/**