public async Task ConfigureScope_Async_CallbackNeverInvoked() { var invoked = false; await SentrySdk.ConfigureScopeAsync(_ => { invoked = true; return(Task.CompletedTask); }); Assert.False(invoked); }
/// <summary> /// Adds the default scope before sending an error to Sentry. /// (globals and user email) /// </summary> public static async void AddDefaultEnhancedTelemetryToScope() { if (IsDefaultEnhancedTelemetryInScope) { return; } await SentrySdk.ConfigureScopeAsync(async (scope) => { scope.SetTag("softwareType", Software.Type); scope.User = new Sentry.Protocol.User { Email = await Task.Run(Globals.GetAndSaveUserEmail) }; }); Console.WriteLine("Enhanced telemetry has been added to the scope."); IsDefaultEnhancedTelemetryInScope = true; }
private static async Task Main() { // When the SDK is disabled, no callback is executed: await SentrySdk.ConfigureScopeAsync(async scope => { // Never executed: // This could be any async I/O operation, like a DB query await Task.Yield(); scope.SetExtra("Key", "Value"); }); // Enable the SDK using (SentrySdk.Init(o => { // Send stack trace for events that were not created from an exception // e.g: CaptureMessage, log.LogDebug, log.LogInformation ... o.AttachStacktrace = true; // Sentry won't consider code from namespace LibraryX.* as part of the app code and will hide it from the stacktrace by default // To see the lines from non `AppCode`, select `Full`. Will include non App code like System.*, Microsoft.* and LibraryX.* o.AddInAppExclude("LibraryX."); // Before excluding all prefixed 'LibraryX.', any stack trace from a type namespaced 'LibraryX.Core' will be considered InApp. o.AddInAppInclude("LibraryX.Core"); // Send personal identifiable information like the username logged on to the computer and machine name o.SendDefaultPii = true; // To enable event sampling, uncomment: // o.SampleRate = 0.5f; // Randomly drop (don't send to Sentry) half of events // Modifications to event before it goes out. Could replace the event altogether o.BeforeSend = @event => { // Drop an event altogether: if (@event.Tags.ContainsKey("SomeTag")) { return(null); } return(@event); }; // Allows inspecting and modifying, returning a new or simply rejecting (returning null) o.BeforeBreadcrumb = crumb => { // Don't add breadcrumbs with message containing: if (crumb.Message?.Contains("bad breadcrumb") == true) { return(null); } return(crumb); }; // Ignore exception by its type: o.AddExceptionFilterForType <XsltCompileException>(); // Configure the background worker which sends events to sentry: // Wait up to 5 seconds before shutdown while there are events to send. o.ShutdownTimeout = TimeSpan.FromSeconds(5); // Enable SDK logging with Debug level o.Debug = true; // To change the verbosity, use: // o.DiagnosticLevel = SentryLevel.Info; // To use a custom logger: // o.DiagnosticLogger = ... // Using a proxy: o.HttpProxy = null; //new WebProxy("https://*****:*****@user{timestamp}.com"; SentrySdk.CaptureUserFeedback(new UserFeedback(eventId, user, email, "this is a sample user feedback")); var error = new Exception("Attempting to send this multiple times"); // Only the first capture will be sent to Sentry for (var i = 0; i < 3; i++) { // The SDK is able to detect duplicate events: // This is useful, for example, when multiple loggers log the same exception. Or exception is re-thrown and recaptured. SentrySdk.CaptureException(error); } var count = 10; for (var i = 0; i < count; i++) { const string msg = "{0} of {1} items we'll wait to flush to Sentry!"; SentrySdk.CaptureEvent(new SentryEvent { Message = new SentryMessage { Message = msg, Formatted = string.Format(msg, i, count) }, Level = SentryLevel.Debug }); } // Console output will show queue being flushed. Task completes then and timeout is never reached (you don't need to wait a day :) await SentrySdk.FlushAsync(TimeSpan.FromDays(1)); // ------------------------- // A custom made client, that could be registered with DI, // would get disposed by the container on app shutdown var evt = new SentryEvent(); evt.Message = "Starting new client"; evt.AddBreadcrumb("Breadcrumb directly to the event"); evt.User.Username = "******"; // Group all events with the following fingerprint: evt.SetFingerprint(new [] { "NewClientDebug" }); evt.Level = SentryLevel.Debug; SentrySdk.CaptureEvent(evt); // Using a different DSN: using (var adminClient = new SentryClient(new SentryOptions { Dsn = AdminDsn })) { // Make believe web framework middleware var middleware = new AdminPartMiddleware(adminClient, null); var request = new { Path = "/admin" }; // made up request middleware.Invoke(request); } // Dispose the client which flushes any queued events SentrySdk.CaptureException( new Exception("Error outside of the admin section: Goes to the default DSN")); } // On Dispose: SDK closed, events queued are flushed/sent to Sentry }
private static async Task Main(string[] args) { // When the SDK is disabled, no callback is executed: await SentrySdk.ConfigureScopeAsync(async scope => { // Never executed: // This could be any async I/O operation, like a DB query await Task.Yield(); scope.SetExtra("Key", "Value"); }); // Enable the SDK using (SentrySdk.Init(o => { o.AddEventProcessor(new SomeEventProcessor()); o.AddExceptionProcessor(new ArgumentExceptionProcessor()); // Send stack trace for events that were not created from an exception // e.g: CaptureMessage, log.LogDebug, log.LogInformation ... o.AttachStacktrace = true; // Sentry won't consider code from namespace LibraryX.* as part of the app code and will hide it from the stacktrace by default // To see the lines from non `AppCode`, select `Full`. That'll include non App code like System.*, Microsoft.* and LibraryX.* o.AddInAppExclude("LibraryX."); // Send personal identifiable information like the username logged on to the computer and machine name o.SendDefaultPii = true; // To enable event sampling, uncomment: // o.SampleRate = 0.5f; // Randomly drop (don't send to Sentry) half of events // Modifications to event before it goes out. Could replace the event altogether o.BeforeSend = @event => { // Drop an event altogether: if (@event.Tags.ContainsKey("SomeTag")) { return(null); } return(@event); }; // Configure the background worker which sends events to sentry: // Wait up to 5 seconds before shutdown while there are events to send. o.ShutdownTimeout = TimeSpan.FromSeconds(5); // Enable SDK logging with Debug level o.Debug = true; // To change the verbosity, use: // o.DiagnosticsLevel = SentryLevel.Info; // To use a custom logger: // o.DiagnosticLogger = ... // Using a proxy: o.HttpProxy = null; //new WebProxy("https://localhost:3128"); // Example customizing the HttpClientHandlers created o.ConfigureHandler = (handler, dsn) => { handler.ServerCertificateCustomValidationCallback = // A custom certificate validation (sender, certificate, chain, sslPolicyErrors) => !certificate.Archived; }; // Access to the HttpClient created to serve the SentryClint o.ConfigureClient = (client, dsn) => { client.DefaultRequestHeaders.TryAddWithoutValidation("CustomHeader", new[] { "my value" }); }; })) { await SentrySdk.ConfigureScopeAsync(async scope => { // This could be any async I/O operation, like a DB query await Task.Yield(); scope.SetExtra("SomeExtraInfo", new { Data = "Value fetched asynchronously", ManaLevel = 199 }); }); SentrySdk.CaptureMessage("Some warning!", SentryLevel.Warning); var error = new Exception("Attempting to send this multiple times"); // Only the first capture will be sent to Sentry for (var i = 0; i < 3; i++) { // The SDK is able to detect duplicate events: // This is useful, for example, when multiple loggers log the same exception. Or exception is re-thrown and recaptured. SentrySdk.CaptureException(error); } // ------------------------- // A custom made client, that could be registered with DI, // would get disposed by the container on app shutdown SentrySdk.CaptureMessage("Starting new client"); // Using a different DSN: var adminDsn = new Dsn(AdminDsn); using (var adminClient = new SentryClient(new SentryOptions { Dsn = adminDsn })) { // Make believe web framework middleware var middleware = new AdminPartMiddleware(adminClient, null); var request = new { Path = "/admin" }; // made up request middleware.Invoke(request); } // Dispose the client which flushes any queued events SentrySdk.CaptureException( new Exception("Error outside of the admin section: Goes to the default DSN")); } // On Dispose: SDK closed, events queued are flushed/sent to Sentry }
private static async Task Main(string[] args) { // When the SDK is disabled, no callback is executed: await SentrySdk.ConfigureScopeAsync(async scope => { // Never executed: // This could be any async I/O operation, like a DB query await Task.Yield(); scope.SetExtra("Key", "Value"); }); // Enable the SDK using (SentrySdk.Init(o => { o.AddEventProcessor(new SomeEventProcessor()); o.AddExceptionProcessor(new ArgumentExceptionProcessor()); // Modifications to event before it goes out. Could replace the event altogether o.BeforeSend = @event => { // Drop an event altogether: if (@event.Tags.ContainsKey("SomeTag")) { return(null); } return(@event); }; // Configure the background worker which sends events to sentry: o.Worker(w => { // Wait up to 5 seconds before shutdown while there are events to send. w.ShutdownTimeout = TimeSpan.FromSeconds(5); }); o.Http(h => { // Using a proxy: h.Proxy = null; //new WebProxy("https://localhost:3128"); }); })) { await SentrySdk.ConfigureScopeAsync(async scope => { // This could be any async I/O operation, like a DB query await Task.Yield(); scope.SetExtra("SomeExtraInfo", new { Data = "Value fetched asynchronously", ManaLevel = 199 }); }); SentrySdk.CaptureMessage("Some warning!", SentryLevel.Warning); var error = new Exception("Attempting to send this multiple times"); // Only the first capture will be sent to Sentry for (int i = 0; i < 100; i++) { // The SDK is able to detect duplicate events: // This is useful, for example, when multiple loggers log the same exception. Or exception is re-thrown and recaptured. SentrySdk.CaptureException(error); } // ------------------------- // A custom made client, that could be registered with DI, // would get disposed by the container on app shutdown SentrySdk.CaptureMessage("Starting new client"); // Using a different DSN: var adminDsn = new Dsn(AdminDsn); using (var adminClient = new SentryClient(new SentryOptions { Dsn = adminDsn })) { // Make believe web framework middleware var middleware = new AdminPartMiddleware(adminClient, null); middleware.Invoke("/admin"); } // Dispose the client which flushes any queued events SentrySdk.CaptureException( new Exception("Error outside of the admin section: Goes to the default DSN")); } // On Dispose: SDK closed, events queued are flushed/sent to Sentry }