-
-
Notifications
You must be signed in to change notification settings - Fork 226
Description
Originally posted by @jamescrosswell in #3836
The SDK includes a StartOrContinueTrace method that returns a transaction context but doesn't use that context to start a new transaction...
sentry-dotnet/src/Sentry.AspNet/HttpContextExtensions.cs
Lines 60 to 130 in 3e70c31
| /// <summary> | |
| /// Starts or continues a Sentry trace. | |
| /// </summary> | |
| public static void StartOrContinueTrace(this HttpContext httpContext) | |
| { | |
| var options = SentrySdk.CurrentOptions; | |
| var traceHeader = TryGetSentryTraceHeader(httpContext, options); | |
| var baggageHeader = TryGetBaggageHeader(httpContext, options); | |
| var method = httpContext.Request.HttpMethod; | |
| var path = httpContext.Request.Path; | |
| var transactionName = $"{method} {path}"; | |
| const string operation = "http.server"; | |
| SentrySdk.ContinueTrace(traceHeader, baggageHeader, transactionName, operation); | |
| } | |
| /// <summary> | |
| /// Starts a new Sentry transaction that encompasses the currently executing HTTP request. | |
| /// </summary> | |
| public static ITransactionTracer StartSentryTransaction(this HttpContext httpContext) | |
| { | |
| var method = httpContext.Request.HttpMethod; | |
| var path = httpContext.Request.Path; | |
| var options = SentrySdk.CurrentOptions; | |
| var traceHeader = TryGetSentryTraceHeader(httpContext, options); | |
| var baggageHeader = TryGetBaggageHeader(httpContext, options); | |
| var transactionName = $"{method} {path}"; | |
| const string transactionOperation = "http.server"; | |
| var transactionContext = SentrySdk.ContinueTrace(traceHeader, baggageHeader, transactionName, transactionOperation); | |
| transactionContext.NameSource = TransactionNameSource.Url; | |
| var customSamplingContext = new Dictionary<string, object?>(3, StringComparer.Ordinal) | |
| { | |
| ["__HttpMethod"] = method, | |
| ["__HttpPath"] = path, | |
| ["__HttpContext"] = httpContext, | |
| }; | |
| // Set the Dynamic Sampling Context from the baggage header, if it exists. | |
| var dynamicSamplingContext = baggageHeader?.CreateDynamicSamplingContext(); | |
| if (traceHeader is not null && baggageHeader is null) | |
| { | |
| // We received a sentry-trace header without a baggage header, which indicates the request | |
| // originated from an older SDK that doesn't support dynamic sampling. | |
| // Set DynamicSamplingContext.Empty to "freeze" the DSC on the transaction. | |
| // See: | |
| // https://develop.sentry.dev/sdk/performance/dynamic-sampling-context/#freezing-dynamic-sampling-context | |
| // https://develop.sentry.dev/sdk/performance/dynamic-sampling-context/#unified-propagation-mechanism | |
| dynamicSamplingContext = DynamicSamplingContext.Empty; | |
| } | |
| var transaction = SentrySdk.StartTransaction(transactionContext, customSamplingContext, dynamicSamplingContext); | |
| transaction.Contexts.Trace.Origin = AspNetOrigin; | |
| SentrySdk.ConfigureScope(scope => scope.Transaction = transaction); | |
| httpContext.Items[HttpContextTransactionItemName] = transaction; | |
| if (options?.SendDefaultPii is true) | |
| { | |
| transaction.Request.Cookies = string.Join("; ", httpContext.Request.Cookies.AllKeys.Select(x => $"{x}={httpContext.Request.Cookies[x]?.Value}")); | |
| } | |
| return transaction; | |
| } |
Under the hood, this propagates trace headers even when performance is disabled:
sentry-dotnet/src/Sentry/Internal/Hub.cs
Lines 252 to 253 in 3fde00a
| var propagationContext = SentryPropagationContext.CreateFromHeaders(_options.DiagnosticLogger, traceHeader, baggageHeader); | |
| ConfigureScope(scope => scope.PropagationContext = propagationContext); |
Later this information gets used when forming headers for outbound requests:
sentry-dotnet/src/Sentry/Internal/Hub.cs
Lines 200 to 211 in 3fde00a
| public SentryTraceHeader GetTraceHeader() | |
| { | |
| if (GetSpan()?.GetTraceHeader() is { } traceHeader) | |
| { | |
| return traceHeader; | |
| } | |
| // With either tracing disabled or no active span on the current scope we fall back to the propagation context | |
| var propagationContext = CurrentScope.PropagationContext; | |
| // In either case, we must not append a sampling decision. | |
| return new SentryTraceHeader(propagationContext.TraceId, propagationContext.SpanId, null); | |
| } |
That intent should be clearly documented in the summary for the StartOrContinueTrace method.