diff --git a/docs/sources/datasources/jaeger.md b/docs/sources/datasources/jaeger.md
index 6b5c96e67b8..4139e33f219 100644
--- a/docs/sources/datasources/jaeger.md
+++ b/docs/sources/datasources/jaeger.md
@@ -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.
-
+
## Query traces
diff --git a/docs/sources/datasources/tempo.md b/docs/sources/datasources/tempo.md
index fcb3bb45729..62993fb6180 100644
--- a/docs/sources/datasources/tempo.md
+++ b/docs/sources/datasources/tempo.md
@@ -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.
-
+
## Query traces
diff --git a/docs/sources/datasources/zipkin.md b/docs/sources/datasources/zipkin.md
index 70e8578f849..85504e86eeb 100644
--- a/docs/sources/datasources/zipkin.md
+++ b/docs/sources/datasources/zipkin.md
@@ -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.
-
+
## Query traces
diff --git a/public/app/core/components/TraceToLogsSettings.tsx b/public/app/core/components/TraceToLogsSettings.tsx
index 742cd8e994f..64ab1668c17 100644
--- a/public/app/core/components/TraceToLogsSettings.tsx
+++ b/public/app/core/components/TraceToLogsSettings.tsx
@@ -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) {
/>
+
+
+
+ ) =>
+ updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToLogs', {
+ ...options.jsonData.tracesToLogs,
+ filterByTraceID: event.currentTarget.checked,
+ })
+ }
+ />
+
+
+
+
+
+ ) =>
+ updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToLogs', {
+ ...options.jsonData.tracesToLogs,
+ filterBySpanID: event.currentTarget.checked,
+ })
+ }
+ />
+
+
);
}
diff --git a/public/app/features/explore/TraceView/createSpanLink.test.ts b/public/app/features/explore/TraceView/createSpanLink.test.ts
index 912bb342d0e..715d8e615d6 100644
--- a/public/app/features/explore/TraceView/createSpanLink.test.ts
+++ b/public/app/features/explore/TraceView/createSpanLink.test.ts
@@ -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":""}]}'
+ )}`
+ );
+ });
});
});
diff --git a/public/app/features/explore/TraceView/createSpanLink.tsx b/public/app/features/explore/TraceView/createSpanLink.tsx
index 185a263d3d3..c2a5b7ee639 100644
--- a/public/app/features/explore/TraceView/createSpanLink.tsx
+++ b/public/app/features/explore/TraceView/createSpanLink.tsx
@@ -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;
}
/**