diff --git a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/SpanFlameGraph.tsx b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/SpanFlameGraph.tsx index dbe28555c26..7f91ea24592 100644 --- a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/SpanFlameGraph.tsx +++ b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/SpanFlameGraph.tsx @@ -13,7 +13,7 @@ import { TimeZone, } from '@grafana/data'; import { FlameGraph } from '@grafana/flamegraph'; -import { config } from '@grafana/runtime'; +import { config, getTemplateSrv } from '@grafana/runtime'; import { useStyles2 } from '@grafana/ui'; import { TraceToProfilesOptions } from 'app/core/components/TraceToProfiles/TraceToProfilesSettings'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; @@ -21,7 +21,14 @@ import { PyroscopeQueryType } from 'app/plugins/datasource/grafana-pyroscope-dat import { PyroscopeDataSource } from 'app/plugins/datasource/grafana-pyroscope-datasource/datasource'; import { Query } from 'app/plugins/datasource/grafana-pyroscope-datasource/types'; -import { defaultProfilingKeys, getFormattedTags, pyroscopeProfileIdTagKey } from '../../../createSpanLink'; +import { + defaultProfilingKeys, + getFormattedTags, + pyroscopeProfileIdTagKey, + scopedVarsFromSpan, + scopedVarsFromTags, + scopedVarsFromTrace, +} from '../../../createSpanLink'; import { TraceSpan } from '../../types/trace'; import { TraceFlameGraphs } from '.'; @@ -33,10 +40,21 @@ export type SpanFlameGraphProps = { traceFlameGraphs: TraceFlameGraphs; setTraceFlameGraphs: (flameGraphs: TraceFlameGraphs) => void; setRedrawListView: (redraw: {}) => void; + traceDuration: number; + traceName: string; }; export default function SpanFlameGraph(props: SpanFlameGraphProps) { - const { span, traceToProfilesOptions, timeZone, traceFlameGraphs, setTraceFlameGraphs, setRedrawListView } = props; + const { + span, + traceToProfilesOptions, + timeZone, + traceFlameGraphs, + setTraceFlameGraphs, + setRedrawListView, + traceDuration, + traceName, + } = props; const [sizeRef, { height: containerHeight }] = useMeasure(); const styles = useStyles2(getStyles); @@ -80,7 +98,12 @@ export default function SpanFlameGraph(props: SpanFlameGraphProps) { ) => { let labelSelector = '{}'; if (traceToProfilesOptions.customQuery && traceToProfilesOptions.query) { - labelSelector = traceToProfilesOptions.query; + const scopedVars = { + ...scopedVarsFromTrace(traceDuration, traceName, span.traceID), + ...scopedVarsFromSpan(span), + ...scopedVarsFromTags(span, traceToProfilesOptions), + }; + labelSelector = getTemplateSrv().replace(traceToProfilesOptions.query, scopedVars); } else { const tags = traceToProfilesOptions.tags && traceToProfilesOptions.tags.length > 0 @@ -119,7 +142,7 @@ export default function SpanFlameGraph(props: SpanFlameGraphProps) { setTraceFlameGraphs({ ...traceFlameGraphs, [profileTagValue]: flameGraph }); } }, - [getTimeRangeForProfile, profileTagValue, setTraceFlameGraphs, timeZone, traceFlameGraphs] + [getTimeRangeForProfile, profileTagValue, setTraceFlameGraphs, timeZone, traceDuration, traceFlameGraphs, traceName] ); useEffect(() => { diff --git a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/index.tsx b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/index.tsx index 31b984d632f..d2a95c71221 100644 --- a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/index.tsx +++ b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/index.tsx @@ -125,6 +125,8 @@ export type SpanDetailProps = { timeZone: TimeZone; tagsToggle: (spanID: string) => void; traceStartTime: number; + traceDuration: number; + traceName: string; warningsToggle: (spanID: string) => void; stackTracesToggle: (spanID: string) => void; referenceItemToggle: (spanID: string, reference: TraceSpanReference) => void; @@ -148,6 +150,8 @@ export default function SpanDetail(props: SpanDetailProps) { span, tagsToggle, traceStartTime, + traceDuration, + traceName, warningsToggle, stackTracesToggle, referencesToggle, @@ -402,6 +406,8 @@ export default function SpanDetail(props: SpanDetailProps) { setTraceFlameGraphs={setTraceFlameGraphs} traceToProfilesOptions={traceToProfilesOptions} setRedrawListView={setRedrawListView} + traceDuration={traceDuration} + traceName={traceName} /> )} diff --git a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetailRow.tsx b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetailRow.tsx index 676d10c5aa8..ac687cf875e 100644 --- a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetailRow.tsx +++ b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetailRow.tsx @@ -90,6 +90,8 @@ export type SpanDetailRowProps = { timeZone: TimeZone; tagsToggle: (spanID: string) => void; traceStartTime: number; + traceDuration: number; + traceName: string; hoverIndentGuideIds: Set; addHoverIndentGuideId: (spanID: string) => void; removeHoverIndentGuideId: (spanID: string) => void; @@ -131,6 +133,8 @@ export class UnthemedSpanDetailRow extends React.PureComponent Boolean(f.config.links?.length)); const createSpanLinks = legacyCreateSpanLinkFactory( @@ -596,14 +596,14 @@ function buildMetricsQuery( * Variables from trace that can be used in the query * @param trace */ -function scopedVarsFromTrace(trace: Trace): ScopedVars { +export function scopedVarsFromTrace(duration: number, name: string, traceId: string): ScopedVars { return { __trace: { text: 'Trace', value: { - duration: trace.duration, - name: trace.traceName, - traceId: trace.traceID, + duration, + name, + traceId, }, }, }; @@ -613,7 +613,7 @@ function scopedVarsFromTrace(trace: Trace): ScopedVars { * Variables from span that can be used in the query * @param span */ -function scopedVarsFromSpan(span: TraceSpan): ScopedVars { +export function scopedVarsFromSpan(span: TraceSpan): ScopedVars { const tags: ScopedVars = {}; // We put all these tags together similar way we do for the __tags variable. This means there can be some overriding @@ -643,7 +643,10 @@ function scopedVarsFromSpan(span: TraceSpan): ScopedVars { * Variables from tags that can be used in the query * @param span */ -function scopedVarsFromTags(span: TraceSpan, traceToProfilesOptions: TraceToProfilesOptions | undefined): ScopedVars { +export function scopedVarsFromTags( + span: TraceSpan, + traceToProfilesOptions: TraceToProfilesOptions | undefined +): ScopedVars { let tags: ScopedVars = {}; if (traceToProfilesOptions) {