mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tempo: Support standard span convention (#88268)
This commit is contained in:
parent
e28a34f126
commit
e7f05f4ff2
@ -0,0 +1,80 @@
|
|||||||
|
import { TraceSpan } from '../types';
|
||||||
|
|
||||||
|
import { findHeaderTags } from './trace-viewer';
|
||||||
|
|
||||||
|
describe('findHeaderTags()', () => {
|
||||||
|
it('return empty object when no spans are provided', () => {
|
||||||
|
const spans: TraceSpan[] = [];
|
||||||
|
expect(findHeaderTags(spans)).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('return header tags when spans follow the OTEL semantic convention', () => {
|
||||||
|
const spans: TraceSpan[] = [
|
||||||
|
// @ts-ignore
|
||||||
|
{
|
||||||
|
tags: [
|
||||||
|
{ key: 'http.request.method', value: 'GET' },
|
||||||
|
{ key: 'http.response.status_code', value: '200' },
|
||||||
|
{ key: 'http.route', value: '/api/users' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
expect(findHeaderTags(spans)).toEqual({
|
||||||
|
method: [{ key: 'http.request.method', value: 'GET' }],
|
||||||
|
status: [{ key: 'http.response.status_code', value: '200' }],
|
||||||
|
url: [{ key: 'http.route', value: '/api/users' }],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('return header tags when spans follow the alternative convention', () => {
|
||||||
|
const spans: TraceSpan[] = [
|
||||||
|
// @ts-ignore
|
||||||
|
{
|
||||||
|
tags: [
|
||||||
|
{ key: 'http.method', value: 'GET' },
|
||||||
|
{ key: 'http.status_code', value: '200' },
|
||||||
|
{ key: 'http.path', value: '/api/users' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// @ts-ignore
|
||||||
|
{
|
||||||
|
tags: [
|
||||||
|
{ key: 'http.method', value: 'POST' },
|
||||||
|
{ key: 'http.status_code', value: '404' },
|
||||||
|
{ key: 'http.path', value: '/api/posts' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
expect(findHeaderTags(spans)).toEqual({
|
||||||
|
method: [{ key: 'http.method', value: 'GET' }],
|
||||||
|
status: [{ key: 'http.status_code', value: '200' }],
|
||||||
|
url: [{ key: 'http.path', value: '/api/users' }],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('return header tags, prioritizing the spans that follow the OTEL semantinc convention', () => {
|
||||||
|
const spans: TraceSpan[] = [
|
||||||
|
// @ts-ignore
|
||||||
|
{
|
||||||
|
tags: [
|
||||||
|
{ key: 'http.method', value: 'GET' },
|
||||||
|
{ key: 'http.status', value: '200' },
|
||||||
|
{ key: 'http.path', value: '/api/users' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// @ts-ignore
|
||||||
|
{
|
||||||
|
tags: [
|
||||||
|
{ key: 'http.request.method', value: 'POST' },
|
||||||
|
{ key: 'http.response.status_code', value: '404' },
|
||||||
|
{ key: 'http.route', value: '/api/users' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
expect(findHeaderTags(spans)).toEqual({
|
||||||
|
method: [{ key: 'http.request.method', value: 'POST' }],
|
||||||
|
status: [{ key: 'http.response.status_code', value: '404' }],
|
||||||
|
url: [{ key: 'http.route', value: '/api/users' }],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -56,7 +56,34 @@ export const getTraceName = memoize(_getTraceNameImpl, (spans: TraceSpan[]) => {
|
|||||||
return spans[0].traceID;
|
return spans[0].traceID;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Find header tags according to either old standard (e..g, `http.method`) or the
|
||||||
|
// standard OTEL semantic convention, as per https://opentelemetry.io/docs/specs/semconv/http/http-spans
|
||||||
|
// (e.g., `http.request.method`). Spans following the OTEL semantic convention are prioritized.
|
||||||
|
//
|
||||||
|
// Note that we are ignoring these cases:
|
||||||
|
// - conventions are mixed, e.g., a span with method in `http.method` but status code in `http.response.status_code`
|
||||||
|
// - tags are not in the same span, e.g., method in spans[0] but status in spans[1]
|
||||||
export function findHeaderTags(spans: TraceSpan[]) {
|
export function findHeaderTags(spans: TraceSpan[]) {
|
||||||
|
// OTEL semantic convention
|
||||||
|
for (let i = 0; i < spans.length; i++) {
|
||||||
|
const method = spans[i].tags.filter((tag) => {
|
||||||
|
return tag.key === 'http.request.method';
|
||||||
|
});
|
||||||
|
|
||||||
|
const status = spans[i].tags.filter((tag) => {
|
||||||
|
return tag.key === 'http.response.status_code';
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = spans[i].tags.filter((tag) => {
|
||||||
|
return tag.key === 'http.route';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (method.length > 0 || status.length > 0 || url.length > 0) {
|
||||||
|
return { method, status, url };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-standard convention
|
||||||
for (let i = 0; i < spans.length; i++) {
|
for (let i = 0; i < spans.length; i++) {
|
||||||
const method = spans[i].tags.filter((tag) => {
|
const method = spans[i].tags.filter((tag) => {
|
||||||
return tag.key === 'http.method';
|
return tag.key === 'http.method';
|
||||||
@ -74,6 +101,7 @@ export function findHeaderTags(spans: TraceSpan[]) {
|
|||||||
return { method, status, url };
|
return { method, status, url };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user