protected override void ProcessException(
            SpecialException exception,
            SentryEvent sentryEvent)
        {
            sentryEvent.AddBreadcrumb("Processor running on special exception.");

            sentryEvent.SetTag("IsSpecial", exception.IsSpecial.ToString());
        }
示例#2
0
        public SentryEvent Process(SentryEvent @event)
        {
            // Here you can modify the event as you need
            if (@event.Level > SentryLevel.Info)
            {
                @event.AddBreadcrumb("Processed by " + nameof(SomeEventProcessor));
            }

            return(@event);
        }
示例#3
0
            public SentryEvent Process(SentryEvent @event)
            {
                // Here you can modify the event as you need
                if (@event.Level > SentryLevel.Info)
                {
                    @event.AddBreadcrumb("Processed by " + nameof(SomeEventProcessor));

                    @event.User = new User
                    {
                        Username = Environment.UserName
                    };

                    @event.ServerName = Environment.MachineName;
                }

                return(@event);
            }
示例#4
0
        public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject()
        {
            var ex        = new Exception("exception message");
            var timestamp = DateTimeOffset.MaxValue;
            var id        = Guid.Parse("4b780f4c-ec03-42a7-8ef8-a41c9d5621f8");
            var sut       = new SentryEvent(ex, timestamp, id)
            {
                User = new User {
                    Id = "user-id"
                },
                Request = new Request {
                    Method = "POST"
                },
                Contexts = new Contexts {
                    ["context_key"]    = "context_value",
                    [".NET Framework"] = new Dictionary <string, string> {
                        [".NET Framework"]        = "\"v2.0.50727\", \"v3.0\", \"v3.5\"",
                        [".NET Framework Client"] = "\"v4.8\", \"v4.0.0.0\"",
                        [".NET Framework Full"]   = "\"v4.8\""
                    }
                },
                Sdk = new SdkVersion {
                    Name = "SDK-test", Version = "1.1.1"
                },
                Environment = "environment",
                Level       = SentryLevel.Fatal,
                Logger      = "logger",
                Message     = new SentryMessage
                {
                    Message   = "message",
                    Formatted = "structured_message"
                },
                Modules          = { { "module_key", "module_value" } },
                Release          = "release",
                SentryExceptions = new[] { new SentryException {
                                               Value = "exception_value"
                                           } },
                SentryThreads = new[] { new SentryThread {
                                            Crashed = true
                                        } },
                ServerName      = "server_name",
                TransactionName = "transaction",
            };

            sut.Sdk.AddPackage(new Package("name", "version"));
            sut.AddBreadcrumb(new Breadcrumb(timestamp, "crumb"));
            sut.AddBreadcrumb(new Breadcrumb(
                                  timestamp,
                                  "message",
                                  "type",
                                  new Dictionary <string, string> {
                { "data-key", "data-value" }
            },
                                  "category",
                                  BreadcrumbLevel.Warning));

            sut.SetExtra("extra_key", "extra_value");
            sut.Fingerprint = new[] { "fingerprint" };
            sut.SetTag("tag_key", "tag_value");

            var actualString = sut.ToJsonString();

            var actual = SentryEvent.FromJson(Json.Parse(actualString));

            actual.Should().BeEquivalentTo(sut, o =>
            {
                // Due to timestamp precision
                o.Excluding(e => e.Breadcrumbs);
                o.Excluding(e => e.Exception);

                return(o);
            });

            // Expected item[0].Timestamp to be <9999-12-31 23:59:59.9999999>, but found <9999-12-31 23:59:59.999>.
            actual.Breadcrumbs.Should().BeEquivalentTo(sut.Breadcrumbs, o => o.Excluding(b => b.Timestamp));
            var counter = 0;

            foreach (var sutBreadcrumb in sut.Breadcrumbs)
            {
                sutBreadcrumb.Timestamp.Should().BeCloseTo(actual.Breadcrumbs.ElementAt(counter++).Timestamp);
            }
        }
示例#5
0
        public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject()
        {
            var ex        = new Exception("exception message");
            var timestamp = DateTimeOffset.MaxValue;
            var id        = Guid.Parse("4b780f4c-ec03-42a7-8ef8-a41c9d5621f8");
            var sut       = new SentryEvent(ex, timestamp, id)
            {
                User = new User {
                    Id = "user-id"
                },
                Request = new Request {
                    Method = "POST"
                },
                Contexts = new Contexts
                {
                    ["context_key"]    = "context_value",
                    [".NET Framework"] = new Dictionary <string, string>
                    {
                        [".NET Framework"]        = "\"v2.0.50727\", \"v3.0\", \"v3.5\"",
                        [".NET Framework Client"] = "\"v4.8\", \"v4.0.0.0\"",
                        [".NET Framework Full"]   = "\"v4.8\""
                    }
                },
                Sdk = new SdkVersion {
                    Name = "SDK-test", Version = "1.1.1"
                },
                Environment = "environment",
                Level       = SentryLevel.Fatal,
                Logger      = "logger",
                Message     = new SentryMessage
                {
                    Message   = "message",
                    Formatted = "structured_message"
                },
                Modules          = { { "module_key", "module_value" } },
                Release          = "release",
                SentryExceptions = new[] { new SentryException {
                                               Value = "exception_value"
                                           } },
                SentryThreads = new[] { new SentryThread {
                                            Crashed = true
                                        } },
                ServerName      = "server_name",
                TransactionName = "transaction",
            };

            sut.Sdk.AddPackage(new Package("name", "version"));
            sut.AddBreadcrumb(new Breadcrumb(timestamp, "crumb"));
            sut.AddBreadcrumb(new Breadcrumb(
                                  timestamp,
                                  "message",
                                  "type",
                                  new Dictionary <string, string> {
                { "data-key", "data-value" }
            },
                                  "category",
                                  BreadcrumbLevel.Warning));

            sut.SetExtra("extra_key", "extra_value");
            sut.Fingerprint = new[] { "fingerprint" };
            sut.SetTag("tag_key", "tag_value");

            var actualString = sut.ToJsonString();

            var actual = SentryEvent.FromJson(Json.Parse(actualString));

            // Assert
            actual.Should().BeEquivalentTo(sut, o =>
            {
                // Exceptions are not deserialized
                o.Excluding(x => x.Exception);

                // Timestamps lose some precision when writing to JSON
                o.Using <DateTimeOffset>(ctx =>
                                         ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromMilliseconds(1))
                                         ).WhenTypeIs <DateTimeOffset>();

                return(o);
            });
        }
示例#6
0
    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
    }
示例#7
0
    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 =>
        {
            // 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);
            };

            // 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);
            };

            // 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" });
            };
        }))
        {
            SentrySdk.AddBreadcrumb(
                "A 'bad breadcrumb' that will be rejected because of 'BeforeBreadcrumb callback above.'");

            // Data added to the root scope (no PushScope called up to this point)
            // The modifications done here will affect all events sent and will propagate to child scopes.
            await SentrySdk.ConfigureScopeAsync(async scope =>
            {
                scope.AddEventProcessor(new SomeEventProcessor());
                scope.AddExceptionProcessor(new ArgumentExceptionProcessor());

                // 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

            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:
            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
    }
示例#8
0
 protected override void ProcessException(
     Exception exception,
     SentryEvent sentryEvent)
 {
     sentryEvent.AddBreadcrumb("Processor running on special exception.");
 }