public Hub(SentryOptions options) { Debug.Assert(options != null); _options = options; if (options.Dsn == null) { if (!Dsn.TryParse(DsnLocator.FindDsnStringOrDisable(), out var dsn)) { const string msg = "Attempt to instantiate a Hub without a DSN."; options.DiagnosticLogger?.LogFatal(msg); throw new InvalidOperationException(msg); } options.Dsn = dsn; } options.DiagnosticLogger?.LogDebug("Initializing Hub for Dsn: '{0}'.", options.Dsn); _ownedClient = new SentryClient(options); ScopeManager = new SentryScopeManager(options, _ownedClient); _integrations = options.Integrations; if (_integrations?.Length > 0) { foreach (var integration in _integrations) { options.DiagnosticLogger?.LogDebug("Registering integration: '{0}'.", integration.GetType().Name); integration.Register(this, options); } } // Push the first scope so the async local starts from here _rootScope = PushScope(); }
public void Dispose() { AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException; _ownedClient?.Dispose(); _ownedClient = null; (ScopeManager as IDisposable)?.Dispose(); }
public Hub(SentryOptions options) { // Create client from options and bind _ownedClient = new SentryClient(options); ScopeManager = new SentryScopeManager(options, _ownedClient); // TODO: Subscribing or not should be based on the Options or some IIntegration AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; }
public SentryMiddleware(RequestDelegate next, IConfigureOptions <SentryOptions> optionsSetup, SentryClient sentryClient, RateLimit rateLimit) { _next = next; _sentryClient = sentryClient; RateLimit = rateLimit; Options = GetOptions(optionsSetup); }
public SentryMiddleware(RequestDelegate next, IOptions <SentryOptions> optionsAccessor, SentryClient sentryClient, RateLimit rateLimit) { _next = next; _sentryClient = sentryClient; _rateLimit = rateLimit; Options = optionsAccessor.Value; }
public async Task TestReportInformationalMessage() { var client = new SentryClient(_dsn); var builder = client.CreateEventBuilder(); var date = DateTime.UtcNow.ToString("O"); builder.SetMessage($"This is an information at {date}\nI am another line."); await builder.CaptureAsync(); }
public SentryEventClient() { var dsn = new Dsn(ConfigurationManager.AppSettings["SentryDsn"]); SentryOptions sentryOptions = new SentryOptions { Dsn = dsn, Environment = this.Environment }; _sentryClient = new SentryClient(sentryOptions); }
public SentryLogger(OsuGame game) { if (!game.IsDeployedBuild) { return; } var options = new SentryOptions { Dsn = new Dsn("https://[email protected]/1255255"), Release = game.Version }; sentry = new SentryClient(options); sentryScope = new Scope(options); Exception lastException = null; Logger.NewEntry += entry => { if (entry.Level < LogLevel.Verbose) { return; } var exception = entry.Exception; if (exception != null) { if (!shouldSubmitException(exception)) { return; } // since we let unhandled exceptions go ignored at times, we want to ensure they don't get submitted on subsequent reports. if (lastException != null && lastException.Message == exception.Message && exception.StackTrace.StartsWith(lastException.StackTrace, StringComparison.Ordinal)) { return; } lastException = exception; sentry.CaptureEvent(new SentryEvent(exception) { Message = entry.Message }, sentryScope); } else { sentryScope.AddBreadcrumb(DateTimeOffset.Now, entry.Message, entry.Target.ToString(), "navigation"); } }; }
protected virtual void Dispose(bool isDisposing) { if (isDisposed) { return; } isDisposed = true; sentry?.Dispose(); sentry = null; sentryScope = null; }
public async Task TestReportException() { var client = new SentryClient(_dsn); try { SomeMethod(42); } catch (InvalidOperationException e) { await client.CaptureAsync(e); } }
public void Dispose() { if (_integrations?.Count > 0) { foreach (var integration in _integrations) { integration.Unregister(this); } } _ownedClient?.Dispose(); _ownedClient = null; (ScopeManager as IDisposable)?.Dispose(); }
private void Awake() { SentryOptions.Builder builder = new SentryOptions.Builder(dsn); UnityEventProcessor defaultProcessor = new UnityEventProcessor(); SentryOptions options = builder .SetDebug(true) .AddExclude("UnityEngine") .SetMaxBreadcrumbs(100) .SetSendDefaultPii(true) .SetEventProcessor(defaultProcessor.Process) .Build(); client = new SentryClient(options); }
public bool Capture(string json) { var result = false; var sentryId = new SentryClient(new SentryOptions() { Dsn = new Dsn(_dsn) }).CaptureMessage(json); if (!string.IsNullOrWhiteSpace(sentryId.ToString())) { result = true; } return(result); }
public SentryLogger(QsorBaseGame game) { if (DebugUtils.IsDebugBuild) { return; } var sentryOptions = new SentryOptions { Dsn = new Dsn("https://[email protected]/5193034"), Release = QsorBaseGame.Version }; _sentry = new SentryClient(sentryOptions); var sentryScope = new Scope(sentryOptions); Exception lastException = null; Logger.NewEntry += async entry => { if (entry.Level < LogLevel.Verbose) { return; } var exception = entry.Exception; if (exception != null) { if (lastException != null && // We shouldn't resubmit the same exception lastException.Message == exception.Message && exception.StackTrace?.StartsWith(lastException.StackTrace ?? string.Empty) == true) { return; } _sentry.CaptureEvent(new SentryEvent(exception) { Message = entry.Message }, sentryScope); lastException = exception; } else { sentryScope.AddBreadcrumb(DateTimeOffset.Now, entry.Message, entry.Target.ToString(), "qsor-logger"); } }; }
public void Dispose() { _options.DiagnosticLogger?.LogInfo("Disposing the Hub."); if (_integrations?.Count > 0) { foreach (var integration in _integrations) { integration.Unregister(this); } } _ownedClient?.Dispose(); _ownedClient = null; (ScopeManager as IDisposable)?.Dispose(); }
public void Log(object logMessage, LogLevel logLevel, params string[] vals) { if (logLevel == LogLevel.Critical && logMessage is Exception exception && !(exception is NonLoggableException)) { var sentryEvent = new SentryEvent(exception); lock (_lockingObject) { foreach (var contextKeyValue in ContextData) { sentryEvent.SetExtra(contextKeyValue.Key, contextKeyValue.Value); } SentryClient.CaptureEvent(sentryEvent); } } }
public Hub(SentryOptions options) { Debug.Assert(options != null); _ownedClient = new SentryClient(options); ScopeManager = new SentryScopeManager(options, _ownedClient); _integrations = options.Integrations; if (_integrations?.Count > 0) { foreach (var integration in _integrations) { integration.Register(this); } } }
public SentryLogger(OsuGame game) { if (!game.IsDeployedBuild) { return; } var options = new SentryOptions { Dsn = "https://[email protected]/1255255", Release = game.Version }; sentry = new SentryClient(options); sentryScope = new Scope(options); Logger.NewEntry += processLogEntry; }
protected override void OnActivate() { Me = Context.Owner as Hero; AbilityFacory = Context.AbilityFactory; // Log.Debug($"Init TextureHelper"); // TextureHelper.Init(Context); Log.Debug("Load abilities"); AbilitiesInCombo = new AbilitiesInCombo(this); Log.Debug("Load config"); Config = new Config(this); Log.Debug("Load updater"); Updater = new Updater(this); Log.Debug("Load combo"); Combo = new Combo(this); Log.Debug("Load Notification Helper"); NotificationHelper = new NotificationHelper(this); Log.Debug("Load NavMeshHelper"); NavMeshHelper = new NavMeshHelper(this); Log.Warn(AbilitiesInCombo.Tornado.Duration); //var test=new DivineSuccess(); _client = new SentryClient( "https://*****:*****@sentry.io/1545139"); // _client.Client.Environment = "info"; AppDomain.CurrentDomain.UnhandledException += (sender, args) => { Console.WriteLine(args); var ex = (Exception)args.ExceptionObject; _client.CaptureAsync(ex); }; if (Game.GameMode != GameMode.Demo) { _client.Capture(new SentryEvent("invoker loaded")); } }
/// <summary> /// Initializes a new instance of the <see cref="SentryLogger"/> class. /// </summary> public SentryLogger() { GetDsn(out var dsn); if (dsn == null) { _isEnabled = _ => false; return; } // DSN is well-formatted --> Enable logging for errors _isEnabled = level => level == LogLevel.Error; // Setup logging var options = new SentryOptions { // Sentry authentication Dsn = dsn, // Attach entire stack-trace AttachStacktrace = true, // Send user info like IP SendDefaultPii = true, }; _sentryClient = new SentryClient(options); // Set configuration _serializedConfiguration = new SerializerBuilder().Build() .Serialize(Configuration.Configuration.Instance); var algorithm = Configuration.Configuration.Instance.EnabledAlgorithm; _serializedAlgorithmConfiguration += $"\n## {algorithm.Algorithm.Name} ##\n"; try { _serializedAlgorithmConfiguration += File.ReadAllText($"{algorithm.Algorithm.Name}.yaml"); } catch (FileNotFoundException) { _serializedAlgorithmConfiguration += $"Could not find file {algorithm.Algorithm.Name}.yaml, but this " + "algorithm is enabled"; } }
public Hub(SentryOptions options) { Debug.Assert(options != null); _options = options; options.DiagnosticLogger?.LogDebug("Initializing Hub for Dsn: '{0}'.", options.Dsn); _ownedClient = new SentryClient(options); ScopeManager = new SentryScopeManager(options, _ownedClient); _integrations = options.Integrations; if (_integrations?.Count > 0) { foreach (var integration in _integrations) { options.DiagnosticLogger?.LogDebug("Registering integration: '{0}'.", integration.GetType().Name); integration.Register(this); } } }
static Logger() { DisableCapture = Game.ExpectedPlayers == 1 || DisabledCaptureModes.Contains(Game.GameMode); const string Key = "ed70f139a30e4c3e8481e629e541dec6:c07ecbe5b1c243aeb9b19b8d40b73461"; const string Project = "1277552"; Client = new SentryClient($"https://{Key}@sentry.io/{Project}"); var metadata = Assembly.GetExecutingAssembly().GetMetadata(); if (metadata == null) { return; } Client.Client.Release = metadata.Commit; Client.Tags["core"] = () => metadata.Version; Client.Tags["mode"] = () => Game.GameMode.ToString(); Client.Tags["hero"] = () => ObjectManager.LocalHero.Name; }
public async Task TestReportExceptionWithBreadcrumbsAndAdditionalInfo() { var client = new SentryClient(_dsn, new SentryEventDefaults(environment: "the_env", serverName: "server1")); var sentryEventBuilder = client.CreateEventBuilder(); sentryEventBuilder.Level = SeverityLevel.Warning; sentryEventBuilder.Breadcrumbs.Add(new SentryBreadcrumb("bread.crumb.1")); sentryEventBuilder.Breadcrumbs.Add(new SentryBreadcrumb("bread.crumb.2") { Level = SeverityLevel.Debug }); try { SomeMethod(42); } catch (InvalidOperationException e) { sentryEventBuilder.SetException(e); await sentryEventBuilder.CaptureAsync(); } }
public SentryEventService() { _httpClient = new HttpClient(); _sentryClient = new SentryClient(ConfigureSentryOptions()); }
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 }
public SentryMiddleware CreateMiddleware(RequestDelegate next, SentryClient client) => new SentryMiddleware(next, Options.Create(ExceptionReportingOptions), client, new RateLimit());
public static SentryAuth Issue(SentryClient client, DateTimeOffset issuedAt) => new SentryAuth(sentryVersion: Sentry.CurrentProtocolVersion, clientVersion: string.Join("/", $"{SentryClient.Name}-csharp", SentryClient.Version), timestamp: UnixTimestamp.Create(issuedAt), publicKey: client.Dsn.GetPublicKey(), secretKey: client.Dsn.GetSecretKey());
public override async Task ConfigureAsync(ServiceCollection serviceCollection) { CreateLogger(configuration.LogLevel); if (string.IsNullOrWhiteSpace(configuration.ConnectionString)) { throw new InvalidOperationException("Connection string cannot be null"); } serviceCollection.AddDbContext <MikiDbContext>( x => x.UseNpgsql( configuration.ConnectionString, b => b.MigrationsAssembly("Miki.Bot.Models")) .EnableDetailedErrors()); serviceCollection.AddDbContext <DbContext, MikiDbContext>( x => x.UseNpgsql( configuration.ConnectionString, b => b.MigrationsAssembly("Miki.Bot.Models")) .EnableDetailedErrors()); serviceCollection.AddScoped <IUnitOfWork, UnitOfWork>(); serviceCollection.AddSingleton(configuration.Configuration); serviceCollection.AddSingleton <ISerializer, ProtobufSerializer>(); serviceCollection.AddScoped < IRepositoryFactory <Achievement>, AchievementRepository.Factory>(); serviceCollection.AddScoped(x => new MikiApiClient(x.GetService <Config>().MikiApiKey)); // Setup Discord serviceCollection.AddSingleton <IApiClient>( s => new DiscordApiClient(s.GetService <Config>().Token, s.GetService <ICacheClient>())); if (configuration.IsSelfHosted) { serviceCollection.AddSingleton <IGateway>( new GatewayShard( new GatewayProperties { ShardCount = 1, ShardId = 0, Token = configuration.Configuration.Token, AllowNonDispatchEvents = true, Intents = GatewayIntents.AllDefault | GatewayIntents.GuildMembers })); serviceCollection.AddSingleton <ICacheClient, InMemoryCacheClient>(); serviceCollection.AddSingleton <IExtendedCacheClient, InMemoryCacheClient>(); var splitConfig = new ConfigurationOptions { LocalhostFilePath = "./feature_flags.yaml" }; var factory = new SplitFactory("localhost", splitConfig); var client = factory.Client(); client.BlockUntilReady(30000); serviceCollection.AddSingleton(client); } else { var consumer = new RetsuConsumer( new ConsumerConfiguration { ConnectionString = new Uri(configuration.Configuration.RabbitUrl), QueueName = "gateway", ExchangeName = "consumer", ConsumerAutoAck = false, PrefetchCount = 25, }, new Retsu.Consumer.Models.QueueConfiguration { ConnectionString = new Uri(configuration.Configuration.RabbitUrl), QueueName = "gateway-command", ExchangeName = "consumer", }); await consumer.SubscribeAsync("MESSAGE_CREATE"); await consumer.SubscribeAsync("MESSAGE_UPDATE"); await consumer.SubscribeAsync("MESSAGE_DELETE"); await consumer.SubscribeAsync("MESSAGE_DELETE_BULK"); await consumer.SubscribeAsync("MESSAGE_REACTION_ADD"); await consumer.SubscribeAsync("MESSAGE_REACTION_REMOVE"); await consumer.SubscribeAsync("MESSAGE_REACTION_REMOVE_ALL"); await consumer.SubscribeAsync("MESSAGE_REACTION_REMOVE_EMOJI"); await consumer.SubscribeAsync("CHANNEL_CREATE"); await consumer.SubscribeAsync("CHANNEL_DELETE"); await consumer.SubscribeAsync("CHANNEL_PINS_UPDATE"); await consumer.SubscribeAsync("CHANNEL_UPDATE"); await consumer.SubscribeAsync("GUILD_CREATE"); await consumer.SubscribeAsync("GUILD_DELETE"); await consumer.SubscribeAsync("GUILD_UPDATE"); await consumer.SubscribeAsync("GUILD_BAN_ADD"); await consumer.SubscribeAsync("GUILD_BAN_REMOVE"); await consumer.SubscribeAsync("GUILD_EMOJIS_UPDATE"); await consumer.SubscribeAsync("GUILD_MEMBER_ADD"); await consumer.SubscribeAsync("GUILD_MEMBER_REMOVE"); await consumer.SubscribeAsync("GUILD_MEMBER_UPDATE"); await consumer.SubscribeAsync("GUILD_ROLE_CREATE"); await consumer.SubscribeAsync("GUILD_ROLE_DELETE"); await consumer.SubscribeAsync("GUILD_ROLE_UPDATE"); await consumer.SubscribeAsync("READY"); await consumer.SubscribeAsync("RESUMED"); serviceCollection.AddSingleton <IGateway>(consumer); serviceCollection.AddSingleton( new RedisConnectionPool(configuration.Configuration.RedisConnectionString)); serviceCollection.AddTransient( x => x.GetRequiredService <RedisConnectionPool>().Get()); serviceCollection.AddTransient <ICacheClient, StackExchangeCacheClient>(); serviceCollection.AddTransient <IExtendedCacheClient, StackExchangeCacheClient>(); ISplitClient client = null; if (!string.IsNullOrEmpty(configuration.Configuration.OptionalValues?.SplitioSdkKey)) { var splitConfig = new ConfigurationOptions(); var factory = new SplitFactory( configuration.Configuration.OptionalValues?.SplitioSdkKey, splitConfig); client = factory.Client(); try { client.BlockUntilReady(30000); } catch (TimeoutException) { Log.Error("Couldn't initialize splitIO in time."); } } serviceCollection.AddSingleton(x => client); } serviceCollection.AddSingleton <IDiscordClient, DiscordClient>(); // Setup web services serviceCollection.AddSingleton <UrbanDictionaryApi>(); // Setup miscellanious services serviceCollection.AddSingleton <ConfigurationManager>(); serviceCollection.AddSingleton( await BackgroundStore.LoadFromFileAsync("./resources/backgrounds.json")); ISentryClient sentryClient = null; if (!string.IsNullOrWhiteSpace(configuration.Configuration.SharpRavenKey)) { sentryClient = new SentryClient( new SentryOptions { Dsn = new Dsn(configuration.Configuration.SharpRavenKey) }); } serviceCollection.AddSingleton(s => sentryClient); serviceCollection.AddSingleton <IMessageWorker <IDiscordMessage>, MessageWorker>(); serviceCollection.AddSingleton <TransactionEvents>(); serviceCollection.AddSingleton(await BuildLocalesAsync()); serviceCollection.AddScoped <ISettingsService, SettingsService>(); serviceCollection.AddScoped <IUserService, UserService>(); serviceCollection.AddScoped <IDailyService, DailyService>(); serviceCollection.AddSingleton <AccountService>(); serviceCollection.AddScoped <PastaService>(); serviceCollection.AddSingleton <RedditService>(); serviceCollection.AddSingleton <AchievementCollection>(); serviceCollection.AddScoped <AchievementService>(); serviceCollection.AddSingleton <ISchedulerService, SchedulerService>(); serviceCollection.AddScoped <IGuildService, GuildService>(); serviceCollection.AddScoped <MarriageService>(); serviceCollection.AddScoped <IRpsService, RpsService>(); serviceCollection.AddScoped <ILocalizationService, LocalizationService>(); serviceCollection.AddScoped <PermissionService>(); serviceCollection.AddScoped <ScopeService>(); serviceCollection.AddScoped <ITransactionService, TransactionService>(); serviceCollection.AddScoped <IBankAccountService, BankAccountService>(); serviceCollection.AddSingleton <LotteryEventHandler>(); serviceCollection.AddScoped <ILotteryService, LotteryService>(); serviceCollection.AddSingleton <IOsuApiClient>( _ => configuration.Configuration.OptionalValues?.OsuApiKey == null ? null : new OsuApiClientV1(configuration.Configuration.OptionalValues.OsuApiKey)); serviceCollection.AddScoped <BlackjackService>(); serviceCollection.AddScoped <LeaderboardsService>(); serviceCollection.AddSingleton(new PrefixCollectionBuilder() .AddAsDefault(new DynamicPrefixTrigger(">")) .Add(new PrefixTrigger("miki.")) .Add(new MentionTrigger()) .Build()); serviceCollection.AddScoped <IPrefixService, PrefixService>(); serviceCollection.AddSingleton( x => new CommandTreeBuilder(x).Create(Assembly.GetExecutingAssembly())); serviceCollection.AddSingleton <CommandTreeService>(); serviceCollection.AddSingleton <IAsyncEventingExecutor <IDiscordMessage> >( services => new CommandPipelineBuilder(services) .UseStage(new CorePipelineStage()) .UseFilters(new BotFilter(), new UserFilter()) .UsePrefixes() .UseStage(new FetchDataStage()) .UseLocalization() .UseArgumentPack() .UseCommandHandler() .UsePermissions() .UseScopes() .Build()); serviceCollection.AddSingleton <DatadogRoutine>(); }
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 }
protected virtual void Dispose(bool isDisposing) { Logger.NewEntry -= processLogEntry; sentry = null; sentryScope = null; }