2025-09-14 20:18:49 +04:30
|
|
|
import { ENTITY_VERSION_V5 } from 'constants/app';
|
|
|
|
|
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
|
|
|
|
|
import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
|
|
|
|
|
import { uniqBy } from 'lodash-es';
|
2025-09-14 17:41:20 +04:30
|
|
|
|
2025-09-14 20:18:49 +04:30
|
|
|
import { HierarchicalSpanData, ServiceEntrySpan, SpanDataRow } from './types';
|
2025-09-14 17:41:20 +04:30
|
|
|
|
|
|
|
|
export function transformEntrySpansToHierarchy(
|
2025-09-14 20:18:49 +04:30
|
|
|
entrySpans?: SpanDataRow[],
|
2025-09-14 17:41:20 +04:30
|
|
|
): HierarchicalSpanData {
|
|
|
|
|
let totalTraceTime = 0;
|
|
|
|
|
|
2025-09-14 20:18:49 +04:30
|
|
|
if (!entrySpans) {
|
|
|
|
|
return { entrySpans: [], totalTraceTime: 0 };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const uniqueEntrySpans = uniqBy(entrySpans, 'data.span_id');
|
|
|
|
|
|
2025-09-14 17:41:20 +04:30
|
|
|
// Calculate total trace time from all entry spans
|
2025-09-14 20:18:49 +04:30
|
|
|
uniqueEntrySpans.forEach((span) => {
|
2025-09-14 17:41:20 +04:30
|
|
|
totalTraceTime += span.data.duration_nano;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Transform entry spans to ServiceEntrySpan structure
|
2025-09-14 20:18:49 +04:30
|
|
|
const entrySpansList: ServiceEntrySpan[] = uniqueEntrySpans.map((span) => ({
|
2025-09-14 17:41:20 +04:30
|
|
|
spanData: span,
|
|
|
|
|
serviceName: span.data['service.name'],
|
|
|
|
|
isExpanded: false,
|
|
|
|
|
serviceSpans: undefined,
|
|
|
|
|
isLoadingServiceSpans: false,
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
entrySpans: entrySpansList,
|
|
|
|
|
totalTraceTime,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-14 20:18:49 +04:30
|
|
|
export async function fetchServiceSpans(
|
2025-09-14 17:41:20 +04:30
|
|
|
traceId: string,
|
|
|
|
|
serviceName: string,
|
|
|
|
|
): Promise<SpanDataRow[]> {
|
2025-09-14 20:18:49 +04:30
|
|
|
// Use the same payload structure as in SpanList component but with service-specific filter
|
|
|
|
|
const payload = initialQueriesMap.traces;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await GetMetricQueryRange(
|
|
|
|
|
{
|
|
|
|
|
graphType: PANEL_TYPES.LIST,
|
|
|
|
|
selectedTime: 'GLOBAL_TIME',
|
|
|
|
|
query: {
|
|
|
|
|
...payload,
|
|
|
|
|
builder: {
|
|
|
|
|
...payload.builder,
|
|
|
|
|
queryData: [
|
|
|
|
|
{
|
|
|
|
|
...payload.builder.queryData[0],
|
|
|
|
|
...{
|
|
|
|
|
name: 'A',
|
|
|
|
|
signal: 'traces',
|
|
|
|
|
stepInterval: null,
|
|
|
|
|
disabled: false,
|
|
|
|
|
filter: {
|
|
|
|
|
expression: `trace_id = '${traceId}' and service.name = '${serviceName}'`,
|
|
|
|
|
},
|
|
|
|
|
limit: 10,
|
|
|
|
|
offset: 0,
|
|
|
|
|
order: [
|
|
|
|
|
{
|
|
|
|
|
key: {
|
|
|
|
|
name: 'timestamp',
|
|
|
|
|
},
|
|
|
|
|
direction: 'desc',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
having: {
|
|
|
|
|
expression: '',
|
|
|
|
|
},
|
|
|
|
|
selectFields: [
|
|
|
|
|
{
|
|
|
|
|
name: 'service.name',
|
|
|
|
|
fieldDataType: 'string',
|
|
|
|
|
signal: 'traces',
|
|
|
|
|
fieldContext: 'resource',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'name',
|
|
|
|
|
fieldDataType: 'string',
|
|
|
|
|
signal: 'traces',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'duration_nano',
|
|
|
|
|
fieldDataType: '',
|
|
|
|
|
signal: 'traces',
|
|
|
|
|
fieldContext: 'span',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'http_method',
|
|
|
|
|
fieldDataType: '',
|
|
|
|
|
signal: 'traces',
|
|
|
|
|
fieldContext: 'span',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'response_status_code',
|
|
|
|
|
fieldDataType: '',
|
|
|
|
|
signal: 'traces',
|
|
|
|
|
fieldContext: 'span',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
2025-09-14 17:41:20 +04:30
|
|
|
},
|
|
|
|
|
},
|
2025-09-14 20:18:49 +04:30
|
|
|
},
|
|
|
|
|
ENTITY_VERSION_V5,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Extract spans from the API response using the same path as SpanList component
|
|
|
|
|
const spans =
|
|
|
|
|
response?.payload?.data?.newResult?.data?.result?.[0]?.list || [];
|
|
|
|
|
|
|
|
|
|
// Transform the API response to SpanDataRow format if needed
|
|
|
|
|
// The API should return the correct format for traces, but we'll handle any potential transformation
|
|
|
|
|
return (spans as unknown) as SpanDataRow[];
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to fetch service spans:', error);
|
|
|
|
|
return [];
|
|
|
|
|
}
|
2025-09-14 17:41:20 +04:30
|
|
|
}
|