/
propagator.ts
88 lines (79 loc) · 2.87 KB
/
propagator.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
import {
Context,
isSpanContextValid,
TextMapGetter,
TextMapPropagator,
TextMapSetter,
trace,
TraceFlags,
} from '@opentelemetry/api';
import { isTracingSuppressed } from '@opentelemetry/core';
import {
baggageHeaderToDynamicSamplingContext,
dynamicSamplingContextToSentryBaggageHeader,
extractTraceparentData,
} from '@sentry/utils';
import {
SENTRY_BAGGAGE_HEADER,
SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY,
SENTRY_TRACE_HEADER,
SENTRY_TRACE_PARENT_CONTEXT_KEY,
} from './constants';
import { SENTRY_SPAN_PROCESSOR_MAP } from './spanprocessor';
/**
* Injects and extracts `sentry-trace` and `baggage` headers from carriers.
*/
export class SentryPropagator implements TextMapPropagator {
/**
* @inheritDoc
*/
public inject(context: Context, carrier: unknown, setter: TextMapSetter): void {
const spanContext = trace.getSpanContext(context);
if (!spanContext || !isSpanContextValid(spanContext) || isTracingSuppressed(context)) {
return;
}
const span = SENTRY_SPAN_PROCESSOR_MAP.get(spanContext.spanId);
if (span) {
setter.set(carrier, SENTRY_TRACE_HEADER, span.toTraceparent());
if (span.transaction) {
const dynamicSamplingContext = span.transaction.getDynamicSamplingContext();
const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
if (sentryBaggageHeader) {
setter.set(carrier, SENTRY_BAGGAGE_HEADER, sentryBaggageHeader);
}
}
}
}
/**
* @inheritDoc
*/
public extract(context: Context, carrier: unknown, getter: TextMapGetter): Context {
let newContext = context;
const maybeSentryTraceHeader: string | string[] | undefined = getter.get(carrier, SENTRY_TRACE_HEADER);
if (maybeSentryTraceHeader) {
const header = Array.isArray(maybeSentryTraceHeader) ? maybeSentryTraceHeader[0] : maybeSentryTraceHeader;
const traceparentData = extractTraceparentData(header);
newContext = newContext.setValue(SENTRY_TRACE_PARENT_CONTEXT_KEY, traceparentData);
if (traceparentData) {
const spanContext = {
traceId: traceparentData.traceId || '',
spanId: traceparentData.parentSpanId || '',
isRemote: true,
// Always sample if traceparent exists, we use SentrySpanProcessor to make sampling decisions with `startTransaction`.
traceFlags: TraceFlags.SAMPLED,
};
newContext = trace.setSpanContext(newContext, spanContext);
}
}
const maybeBaggageHeader = getter.get(carrier, SENTRY_BAGGAGE_HEADER);
const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(maybeBaggageHeader);
newContext = newContext.setValue(SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY, dynamicSamplingContext);
return newContext;
}
/**
* @inheritDoc
*/
public fields(): string[] {
return [SENTRY_TRACE_HEADER, SENTRY_BAGGAGE_HEADER];
}
}