mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tempo: Display start time in search results as relative time (#44568)
* Explore: modify tempo trace start time to human readable format in table output Signed-off-by: tharun <rajendrantharun@live.com> * add unit tests Signed-off-by: tharun <rajendrantharun@live.com>
This commit is contained in:
parent
76603b93d6
commit
de1661e877
@ -1,6 +1,12 @@
|
||||
import { FieldType, MutableDataFrame } from '@grafana/data';
|
||||
import { createTableFrame, transformToOTLP, transformFromOTLP } from './resultTransformer';
|
||||
import { otlpDataFrameToResponse, otlpDataFrameFromResponse, otlpResponse } from './testResponse';
|
||||
import { FieldType, MutableDataFrame, PluginType, DataSourceInstanceSettings, dateTime } from '@grafana/data';
|
||||
import {
|
||||
SearchResponse,
|
||||
createTableFrame,
|
||||
transformToOTLP,
|
||||
transformFromOTLP,
|
||||
createTableFrameFromSearch,
|
||||
} from './resultTransformer';
|
||||
import { otlpDataFrameToResponse, otlpDataFrameFromResponse, otlpResponse, tempoSearchResponse } from './testResponse';
|
||||
import { collectorTypes } from '@opentelemetry/exporter-collector';
|
||||
|
||||
describe('transformTraceList()', () => {
|
||||
@ -54,3 +60,43 @@ describe('transformFromOTLP()', () => {
|
||||
expect(res.data[0]).toMatchObject(otlpDataFrameFromResponse);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createTableFrameFromSearch()', () => {
|
||||
const mockTimeUnix = dateTime(1643357709095).valueOf();
|
||||
global.Date.now = jest.fn(() => mockTimeUnix);
|
||||
test('transforms search response to dataFrame', () => {
|
||||
const frame = createTableFrameFromSearch(tempoSearchResponse.traces as SearchResponse[], defaultSettings);
|
||||
expect(frame.fields[0].name).toBe('traceID');
|
||||
expect(frame.fields[0].values.get(0)).toBe('e641dcac1c3a0565');
|
||||
|
||||
expect(frame.fields[1].name).toBe('traceName');
|
||||
expect(frame.fields[1].values.get(0)).toBe('c10d7ca4e3a00354 ');
|
||||
|
||||
// expect time in ago format if startTime less than 1 hour
|
||||
expect(frame.fields[2].name).toBe('startTime');
|
||||
expect(frame.fields[2].values.get(0)).toBe('15 minutes ago');
|
||||
|
||||
// expect time in format if startTime greater than 1 hour
|
||||
expect(frame.fields[2].values.get(1)).toBe('2022-01-27 22:56:06');
|
||||
|
||||
expect(frame.fields[3].name).toBe('duration');
|
||||
expect(frame.fields[3].values.get(0)).toBe(65);
|
||||
});
|
||||
});
|
||||
|
||||
const defaultSettings: DataSourceInstanceSettings = {
|
||||
id: 0,
|
||||
uid: '0',
|
||||
type: 'tracing',
|
||||
name: 'tempo',
|
||||
access: 'proxy',
|
||||
meta: {
|
||||
id: 'tempo',
|
||||
name: 'tempo',
|
||||
type: PluginType.datasource,
|
||||
info: {} as any,
|
||||
module: '',
|
||||
baseUrl: '',
|
||||
},
|
||||
jsonData: {},
|
||||
};
|
||||
|
@ -9,9 +9,12 @@ import {
|
||||
TraceKeyValuePair,
|
||||
TraceLog,
|
||||
TraceSpanRow,
|
||||
dateTimeFormat,
|
||||
} from '@grafana/data';
|
||||
import { SpanStatus, SpanStatusCode } from '@opentelemetry/api';
|
||||
import { collectorTypes } from '@opentelemetry/exporter-collector';
|
||||
import formatDistance from 'date-fns/formatDistance';
|
||||
import differenceInHours from 'date-fns/differenceInHours';
|
||||
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
|
||||
import { createGraphFrames } from './graphTransform';
|
||||
|
||||
@ -525,7 +528,7 @@ function parseJsonFields(frame: DataFrame) {
|
||||
}
|
||||
}
|
||||
|
||||
type SearchResponse = {
|
||||
export type SearchResponse = {
|
||||
traceID: string;
|
||||
rootServiceName: string;
|
||||
rootTraceName: string;
|
||||
@ -558,7 +561,7 @@ export function createTableFrameFromSearch(data: SearchResponse[], instanceSetti
|
||||
},
|
||||
},
|
||||
{ name: 'traceName', type: FieldType.string, config: { displayNameFromDS: 'Trace name' } },
|
||||
{ name: 'startTime', type: FieldType.time, config: { displayNameFromDS: 'Start time' } },
|
||||
{ name: 'startTime', type: FieldType.string, config: { displayNameFromDS: 'Start time' } },
|
||||
{ name: 'duration', type: FieldType.number, config: { displayNameFromDS: 'Duration', unit: 'ms' } },
|
||||
],
|
||||
meta: {
|
||||
@ -569,7 +572,9 @@ export function createTableFrameFromSearch(data: SearchResponse[], instanceSetti
|
||||
return frame;
|
||||
}
|
||||
// Show the most recent traces
|
||||
const traceData = data.map(transformToTraceData).sort((a, b) => b?.startTime! - a?.startTime!);
|
||||
const traceData = data
|
||||
.sort((a, b) => parseInt(b?.startTimeUnixNano!, 10) / 1000000 - parseInt(a?.startTimeUnixNano!, 10) / 1000000)
|
||||
.map(transformToTraceData);
|
||||
|
||||
for (const trace of traceData) {
|
||||
frame.add(trace);
|
||||
@ -586,9 +591,21 @@ function transformToTraceData(data: SearchResponse) {
|
||||
if (data.rootTraceName) {
|
||||
traceName += data.rootTraceName;
|
||||
}
|
||||
|
||||
const traceStartTime = parseInt(data.startTimeUnixNano!, 10) / 1000000;
|
||||
|
||||
let startTime = dateTimeFormat(traceStartTime);
|
||||
|
||||
if (Math.abs(differenceInHours(new Date(traceStartTime), Date.now())) <= 1) {
|
||||
startTime = formatDistance(new Date(traceStartTime), Date.now(), {
|
||||
addSuffix: true,
|
||||
includeSeconds: true,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
traceID: data.traceID,
|
||||
startTime: parseInt(data.startTimeUnixNano, 10) / 1000 / 1000,
|
||||
startTime: startTime,
|
||||
duration: data.durationMs,
|
||||
traceName,
|
||||
};
|
||||
|
@ -2202,3 +2202,24 @@ export const otlpResponse = {
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const tempoSearchResponse = {
|
||||
traces: [
|
||||
{
|
||||
traceID: 'e641dcac1c3a0565',
|
||||
rootServiceName: 'c10d7ca4e3a00354',
|
||||
startTimeUnixNano: '1643356828724000000',
|
||||
durationMs: 65,
|
||||
},
|
||||
{
|
||||
traceID: 'c2983496a2b12544',
|
||||
rootServiceName: '<root span not yet received>',
|
||||
startTimeUnixNano: '1643342166678000000',
|
||||
durationMs: 93,
|
||||
},
|
||||
],
|
||||
metrics: {
|
||||
inspectedTraces: 2,
|
||||
inspectedBytes: '83720',
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user