Trace View: Use data links post processor for legacy data links (#111304)

This commit is contained in:
Piotr Jamróz 2025-09-29 17:00:07 +02:00 committed by GitHub
parent 382c414869
commit 410df3d065
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 26 deletions

View File

@ -15,6 +15,7 @@ import {
SplitOpen,
TimeRange,
TraceSearchProps,
useDataLinksContext,
} from '@grafana/data';
import { Trans, t } from '@grafana/i18n';
import { getTraceToLogsOptions, TraceToMetricsData, TraceToProfilesData } from '@grafana/o11y-ds-frontend';
@ -142,6 +143,8 @@ export function TraceView(props: Props) {
const traceToProfilesOptions = traceToProfilesData?.tracesToProfiles;
const spanBarOptions: SpanBarOptionsData | undefined = instanceSettings?.jsonData;
const dataLinksContext = useDataLinksContext();
const createSpanLink = useMemo(
() =>
createSpanLinkFromProps ??
@ -153,6 +156,7 @@ export function TraceView(props: Props) {
dataFrame: props.dataFrames[0],
createFocusSpanLink,
trace: traceProp,
dataLinkPostProcessor: dataLinksContext?.dataLinkPostProcessor,
}),
[
props.splitOpenFn,
@ -163,6 +167,7 @@ export function TraceView(props: Props) {
createFocusSpanLink,
traceProp,
createSpanLinkFromProps,
dataLinksContext?.dataLinkPostProcessor,
]
);
const timeZone = useSelector((state) => getTimeZone(state.user));

View File

@ -1,10 +1,12 @@
import { useMemo } from 'react';
import { DataFrame, SplitOpen, TimeRange } from '@grafana/data';
import { DataFrame, DataLinksContext, SplitOpen, TimeRange } from '@grafana/data';
import { t } from '@grafana/i18n';
import { PanelChrome } from '@grafana/ui';
import { StoreState, useSelector } from 'app/types/store';
import { useExploreDataLinkPostProcessor } from '../hooks/useExploreDataLinkPostProcessor';
import { TraceView } from './TraceView';
import { transformDataFrames } from './utils/transform';
@ -25,21 +27,25 @@ export function TraceViewContainer(props: Props) {
(state: StoreState) => state.explore.panes[props.exploreId]?.datasourceInstance ?? undefined
);
const dataLinkPostProcessor = useExploreDataLinkPostProcessor(splitOpenFn, timeRange);
if (!traceProp) {
return null;
}
return (
<PanelChrome padding="none" title={t('explore.trace-view-container.title-trace', 'Trace')}>
<TraceView
exploreId={exploreId}
dataFrames={dataFrames}
splitOpenFn={splitOpenFn}
scrollElement={scrollElement}
traceProp={traceProp}
datasource={datasource}
timeRange={timeRange}
/>
<DataLinksContext.Provider value={{ dataLinkPostProcessor }}>
<TraceView
exploreId={exploreId}
dataFrames={dataFrames}
splitOpenFn={splitOpenFn}
scrollElement={scrollElement}
traceProp={traceProp}
datasource={datasource}
timeRange={timeRange}
/>
</DataLinksContext.Provider>
</PanelChrome>
);
}

View File

@ -196,6 +196,7 @@ const createLinkModel = (
className,
type,
linkModel: {
...link.linkModel,
...link,
title: title,
target: '_blank',

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import { Field, LinkTarget } from '@grafana/data';
import { Field, LinkModel, LinkTarget } from '@grafana/data';
import { TraceSpan } from './trace';
@ -22,6 +22,7 @@ export type SpanLinkDef = {
field: Field;
type: SpanLinkType;
target?: LinkTarget;
linkModel?: LinkModel;
};
export type SpanLinkFunc = (span: TraceSpan) => SpanLinkDef[] | undefined;

View File

@ -1,6 +1,7 @@
import {
DataFrame,
DataLink,
DataLinkPostProcessor,
DataSourceInstanceSettings,
DataSourceJsonData,
dateTime,
@ -44,6 +45,7 @@ export function createSpanLinkFactory({
dataFrame,
createFocusSpanLink,
trace,
dataLinkPostProcessor,
}: {
splitOpenFn: SplitOpen;
traceToLogsOptions?: TraceToLogsOptionsV2;
@ -52,6 +54,7 @@ export function createSpanLinkFactory({
dataFrame?: DataFrame;
createFocusSpanLink?: (traceId: string, spanId: string) => LinkModel<Field>;
trace: Trace;
dataLinkPostProcessor?: DataLinkPostProcessor;
}): SpanLinkFunc | undefined {
if (!dataFrame) {
return undefined;
@ -67,7 +70,9 @@ export function createSpanLinkFactory({
traceToLogsOptions,
traceToMetricsOptions,
createFocusSpanLink,
scopedVars
scopedVars,
dataFrame,
dataLinkPostProcessor
);
return function SpanLink(span: TraceSpan): SpanLinkDef[] | undefined {
@ -147,7 +152,9 @@ function legacyCreateSpanLinkFactory(
traceToLogsOptions?: TraceToLogsOptionsV2,
traceToMetricsOptions?: TraceToMetricsOptions,
createFocusSpanLink?: (traceId: string, spanId: string) => LinkModel<Field>,
scopedVars?: ScopedVars
scopedVars?: ScopedVars,
dataFrame?: DataFrame,
dataLinkPostProcessor?: DataLinkPostProcessor
) {
let logsDataSourceSettings: DataSourceInstanceSettings<DataSourceJsonData> | undefined;
if (traceToLogsOptions?.datasourceUid) {
@ -215,6 +222,18 @@ function legacyCreateSpanLinkFactory(
datasourceUid: logsDataSourceSettings.uid,
datasourceName: logsDataSourceSettings.name,
query,
range: getTimeRangeFromSpan(
span,
{
startMs: traceToLogsOptions.spanStartTimeShift
? rangeUtil.intervalToMs(traceToLogsOptions.spanStartTimeShift)
: 0,
endMs: traceToLogsOptions.spanEndTimeShift
? rangeUtil.intervalToMs(traceToLogsOptions.spanEndTimeShift)
: 0,
},
isSplunkDS
),
},
};
@ -229,29 +248,32 @@ function legacyCreateSpanLinkFactory(
// Check if all variables are defined and don't show if they aren't. This is usually handled by the
// getQueryFor* functions but this is for case of custom query supplied by the user.
if (getVariableUsageInfo(dataLink.internal!.query, scopedVars).allVariablesDefined) {
const link = mapInternalLinkToExplore({
let link = mapInternalLinkToExplore({
link: dataLink,
internalLink: dataLink.internal!,
scopedVars: scopedVars,
range: getTimeRangeFromSpan(
span,
{
startMs: traceToLogsOptions.spanStartTimeShift
? rangeUtil.intervalToMs(traceToLogsOptions.spanStartTimeShift)
: 0,
endMs: traceToLogsOptions.spanEndTimeShift
? rangeUtil.intervalToMs(traceToLogsOptions.spanEndTimeShift)
: 0,
},
isSplunkDS
),
range: dataLink.internal!.range,
field: {} as Field,
onClickFn: splitOpenFn,
replaceVariables: getTemplateSrv().replace.bind(getTemplateSrv()),
});
link =
(dataFrame &&
dataLinkPostProcessor?.({
frame: dataFrame,
field: field,
dataLinkScopedVars: scopedVars,
replaceVariables: getTemplateSrv().replace.bind(getTemplateSrv()),
config: {},
link: dataLink,
linkModel: link,
})) ||
link;
links.push({
href: link.href,
linkModel: link,
title: t('explore.legacy-create-span-link-factory.title.related-logs', 'Related logs'),
onClick: link.onClick,
content: (
@ -351,6 +373,7 @@ function legacyCreateSpanLinkFactory(
links!.push({
href: link.href,
linkModel: link,
title,
content: <Icon name="link" title={title} />,
onClick: link.onClick,