-
-
Notifications
You must be signed in to change notification settings - Fork 211
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
Option to link Http Request Spans to the Root Transaction? #1679
Comments
Given how the results are nested under each other instead of the root, I consider this more of a bug than an enhancement. |
I took another look at this recently, and I have a solution. My last statement was incorrect - it is an enhancement that is required, and the SDK is currently working as designed. The good news is, the enhancement is already specified in the Sentry Unified SDK spec:
In the .NET SDK, [HttpGet("GetAnimals")]
public async Task<IEnumerable<int>> GetDogs()
{
var dogs = Enumerable.Range(0, 200).ToList();
// Get the current span before starting the parallel operation.
var baseSpan = SentrySdk.GetSpan();
// Start the parallel operation.
var parallelOptions = new ParallelOptions {MaxDegreeOfParallelism = 6};
await Parallel.ForEachAsync(dogs, parallelOptions, async (dog, ct) =>
{
// Create a new scope for each iteration so they don't step on each other
// and we don't interfere with the parent scope.
await SentrySdk.WithScopeAsync(async scope =>
{
// Set the new scope's span to the base span we collected earlier.
// This ensures that any operation will be rooted to the starting point,
// rather than to just the latest span that happens to be open.
scope.Span = baseSpan;
// Now do the actual work.
await _httpClient.GetAsync($"{baseUri}/GetDog/{dog}", ct);
});
});
return dogs;
} Note that So all that's needed is to implement the |
I'm a bit embarrassed now, as it seems we reached a similar conclusion some time ago with #1845. |
Fixed in #2364 |
The important thing is that it got fixed :D |
Package
Sentry.AspNetCore
.NET Flavor
.NET Core
.NET Version
6.0.0
OS
Windows
SDK Version
3.17.1
Self-Hosted Sentry Version
No response
Steps to Reproduce
Sample project: https://github.com/lucas-zimerman/httpclient-stack-sample
run and once you get information on the browser an event will be sent to
Sentry SDKs
org on the .NET project.but it should be replicable if you call an httpclient in parallel inside of a request.
Expected Result
Looking at the code, you may expect that each span generated on the ForEach loop would have the parentId as
GetAnimals
Actual Result
https://sentry.io/organizations/sentry-sdks/discover/sentry-dotnet:dc044830d1994a2685d81dd22eb3cb7c/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All+Events&query=&sort=-timestamp&statsPeriod=1h&yAxis=count%28%29
Due to the defined behavior the HttpClient will try to get the last opened span and due to the parallel behavior, you'll end up with multiple
GetDog
spans inside of each other.One idea is to set an option that affects spans not generated by the user where you can define if the parent will be the last opened Span or always the scope Transaction, (or maybe even an user defined logic?).
EDIT: A brainstorm. Spans could have a parameter that would hide it from
GetSpan
, let's name itAllowChildren
. in specific cases like a http request, we could easily assume it's the last span from a stack so we setAllowChildren
as false on HttpClient spans, with that, when you callGetSpan
you'll always get the last open span that could have a children.The same idea could be applied to the DiagnosticSource Spans or even into parallel code from users.
The text was updated successfully, but these errors were encountered: