/
parse-otel-span-description.ts
89 lines (72 loc) · 2.64 KB
/
parse-otel-span-description.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { AttributeValue, SpanKind } from '@opentelemetry/api';
import { Span as OtelSpan } from '@opentelemetry/sdk-trace-base';
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
interface SpanDescription {
op: string | undefined;
description: string;
}
/**
* Extract better op/description from an otel span.
*
* Based on https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/7422ce2a06337f68a59b552b8c5a2ac125d6bae5/exporter/sentryexporter/sentry_exporter.go#L306
*
* @param otelSpan
* @returns Better op/description to use, or undefined
*/
export function parseSpanDescription(otelSpan: OtelSpan): SpanDescription {
const { attributes, name } = otelSpan;
// if http.method exists, this is an http request span
const httpMethod = attributes[SemanticAttributes.HTTP_METHOD];
if (httpMethod) {
return descriptionForHttpMethod(otelSpan, httpMethod);
}
// If db.type exists then this is a database call span.
const dbSystem = attributes[SemanticAttributes.DB_SYSTEM];
if (dbSystem) {
return descriptionForDbSystem(otelSpan, dbSystem);
}
// If rpc.service exists then this is a rpc call span.
const rpcService = attributes[SemanticAttributes.RPC_SERVICE];
if (rpcService) {
return {
op: 'rpc',
description: name,
};
}
// If messaging.system exists then this is a messaging system span.
const messagingSystem = attributes[SemanticAttributes.MESSAGING_SYSTEM];
if (messagingSystem) {
return {
op: 'message',
description: name,
};
}
// If faas.trigger exists then this is a function as a service span.
const faasTrigger = attributes[SemanticAttributes.FAAS_TRIGGER];
if (faasTrigger) {
return { op: faasTrigger.toString(), description: name };
}
return { op: undefined, description: name };
}
function descriptionForDbSystem(otelSpan: OtelSpan, _dbSystem: AttributeValue): SpanDescription {
const { attributes, name } = otelSpan;
// Use DB statement (Ex "SELECT * FROM table") if possible as description.
const statement = attributes[SemanticAttributes.DB_STATEMENT];
const description = statement ? statement.toString() : name;
return { op: 'db', description };
}
function descriptionForHttpMethod(otelSpan: OtelSpan, httpMethod: AttributeValue): SpanDescription {
const { name, kind } = otelSpan;
const opParts = ['http'];
switch (kind) {
case SpanKind.CLIENT:
opParts.push('client');
break;
case SpanKind.SERVER:
opParts.push('server');
break;
}
// Ex. description="GET /api/users/{user_id}".
const description = `${httpMethod} ${name}`;
return { op: opParts.join('.'), description };
}