Tracing: Add ability to write trace to metrics query (#48824)
* Tracing: Add ability to write trace to metrics query
This commit is contained in:
@@ -40,6 +40,15 @@ This is a configuration for the [trace to logs feature]({{< relref "../explore/t
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
### Trace to metrics
|
||||||
|
|
||||||
|
> **Note:** This feature is behind the `traceToMetrics` feature toggle.
|
||||||
|
|
||||||
|
To configure trace to metrics, select the target Prometheus data source and enter the desired query.
|
||||||
|
|
||||||
|
-- **Data source -** Target data source.
|
||||||
|
-- **Query -** Query that runs when navigating from a trace to the metrics data source.
|
||||||
|
|
||||||
### Node Graph
|
### Node Graph
|
||||||
|
|
||||||
This is a configuration for the beta Node Graph visualization. The Node Graph is shown after the trace view is loaded and is disabled by default.
|
This is a configuration for the beta Node Graph visualization. The Node Graph is shown after the trace view is loaded and is disabled by default.
|
||||||
|
|||||||
@@ -39,6 +39,15 @@ This is a configuration for the [trace to logs feature]({{< relref "../explore/t
|
|||||||
|
|
||||||
{{< figure src="/static/img/docs/explore/traces-to-logs-settings-8-2.png" class="docs-image--no-shadow" caption="Screenshot of the trace to logs settings" >}}
|
{{< figure src="/static/img/docs/explore/traces-to-logs-settings-8-2.png" class="docs-image--no-shadow" caption="Screenshot of the trace to logs settings" >}}
|
||||||
|
|
||||||
|
### Trace to metrics
|
||||||
|
|
||||||
|
> **Note:** This feature is behind the `traceToMetrics` feature toggle.
|
||||||
|
|
||||||
|
To configure trace to metrics, select the target Prometheus data source and enter the desired query.
|
||||||
|
|
||||||
|
-- **Data source -** Target data source.
|
||||||
|
-- **Query -** Query that runs when navigating from a trace to the metrics data source.
|
||||||
|
|
||||||
### Service Graph
|
### Service Graph
|
||||||
|
|
||||||
This is a configuration for the Service Graph feature.
|
This is a configuration for the Service Graph feature.
|
||||||
|
|||||||
@@ -40,6 +40,15 @@ This is a configuration for the [trace to logs feature]({{< relref "../explore/t
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
### Trace to metrics
|
||||||
|
|
||||||
|
> **Note:** This feature is behind the `traceToMetrics` feature toggle.
|
||||||
|
|
||||||
|
To configure trace to metrics, select the target Prometheus data source and enter the desired query.
|
||||||
|
|
||||||
|
-- **Data source -** Target data source.
|
||||||
|
-- **Query -** Query that runs when navigating from a trace to the metrics data source.
|
||||||
|
|
||||||
### Node Graph
|
### Node Graph
|
||||||
|
|
||||||
This is a configuration for the beta Node Graph visualization. The Node Graph is shown after the trace view is loaded and is disabled by default.
|
This is a configuration for the beta Node Graph visualization. The Node Graph is shown after the trace view is loaded and is disabled by default.
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ import {
|
|||||||
updateDatasourcePluginJsonDataOption,
|
updateDatasourcePluginJsonDataOption,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { DataSourcePicker } from '@grafana/runtime';
|
import { DataSourcePicker } from '@grafana/runtime';
|
||||||
import { Button, InlineField, InlineFieldRow, useStyles } from '@grafana/ui';
|
import { Button, InlineField, InlineFieldRow, Input, useStyles } from '@grafana/ui';
|
||||||
|
|
||||||
export interface TraceToMetricsOptions {
|
export interface TraceToMetricsOptions {
|
||||||
datasourceUid?: string;
|
datasourceUid?: string;
|
||||||
|
query: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TraceToMetricsData extends DataSourceJsonData {
|
export interface TraceToMetricsData extends DataSourceJsonData {
|
||||||
@@ -49,10 +50,10 @@ export function TraceToMetricsSettings({ options, onOptionsChange }: Props) {
|
|||||||
</InlineField>
|
</InlineField>
|
||||||
{options.jsonData.tracesToMetrics?.datasourceUid ? (
|
{options.jsonData.tracesToMetrics?.datasourceUid ? (
|
||||||
<Button
|
<Button
|
||||||
type={'button'}
|
type="button"
|
||||||
variant={'secondary'}
|
variant="secondary"
|
||||||
size={'sm'}
|
size="sm"
|
||||||
fill={'text'}
|
fill="text"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToMetrics', {
|
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToMetrics', {
|
||||||
...options.jsonData.tracesToMetrics,
|
...options.jsonData.tracesToMetrics,
|
||||||
@@ -64,6 +65,28 @@ export function TraceToMetricsSettings({ options, onOptionsChange }: Props) {
|
|||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
</InlineFieldRow>
|
</InlineFieldRow>
|
||||||
|
|
||||||
|
<InlineFieldRow>
|
||||||
|
<InlineField
|
||||||
|
label="Query"
|
||||||
|
labelWidth={26}
|
||||||
|
tooltip="The Prometheus query that will run when navigating from a trace to metrics"
|
||||||
|
grow
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
label="Query"
|
||||||
|
type="text"
|
||||||
|
allowFullScreen
|
||||||
|
value={options.jsonData.tracesToMetrics?.query}
|
||||||
|
onChange={(e) => {
|
||||||
|
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToMetrics', {
|
||||||
|
...options.jsonData.tracesToMetrics,
|
||||||
|
query: e.currentTarget.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</InlineField>
|
||||||
|
</InlineFieldRow>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { DataSourceInstanceSettings, MutableDataFrame } from '@grafana/data';
|
import { DataSourceInstanceSettings, MutableDataFrame } from '@grafana/data';
|
||||||
import { setDataSourceSrv, setTemplateSrv } from '@grafana/runtime';
|
import { setDataSourceSrv, setTemplateSrv } from '@grafana/runtime';
|
||||||
import { TraceSpan } from '@jaegertracing/jaeger-ui-components';
|
import { TraceSpan } from '@jaegertracing/jaeger-ui-components';
|
||||||
|
import { TraceToMetricsOptions } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
||||||
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||||
|
|
||||||
import { TraceToLogsOptions } from '../../../core/components/TraceToLogs/TraceToLogsSettings';
|
import { TraceToLogsOptions } from '../../../core/components/TraceToLogs/TraceToLogsSettings';
|
||||||
@@ -399,6 +400,7 @@ describe('createSpanLinkFactory', () => {
|
|||||||
splitOpenFn,
|
splitOpenFn,
|
||||||
traceToMetricsOptions: {
|
traceToMetricsOptions: {
|
||||||
datasourceUid: 'prom1',
|
datasourceUid: 'prom1',
|
||||||
|
query: 'customQuery',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(createLink).toBeDefined();
|
expect(createLink).toBeDefined();
|
||||||
@@ -406,6 +408,27 @@ describe('createSpanLinkFactory', () => {
|
|||||||
const links = createLink!(createTraceSpan());
|
const links = createLink!(createTraceSpan());
|
||||||
const linkDef = links?.metricLinks?.[0];
|
const linkDef = links?.metricLinks?.[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":"prom1","queries":[{"expr":"customQuery","refId":""}],"panelsState":{}}'
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses default query if no query specified', () => {
|
||||||
|
const splitOpenFn = jest.fn();
|
||||||
|
const createLink = createSpanLinkFactory({
|
||||||
|
splitOpenFn,
|
||||||
|
traceToMetricsOptions: {
|
||||||
|
datasourceUid: 'prom1',
|
||||||
|
} as TraceToMetricsOptions,
|
||||||
|
});
|
||||||
|
expect(createLink).toBeDefined();
|
||||||
|
|
||||||
|
const links = createLink!(createTraceSpan());
|
||||||
|
const linkDef = links?.metricLinks?.[0];
|
||||||
|
|
||||||
expect(linkDef).toBeDefined();
|
expect(linkDef).toBeDefined();
|
||||||
expect(linkDef!.href).toBe(
|
expect(linkDef!.href).toBe(
|
||||||
`/explore?left=${encodeURIComponent(
|
`/explore?left=${encodeURIComponent(
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ function legacyCreateSpanLinkFactory(
|
|||||||
|
|
||||||
// Get metrics links
|
// Get metrics links
|
||||||
if (metricsDataSourceSettings && traceToMetricsOptions) {
|
if (metricsDataSourceSettings && traceToMetricsOptions) {
|
||||||
|
const defaultQuery = `histogram_quantile(0.5, sum(rate(tempo_spanmetrics_latency_bucket{operation="${span.operationName}"}[5m])) by (le))`;
|
||||||
const dataLink: DataLink<PromQuery> = {
|
const dataLink: DataLink<PromQuery> = {
|
||||||
title: metricsDataSourceSettings.name,
|
title: metricsDataSourceSettings.name,
|
||||||
url: '',
|
url: '',
|
||||||
@@ -157,7 +158,7 @@ function legacyCreateSpanLinkFactory(
|
|||||||
datasourceUid: metricsDataSourceSettings.uid,
|
datasourceUid: metricsDataSourceSettings.uid,
|
||||||
datasourceName: metricsDataSourceSettings.name,
|
datasourceName: metricsDataSourceSettings.name,
|
||||||
query: {
|
query: {
|
||||||
expr: `histogram_quantile(0.5, sum(rate(tempo_spanmetrics_latency_bucket{operation="${span.operationName}"}[5m])) by (le))`,
|
expr: traceToMetricsOptions.query ?? defaultQuery,
|
||||||
refId: '',
|
refId: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user