Explore: Download traces as JSON in Explore Inspector (#38614)

* Transform dataframe to jaeger format

* Transform dataframe to Zipkin format

* Add endpoint type and shared to Zipkin

* Transform dataframe to OTLP format

* Add data tab tests and note in inspector docs

* Remove comments and logs

* Resolve typescript strict errors

* Update docs/sources/explore/explore-inspector.md

Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>

* Update docs

* Improve OTLP conversion to include service info and additional tags

Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>
This commit is contained in:
Connor Lindsey
2021-09-08 07:04:27 -06:00
committed by GitHub
parent 3bb2ee9de6
commit 6a39ac7407
16 changed files with 702 additions and 11 deletions

View File

@@ -1,6 +1,13 @@
import { DataFrame, DataSourceInstanceSettings, FieldType, MutableDataFrame, TraceSpanRow } from '@grafana/data';
import {
DataFrame,
DataSourceInstanceSettings,
FieldType,
MutableDataFrame,
TraceLog,
TraceSpanRow,
} from '@grafana/data';
import { transformTraceData } from '@jaegertracing/jaeger-ui-components';
import { Span, TraceProcess, TraceResponse } from './types';
import { JaegerResponse, Span, TraceProcess, TraceResponse } from './types';
export function createTraceFrame(data: TraceResponse): DataFrame {
const spans = data.spans.map((s) => toSpanRow(s, data.processes));
@@ -22,6 +29,9 @@ export function createTraceFrame(data: TraceResponse): DataFrame {
],
meta: {
preferredVisualisationType: 'trace',
custom: {
traceFormat: 'jaeger',
},
},
});
@@ -107,3 +117,62 @@ function transformToTraceData(data: TraceResponse) {
traceName: traceData.traceName,
};
}
export function transformToJaeger(data: MutableDataFrame): JaegerResponse {
let traceResponse: TraceResponse = {
traceID: '',
spans: [],
processes: {},
warnings: null,
};
let processes: string[] = [];
for (let i = 0; i < data.length; i++) {
const span = data.get(i);
// Set traceID
if (!traceResponse.traceID) {
traceResponse.traceID = span.traceID;
}
// Create process if doesn't exist
if (!processes.find((p) => p === span.serviceName)) {
processes.push(span.serviceName);
traceResponse.processes[`p${processes.length}`] = {
serviceName: span.serviceName,
tags: span.serviceTags,
};
}
// Create span
traceResponse.spans.push({
traceID: span.traceID,
spanID: span.spanID,
duration: span.duration * 1000,
references: span.parentSpanID
? [
{
refType: 'CHILD_OF',
spanID: span.parentSpanID,
traceID: span.traceID,
},
]
: [],
flags: 0,
logs: span.logs.map((l: TraceLog) => ({
...l,
timestamp: l.timestamp * 1000,
})),
operationName: span.operationName,
processID:
Object.keys(traceResponse.processes).find(
(key) => traceResponse.processes[key].serviceName === span.serviceName
) || '',
startTime: span.startTime * 1000,
tags: span.tags,
warnings: span.warnings ? span.warnings : null,
});
}
return { data: [traceResponse], total: 0, limit: 0, offset: 0, errors: null };
}