- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 225
fix: http integration uses correct parent span id #4264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
21c7fc1
              0233ca2
              18fae46
              4655627
              20fa9b7
              59fb4e8
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|  | @@ -86,7 +86,7 @@ protected override async Task<HttpResponseMessage> SendAsync( | |||||||||||||||||||||||||
| var span = ProcessRequest(request, method, url); | ||||||||||||||||||||||||||
| try | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| PropagateTraceHeaders(request, url); | ||||||||||||||||||||||||||
| PropagateTraceHeaders(request, url, span); | ||||||||||||||||||||||||||
| var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); | ||||||||||||||||||||||||||
| HandleResponse(response, span, method, url); | ||||||||||||||||||||||||||
| return response; | ||||||||||||||||||||||||||
|  | @@ -108,7 +108,7 @@ protected override HttpResponseMessage Send(HttpRequestMessage request, Cancella | |||||||||||||||||||||||||
| var span = ProcessRequest(request, method, url); | ||||||||||||||||||||||||||
| try | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| PropagateTraceHeaders(request, url); | ||||||||||||||||||||||||||
| PropagateTraceHeaders(request, url, span); | ||||||||||||||||||||||||||
| var response = base.Send(request, cancellationToken); | ||||||||||||||||||||||||||
| HandleResponse(response, span, method, url); | ||||||||||||||||||||||||||
| return response; | ||||||||||||||||||||||||||
|  | @@ -121,7 +121,7 @@ protected override HttpResponseMessage Send(HttpRequestMessage request, Cancella | |||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||
| private void PropagateTraceHeaders(HttpRequestMessage request, string url) | ||||||||||||||||||||||||||
| private void PropagateTraceHeaders(HttpRequestMessage request, string url, ISpan? parentSpan) | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| // Assign a default inner handler for convenience the first time this is used. | ||||||||||||||||||||||||||
| // We can't do this in a constructor, or it will throw when used with HttpMessageHandlerBuilderFilter. | ||||||||||||||||||||||||||
|  | @@ -135,15 +135,17 @@ private void PropagateTraceHeaders(HttpRequestMessage request, string url) | |||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||
| if (_options?.TracePropagationTargets.MatchesSubstringOrRegex(url) is true or null) | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| AddSentryTraceHeader(request); | ||||||||||||||||||||||||||
| AddSentryTraceHeader(request, parentSpan); | ||||||||||||||||||||||||||
| AddBaggageHeader(request); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||
| private void AddSentryTraceHeader(HttpRequestMessage request) | ||||||||||||||||||||||||||
| private void AddSentryTraceHeader(HttpRequestMessage request, ISpan? parentSpan) | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| // Set trace header if it hasn't already been set | ||||||||||||||||||||||||||
| if (!request.Headers.Contains(SentryTraceHeader.HttpHeaderName) && _hub.GetTraceHeader() is { } traceHeader) | ||||||||||||||||||||||||||
| if (!request.Headers.Contains(SentryTraceHeader.HttpHeaderName) && | ||||||||||||||||||||||||||
| // Use the span created by this integration as parent, instead of its own parent | ||||||||||||||||||||||||||
| (parentSpan?.GetTraceHeader() ?? _hub.GetTraceHeader()) is { } traceHeader) | ||||||||||||||||||||||||||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't be necessary. The previous behaviour simply got the header from  This seems like a workaround for the fact that the span representing the HttpRequest hasn't been set correctly as the current span then. Just looking at the code, I can't see why that would be. All of the machinery to make this happen seems to be in place. Basically the HttpMessageHandler creates the span here: sentry-dotnet/src/Sentry/SentryHttpMessageHandler.cs Lines 70 to 73 in dc3c0dd 
 And the new span gets pushed onto the stack to become the active span here: sentry-dotnet/src/Sentry/TransactionTracer.cs Lines 311 to 312 in aebd6a2 
 If you've got the code sample that results in the erroneous parent/child relationship, it'd be good to dig into this to try to work out what's going wrong with the active span tracking. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't want the http as current span. because otherwise any other span in parallel becomes a child of the http one. I saw this behavior before and it was broken the whole thing when using MAUI (or any global mode approach) is totally broken, with this I was able to set a span explicitly and have the parent child work properly for outgoing http regardless of what's explicitly set to the scope (see scope.Span) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to summarise a chat that @bruno-garcia and I had... The issue with not wanting the spans for outgoing HttpRequests to be mixed up with other spans (perhaps being performed in async Tasks) is a bit more nuanced. Currently, the way the MessageHandler creates spans is this: sentry-dotnet/src/Sentry/SentryHttpMessageHandler.cs Lines 68 to 73 in dc3c0dd 
 In the most common case then, if there's no  The way Bruno managed to work around that in the symbol collector is by setting  This appears to be completely undocumented. 
 | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| request.Headers.Add(SentryTraceHeader.HttpHeaderName, traceHeader.ToString()); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.