public void Log <TState>( LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter) { if (!IsEnabled(logLevel)) { return; } var message = formatter?.Invoke(state, exception); if (SendEvent(logLevel, eventId, exception)) { var @event = new SentryEvent(exception) { Logger = CategoryName, Message = message, Level = logLevel.ToSentryLevel() }; var tuple = eventId.ToTupleOrNull(); if (tuple.HasValue) { @event.SetTag(tuple.Value.name, tuple.Value.value); } _hub.CaptureEvent(@event); } // Even if it was sent as event, add breadcrumb so next event includes it if (_options.MinimumBreadcrumbLevel != LogLevel.None && logLevel >= _options.MinimumBreadcrumbLevel) { var data = eventId.ToDictionaryOrNull(); if (exception != null && message != null) { // Exception.Message won't be used as Breadcrumb message // Avoid losing it by adding as data: data = data ?? new Dictionary <string, string>(); data.Add("exception_message", exception.Message); } _hub.AddBreadcrumb( _clock, message ?? exception?.Message, CategoryName, type: null, data, logLevel.ToBreadcrumbLevel()); } }
public void Log <TState>( LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter) { if (!IsEnabled(logLevel)) { return; } var message = formatter?.Invoke(state, exception); if (_options.MinimumEventLevel != LogLevel.None && logLevel >= _options.MinimumEventLevel) { var @event = new SentryEvent(exception) { Logger = CategoryName, }; if (message != null) { // TODO: this will override the current message // which could have been set from reading Exception.Message if (@event.Message != null) { @event.SetExtra("original_message", @event.Message); } @event.Message = message; } var tuple = eventId.ToTupleOrNull(); if (tuple.HasValue) { @event.SetTag(tuple.Value.name, tuple.Value.value); } _sentryClient.CaptureEvent(@event); } // Even if it was sent as event, add breadcrumb so next event includes it if (_options.MinimumBreadcrumbLevel != LogLevel.None && logLevel >= _options.MinimumBreadcrumbLevel) { var data = eventId.ToDictionaryOrNull(); if (exception != null && message != null) { // Exception.Message won't be used as Breadcrumb message // Avoid losing it by adding as data: data = data ?? new Dictionary <string, string>(); data.Add("exception_message", exception.Message); } _sentryClient.AddBreadcrumb( _clock, message ?? exception?.Message, "default", CategoryName, data, logLevel.ToBreadcrumbLevel()); } }
public void Log <TState>( LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter) { if (!IsEnabled(logLevel)) { return; } var message = formatter?.Invoke(state, exception); if (ShouldCaptureEvent(logLevel, eventId, exception)) { var @event = new SentryEvent(exception) { Logger = CategoryName, Message = message, Level = logLevel.ToSentryLevel() }; if (state is IEnumerable <KeyValuePair <string, object> > pairs) { foreach (var property in pairs) { if (property.Key == "{OriginalFormat}" && property.Value is string template) { // Original format found, use Sentry logEntry interface @event.Message = null; @event.LogEntry = new LogEntry { Formatted = message, Message = template }; continue; } if (property.Value is string tagValue) { @event.SetTag(property.Key, tagValue); } } } var tuple = eventId.ToTupleOrNull(); if (tuple.HasValue) { @event.SetTag(tuple.Value.name, tuple.Value.value); } _hub.CaptureEvent(@event); } // Even if it was sent as event, add breadcrumb so next event includes it if (ShouldAddBreadcrumb(logLevel, eventId, exception)) { var data = eventId.ToDictionaryOrNull(); if (exception != null && message != null) { // Exception.Message won't be used as Breadcrumb message // Avoid losing it by adding as data: data = data ?? new Dictionary <string, string>(); data.Add("exception_message", exception.Message); } _hub.AddBreadcrumb( _clock, message ?? exception?.Message, CategoryName, type: null, data, logLevel.ToBreadcrumbLevel()); } }