Replies: 10 comments
-
Thanks for raising. Apologies if this is confusing but I hope I'll be able to clarify all your points:
On each new request a new scope is pushed in by the SDK. Just like ASP.NET Core pushes one within the container. When you register something You can modify the current scope (say in a Controller, the current request) with If you don't want to couple your code with static classes, in ASP.NET Core we register a sentry-dotnet/src/Sentry/IHub.cs Lines 15 to 17 in 967c0e0 Also, you don't have to set things to the Scope. You can do it, so that you set it once and all events sent within that scope include that value. It's for convenience. The values from the Scope are copied over to the event on each event sent out but all of those properties still exist in the event. You can always set directly to it. You can always do: SentrySdk.CaptureEvent(new SentryEvent
{
// Everything sent to sentry is here
}); Or with a new client, without any scope involved: var client = new SentryClient(new SentryOptions
{
// Configure Client
});
client.CaptureEvent(new SentryEvent
{
// Access everything that gets sent to Sentry
});
client.Dispose(); // Blocks the thread until event is flushed out, closes the HttpClient
Sentry integration for ASP.NET Core uses the framework's dependency injection (DI). You don't need to register anything. When the docs mention all you need to do is If your register your factory, the SDK will not register the default one, that's how services.AddTransient<IUserFactory, MyUserFactory>(); If you register your factory, before sending an event the SDK will call your
These are hooks to the event processing pipeline. You can create a class that implement one of those interfaces and register with the DI container and the SDK will resole them from the container and invoke the
Those classes are in the Sample project. They are there just to show you can create your own and register with the container. The lifetime is up to you. In case you have an event processor that is not thread-safe, you should register it as Transient. The SDK will always ask the container for each event it processes so there'll be no race-condition. I suggest putting a breakpoint in one of these sample processors and stepping through the code. It's the same idea of services.AddTransient<ISentryEventProcessor, MarkVipCustomerEventProcessor>();
services.AddTransient<ISentryEventProcessor, DropTestUserEventProcessor>(); Where those classes would be something that takes their own dependencies via constructor injection and could do whatever your application requirements dictate. Basically it's a way to run your code against events before sending them. As the docs mention you can also drop events if you choose to return null instead of an event: sentry-dotnet/src/Sentry/Extensibility/ISentryEventProcessor.cs Lines 13 to 17 in 967c0e0
The new Unified API doesn't expose such hook. We've chosen to do that as there's no guarantee that events are sent to Sentry. If you choose to enable debugging
Yes. You can call I hope this clarifies things a bit. Let us know what continues blurry. |
Beta Was this translation helpful? Give feedback.
-
I think it's worth noting that when moving from ASP.NET classic to ASP.NET Core I suggest no longer relying to a Singleton instance of SentryClient around or static classes. If you need to send an event (without messing with the scope) simply take |
Beta Was this translation helpful? Give feedback.
-
Thanks @bruno-garcia. I'm working through your response now to try and apply it to my code. Eventually we are going to move to a DI-centric approach for logging, but currently our logging class is a static class that we call into when exceptions are caught both during an HttpRequest, and also outside the scope of the request. We obtain a sentry client from the HttpContext passed into our logging class, when it's available, otherwise we fall back to our singleton:
In this scenario, how do you set the Fingerprint and Tags of an event? With the old SDK, we were able to set the Fingerprint property directly on the Event. In the new SDK it's read-only. I see above where you indicated:
It's still not clear to me what happens when I call into that method from a static class. Is there some way to obtain/modify the Scope using the HttpContext object? Or if we obtain the client via the Assuming Tags/Fingerprints should now be defined on the scope instead of the event (this is still confusing to me). |
Beta Was this translation helpful? Give feedback.
-
@winzig You an set fingerprint by using the extension method Here's an example from the samples:
I'm unsure if you'll ever need the fallback though. With
If you obtain the client via var hub = context.RequestServices.GetService<Sentry.IHub>()
hub.ConfigureScope(s => ...); // whatever u set here will be included to ALL events sent during this request. Even after leaving this method.
hub.CaptureException(exception); // Sends one event for this one exception, including the Scope data u set above. But if you are about to send an event directly, without messing with the scope, you can just set the fingerprint to the Event: var client = context.RequestServices.GetService<Sentry.ISentryClient>();
var evt = new SentryEvent(exception);
evt.SetFingerprint(new [] { "..." });
client.CaptureEvent(evt); ^ No scope involved. The data you set to the event is sent to Sentry and doesn't stay around in memory in case more events are sent out (which is what scope does).
They can if you want to set it once, and any event sent later on in that same request will include them. If you set in the beginning of the request a tag I suggest opening the samples we have in the repo and debugging through, it should make it more clear. Let us know! |
Beta Was this translation helpful? Give feedback.
-
Yes, alongside our dotnet core web project, we have built out a class library with a lot of our business logic, and so in certain scenarios, we don't have an HttpContext available. In addition, we are currently planning to handle the exceptions with a middleware exception handler, rather than UseSentry(), so that our code that records exceptions into our local database can be shared between our class library code that has no HttpContext. (Updated to remove references to a problem I just resolved.) |
Beta Was this translation helpful? Give feedback.
-
Turns out a large part of my confusion related to tags, fingerprints, etc. was due to not having a Next issue is with the |
Beta Was this translation helpful? Give feedback.
-
@bruno-garcia Is there sample code somewhere showing the recommended way to register |
Beta Was this translation helpful? Give feedback.
-
@winzig there isn't a recommended way without |
Beta Was this translation helpful? Give feedback.
-
@bruno-garcia Because we send exceptions from a centralized class library that doesn’t always have an HttpContext. |
Beta Was this translation helpful? Give feedback.
-
@winzig the recommended way for class libraries is to pass an ISentryClient to the constructor of the current class. Alternatively you can pass an ILogger object, since Sentry adds a listener to the default Microsoft.Extensions.Logging provider. The last method is to use the static SentrySdk class. It uses AsyncLocal to retrieve the scope of the current request (if you called UseSentry during startup) so your library class doesn't need to be aware of the request itself. |
Beta Was this translation helpful? Give feedback.
-
For the most basic scenario ("I just want to log .NET exceptions to Sentry"), the documentation is adequate, and the
.UseSentry()
method is easy to use. But I'm trying to migrate from my original use of the Raven .NET SDK, and I keep running into things I can't find documented.So in the context of ASP.NET Core MVC, I ask these questions:
How do we modify the scope for the current HttpRequest?
Previously in my custom Sentry logging, I would create a
SentryEvent
, including modifying the fingerprint, setting the tags, etc. It seems like this is done on Scopes now, but I cannot figure out how to access the per-request Scope. All the sample code I'm seeing just calls into SentrySdk directly.This doc talks about the exact issue I'm facing — what's the best way to access the current Scope for the current request in ASP.NET MVC — except it doesn't actually explain how to do it. It just links to some sample code, but I am not seeing this in the code.
What's the preferred way of modifying User data before the event is sent to Sentry?
This page only talks about Scopes, but I have yet to find documentation which explains how to access the per-request scope that I presume Sentry has available somewhere.
I see
IUserFactory
, which seems similar to what we use in the old SDK,SentryUserFactory
. But it's unclear where to register that factory in the new SDK, assuming that's even the preferred way to modify User properties before logging an event.What are ISentryEventExceptionProcessor and ISentryEventProcessor?
In the MVC sample code, I see references to adding implementations of these as singletons and transients, but can't find where these classes are documented:
How do I do handle exceptions that may be encountered while logging to Sentry?
Previously there was an
ErrorOnCapture
on RavenClient, but not seeing anything like that in SentryClient.Is SentryClient thread-safe?
With
RavenClient
we would keep a static singleton around in scenarios where we wanted to log an exception outside of a typical HttpContext/request. Is this the best way to handle these scenarios with the new SDK?Beta Was this translation helpful? Give feedback.
All reactions