|
1 |
| -import type { Baggage, Context, Span, TextMapGetter, TextMapSetter } from '@opentelemetry/api'; |
| 1 | +import type { Baggage, Context, Span, SpanContext, TextMapGetter, TextMapSetter } from '@opentelemetry/api'; |
| 2 | +import { TraceFlags } from '@opentelemetry/api'; |
2 | 3 | import { INVALID_TRACEID } from '@opentelemetry/api';
|
3 | 4 | import { context } from '@opentelemetry/api';
|
4 | 5 | import { propagation, trace } from '@opentelemetry/api';
|
@@ -30,8 +31,8 @@ import {
|
30 | 31 | } from './constants';
|
31 | 32 | import { DEBUG_BUILD } from './debug-build';
|
32 | 33 | import { getScopesFromContext, setScopesOnContext } from './utils/contextData';
|
33 |
| -import { generateSpanContextForPropagationContext } from './utils/generateSpanContextForPropagationContext'; |
34 | 34 | import { getSamplingDecision } from './utils/getSamplingDecision';
|
| 35 | +import { makeTraceState } from './utils/makeTraceState'; |
35 | 36 | import { setIsSetup } from './utils/setupCheck';
|
36 | 37 |
|
37 | 38 | /** Get the Sentry propagation context from a span context. */
|
@@ -88,11 +89,7 @@ export class SentryPropagator extends W3CBaggagePropagator {
|
88 | 89 | const url = activeSpan && getCurrentURL(activeSpan);
|
89 | 90 |
|
90 | 91 | const tracePropagationTargets = getClient()?.getOptions()?.tracePropagationTargets;
|
91 |
| - if ( |
92 |
| - typeof url === 'string' && |
93 |
| - tracePropagationTargets && |
94 |
| - !this._shouldInjectTraceData(tracePropagationTargets, url) |
95 |
| - ) { |
| 92 | + if (!shouldPropagateTraceForUrl(url, tracePropagationTargets, this._urlMatchesTargetsMap)) { |
96 | 93 | DEBUG_BUILD &&
|
97 | 94 | logger.log(
|
98 | 95 | '[Tracing] Not injecting trace data for url because it does not match tracePropagationTargets:',
|
@@ -168,22 +165,36 @@ export class SentryPropagator extends W3CBaggagePropagator {
|
168 | 165 | public fields(): string[] {
|
169 | 166 | return [SENTRY_TRACE_HEADER, SENTRY_BAGGAGE_HEADER];
|
170 | 167 | }
|
| 168 | +} |
171 | 169 |
|
172 |
| - /** If we want to inject trace data for a given URL. */ |
173 |
| - private _shouldInjectTraceData(tracePropagationTargets: Options['tracePropagationTargets'], url: string): boolean { |
174 |
| - if (tracePropagationTargets === undefined) { |
175 |
| - return true; |
176 |
| - } |
| 170 | +const NOT_PROPAGATED_MESSAGE = |
| 171 | + '[Tracing] Not injecting trace data for url because it does not match tracePropagationTargets:'; |
177 | 172 |
|
178 |
| - const cachedDecision = this._urlMatchesTargetsMap.get(url); |
179 |
| - if (cachedDecision !== undefined) { |
180 |
| - return cachedDecision; |
181 |
| - } |
| 173 | +/** |
| 174 | + * Check if a given URL should be propagated to or not. |
| 175 | + * If no url is defined, or no trace propagation targets are defined, this will always return `true`. |
| 176 | + * You can also optionally provide a decision map, to cache decisions and avoid repeated regex lookups. |
| 177 | + */ |
| 178 | +export function shouldPropagateTraceForUrl( |
| 179 | + url: string | undefined, |
| 180 | + tracePropagationTargets: Options['tracePropagationTargets'], |
| 181 | + decisionMap?: LRUMap<string, boolean>, |
| 182 | +): boolean { |
| 183 | + if (typeof url !== 'string' || !tracePropagationTargets) { |
| 184 | + return true; |
| 185 | + } |
182 | 186 |
|
183 |
| - const decision = stringMatchesSomePattern(url, tracePropagationTargets); |
184 |
| - this._urlMatchesTargetsMap.set(url, decision); |
185 |
| - return decision; |
| 187 | + const cachedDecision = decisionMap?.get(url); |
| 188 | + if (cachedDecision !== undefined) { |
| 189 | + DEBUG_BUILD && !cachedDecision && logger.log(NOT_PROPAGATED_MESSAGE, url); |
| 190 | + return cachedDecision; |
186 | 191 | }
|
| 192 | + |
| 193 | + const decision = stringMatchesSomePattern(url, tracePropagationTargets); |
| 194 | + decisionMap?.set(url, decision); |
| 195 | + |
| 196 | + DEBUG_BUILD && !decision && logger.log(NOT_PROPAGATED_MESSAGE, url); |
| 197 | + return decision; |
187 | 198 | }
|
188 | 199 |
|
189 | 200 | /**
|
@@ -287,3 +298,23 @@ function getCurrentURL(span: Span): string | undefined {
|
287 | 298 |
|
288 | 299 | return undefined;
|
289 | 300 | }
|
| 301 | + |
| 302 | +// TODO: Adjust this behavior to avoid invalid spans |
| 303 | +function generateSpanContextForPropagationContext(propagationContext: PropagationContext): SpanContext { |
| 304 | + // We store the DSC as OTEL trace state on the span context |
| 305 | + const traceState = makeTraceState({ |
| 306 | + parentSpanId: propagationContext.parentSpanId, |
| 307 | + dsc: propagationContext.dsc, |
| 308 | + sampled: propagationContext.sampled, |
| 309 | + }); |
| 310 | + |
| 311 | + const spanContext: SpanContext = { |
| 312 | + traceId: propagationContext.traceId, |
| 313 | + spanId: propagationContext.parentSpanId || '', |
| 314 | + isRemote: true, |
| 315 | + traceFlags: propagationContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE, |
| 316 | + traceState, |
| 317 | + }; |
| 318 | + |
| 319 | + return spanContext; |
| 320 | +} |
0 commit comments