Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 32 additions & 25 deletions src/Sentry.Extensions.Logging/SentryLogger.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using Sentry.Extensibility;
using Sentry.Infrastructure;
using Sentry.Internal;

Expand Down Expand Up @@ -51,7 +52,12 @@ public void Log<TState>(

var message = formatter?.Invoke(state, exception);

if (ShouldCaptureEvent(logLevel, eventId, exception))
if (IsFromSentry() || IsEfExceptionMessage(eventId) || IsFiltered(logLevel, eventId, exception))
{
return;
}

if (ShouldCaptureEvent(logLevel))
{
var @event = CreateEvent(logLevel, eventId, state, exception, message, CategoryName);

Expand All @@ -64,7 +70,7 @@ public void Log<TState>(
}
}

if (ShouldAddBreadcrumb(logLevel, eventId, exception))
if (ShouldAddBreadcrumb(logLevel))
{
var data = eventId.ToDictionaryOrNull();

Expand Down Expand Up @@ -153,35 +159,36 @@ internal static SentryEvent CreateEvent<TState>(
return @event;
}

private bool ShouldCaptureEvent(
private bool ShouldCaptureEvent(LogLevel logLevel)
=> _options.MinimumEventLevel != LogLevel.None
&& logLevel >= _options.MinimumEventLevel;

private bool ShouldAddBreadcrumb(LogLevel logLevel)
=> _options.MinimumBreadcrumbLevel != LogLevel.None
&& logLevel >= _options.MinimumBreadcrumbLevel;

private bool IsFiltered(
LogLevel logLevel,
EventId eventId,
Exception? exception)
=> _options.MinimumEventLevel != LogLevel.None
&& logLevel >= _options.MinimumEventLevel
&& !IsFromSentry()
&& !IsEfExceptionMessage(eventId)
&& _options.Filters.All(
f => !f.Filter(
CategoryName,
logLevel,
eventId,
exception));

private bool ShouldAddBreadcrumb(
=> _options.Filters.Any(f => IsFiltered(f, logLevel, eventId, exception));

private bool IsFiltered(
ILogEntryFilter filter,
LogLevel logLevel,
EventId eventId,
Exception? exception)
=> _options.MinimumBreadcrumbLevel != LogLevel.None
&& logLevel >= _options.MinimumBreadcrumbLevel
&& !IsFromSentry()
&& !IsEfExceptionMessage(eventId)
&& _options.Filters.All(
f => !f.Filter(
CategoryName,
logLevel,
eventId,
exception));
{
try
{
return filter.Filter(CategoryName, logLevel, eventId, exception);
}
catch (Exception e)
{
_options.LogError(e, "The {0} log filter callback failed. The log entry will be filtered out.", filter.GetType().Name);
return true;
}
}


private bool IsFromSentry() => SentrySdkNamespaces.IsSentrySdk(CategoryName);
Expand Down
18 changes: 16 additions & 2 deletions src/Sentry.Maui/Internal/SentryMauiScreenshotProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,23 @@ public SentryMauiScreenshotProcessor(SentryMauiOptions options)

public SentryEvent? Process(SentryEvent @event, SentryHint hint)
{
if (!_options.BeforeCaptureInternal?.Invoke(@event, hint) ?? false)
if (_options.BeforeScreenshotCaptureInternal is { } beforeCapture)
{
return @event;
bool shouldCapture;
try
{
shouldCapture = beforeCapture.Invoke(@event, hint);
}
catch (Exception e)
{
_options.LogError(e, "BeforeScreenshotCapture callback failed.");
return @event;
}

if (!shouldCapture)
{
return @event;
}
}

hint.Attachments.Add(new ScreenshotAttachment(_options));
Expand Down
8 changes: 4 additions & 4 deletions src/Sentry.Maui/SentryMauiOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ public SentryMauiOptions()
/// </remarks>
public bool AttachScreenshot { get; set; }

private Func<SentryEvent, SentryHint, bool>? _beforeCapture;
private Func<SentryEvent, SentryHint, bool>? _beforeScreenshotCapture;
/// <summary>
/// Action performed before attaching a screenshot
/// </summary>
internal Func<SentryEvent, SentryHint, bool>? BeforeCaptureInternal => _beforeCapture;
internal Func<SentryEvent, SentryHint, bool>? BeforeScreenshotCaptureInternal => _beforeScreenshotCapture;

/// <summary>
/// Configures a callback function to be invoked before taking a screenshot
Expand All @@ -90,7 +90,7 @@ public SentryMauiOptions()
/// </remarks>
/// <code>
///
///options.SetBeforeCapture((@event, hint) =>
///options.SetBeforeScreenshotCapture((@event, hint) =>
///{
/// // Return true to capture or false to prevent the capture
/// return true;
Expand All @@ -99,6 +99,6 @@ public SentryMauiOptions()
/// <param name="beforeCapture">Callback to be executed before taking a screenshot</param>
public void SetBeforeScreenshotCapture(Func<SentryEvent, SentryHint, bool> beforeCapture)
{
_beforeCapture = beforeCapture;
_beforeScreenshotCapture = beforeCapture;
}
}
13 changes: 11 additions & 2 deletions src/Sentry/Internal/DefaultSentryMetricEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ private protected override void CaptureMetric<T>(SentryMetricType type, string n
{
if (!SentryMetric.IsSupported(typeof(T)))
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.Invalid, DataCategory.TraceMetric);
_options.DiagnosticLogger?.LogWarning("{0} is unsupported type for Sentry Metrics. The only supported types are byte, short, int, long, float, and double.", typeof(T));
return;
}

if (string.IsNullOrEmpty(name))
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.Invalid, DataCategory.TraceMetric);
_options.DiagnosticLogger?.LogWarning("Name of metrics cannot be null or empty. Metric-Type: {0}; Value-Type: {1}", type.ToString(), typeof(T));
return;
}
Expand All @@ -46,12 +48,14 @@ private protected override void CaptureMetric<T>(SentryMetricType type, string n
{
if (!SentryMetric.IsSupported(typeof(T)))
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.Invalid, DataCategory.TraceMetric);
_options.DiagnosticLogger?.LogWarning("{0} is unsupported type for Sentry Metrics. The only supported types are byte, short, int, long, float, and double.", typeof(T));
return;
}

if (string.IsNullOrEmpty(name))
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.Invalid, DataCategory.TraceMetric);
_options.DiagnosticLogger?.LogWarning("Name of metrics cannot be null or empty. Metric-Type: {0}; Value-Type: {1}", type.ToString(), typeof(T));
return;
}
Expand All @@ -76,15 +80,20 @@ private protected override void CaptureMetric<T>(SentryMetric<T> metric) where T
}
catch (Exception e)
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.CallbackError, DataCategory.TraceMetric);
_options.DiagnosticLogger?.LogError(e, "The BeforeSendMetric callback threw an exception. The Metric will be dropped.");
return;
}
}

if (configuredMetric is not null)
if (configuredMetric is null)
{
_batchProcessor.Enqueue(configuredMetric);
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.BeforeSend, DataCategory.TraceMetric);
Comment thread
jamescrosswell marked this conversation as resolved.
_options.DiagnosticLogger?.LogInfo("Metric dropped by BeforeSendMetric callback.");
return;
}

_batchProcessor.Enqueue(configuredMetric);
}

/// <inheritdoc />
Expand Down
11 changes: 9 additions & 2 deletions src/Sentry/Internal/DefaultSentryStructuredLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ private protected override void CaptureLog(SentryLogLevel level, string template
}
catch (FormatException e)
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.Invalid, DataCategory.LogItem);
_options.DiagnosticLogger?.LogError(e, "Template string does not match the provided argument. The Log will be dropped.");
return;
}
Expand Down Expand Up @@ -70,6 +71,7 @@ private protected override void CaptureLog(SentryLogLevel level, string template
}
catch (Exception e)
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.CallbackError, DataCategory.LogItem);
_options.DiagnosticLogger?.LogError(e, "The configureLog callback threw an exception. The Log will be dropped.");
return;
}
Expand All @@ -93,15 +95,20 @@ protected internal override void CaptureLog(SentryLog log)
}
catch (Exception e)
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.CallbackError, DataCategory.LogItem);
_options.DiagnosticLogger?.LogError(e, "The BeforeSendLog callback threw an exception. The Log will be dropped.");
return;
}
}

if (configuredLog is not null)
if (configuredLog is null)
{
_batchProcessor.Enqueue(configuredLog);
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.BeforeSend, DataCategory.LogItem);
Comment thread
jamescrosswell marked this conversation as resolved.
_options.DiagnosticLogger?.LogInfo("Log dropped by BeforeSendLog callback.");
return;
}

_batchProcessor.Enqueue(configuredLog);
}

/// <inheritdoc />
Expand Down
2 changes: 2 additions & 0 deletions src/Sentry/Internal/DiscardReason.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ namespace Sentry.Internal;
{
// See https://develop.sentry.dev/sdk/client-reports/ for list
public static DiscardReason BeforeSend = new("before_send");
public static DiscardReason CallbackError = new("callback_error");
public static DiscardReason BufferOverflow = new("buffer_overflow");
public static DiscardReason CacheOverflow = new("cache_overflow");
public static DiscardReason EventProcessor = new("event_processor");
public static DiscardReason Invalid = new("invalid");
public static DiscardReason NetworkError = new("network_error");
public static DiscardReason QueueOverflow = new("queue_overflow");
public static DiscardReason SendError = new("send_error");
Expand Down
14 changes: 12 additions & 2 deletions src/Sentry/Internal/SentryEventHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ internal static class SentryEventHelper

foreach (var processor in processors)
{
processedEvent = processor.DoProcessEvent(processedEvent, effectiveHint);
try
{
processedEvent = processor.DoProcessEvent(processedEvent, effectiveHint);
}
catch (Exception e)
{
options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.CallbackError, dataCategory);
options.LogError(e, "Event processor {0} threw an exception. The event will be dropped.", processor.GetType().Name);
return null;
}

if (processedEvent == null)
{
options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.EventProcessor, dataCategory);
Expand Down Expand Up @@ -94,7 +104,7 @@ internal static class SentryEventHelper
}
catch (Exception e)
{
options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.BeforeSend, DataCategory.Feedback);
options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.CallbackError, DataCategory.Feedback);
options.LogError(e, "The BeforeSendFeedback callback threw an exception. The feedback will be dropped.");
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
using Sentry.Android.Extensions;
using Sentry.Extensibility;

namespace Sentry.Android.Callbacks;

internal class BeforeBreadcrumbCallback : JavaObject, JavaSdk.SentryOptions.IBeforeBreadcrumbCallback
{
private readonly Func<Breadcrumb, SentryHint, Breadcrumb?> _beforeBreadcrumb;
private readonly SentryOptions _options;

public BeforeBreadcrumbCallback(Func<Breadcrumb, SentryHint, Breadcrumb?> beforeBreadcrumb)
public BeforeBreadcrumbCallback(
Func<Breadcrumb, SentryHint, Breadcrumb?> beforeBreadcrumb,
SentryOptions options)
{
_beforeBreadcrumb = beforeBreadcrumb;
_options = options;
}

public JavaSdk.Breadcrumb? Execute(JavaSdk.Breadcrumb b, JavaSdk.Hint h)
Expand All @@ -18,7 +23,17 @@ public BeforeBreadcrumbCallback(Func<Breadcrumb, SentryHint, Breadcrumb?> before

var breadcrumb = b.ToBreadcrumb();
var hint = h.ToHint();
var result = _beforeBreadcrumb.Invoke(breadcrumb, hint);

Breadcrumb? result;
try
{
result = _beforeBreadcrumb.Invoke(breadcrumb, hint);
}
catch (Exception exception)
{
_options.LogError(exception, "Android BeforeBreadcrumb callback failed.");
return null;
}

if (result == breadcrumb)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Sentry/Platforms/Android/SentrySdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private static void InitSentryAndroidSdk(SentryOptions options)

if (options.BeforeBreadcrumbInternal is { } beforeBreadcrumb)
{
o.BeforeBreadcrumb = new BeforeBreadcrumbCallback(beforeBreadcrumb);
o.BeforeBreadcrumb = new BeforeBreadcrumbCallback(beforeBreadcrumb, options);
}

// These options we have behind feature flags
Expand Down
12 changes: 11 additions & 1 deletion src/Sentry/Platforms/Cocoa/SentrySdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,17 @@ private static void InitSentryCocoaSdk(SentryOptions options)
// See https://github.com/getsentry/sentry-cocoa/issues/2325
var hint = new SentryHint();
var breadcrumb = b.ToBreadcrumb(options.DiagnosticLogger);
var result = beforeBreadcrumb(breadcrumb, hint)?.ToCocoaBreadcrumb();

CocoaSdk.SentryObjCBreadcrumb? result;
try
{
result = beforeBreadcrumb(breadcrumb, hint)?.ToCocoaBreadcrumb();
}
catch (Exception ex)
{
options.LogError(ex, "Cocoa BeforeBreadcrumb callback failed.");
result = null;
}

// Note: Nullable result is allowed but delegate is generated incorrectly
// See https://github.com/xamarin/xamarin-macios/issues/15299#issuecomment-1201863294
Expand Down
15 changes: 12 additions & 3 deletions src/Sentry/Scope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,24 @@ public void AddBreadcrumb(Breadcrumb breadcrumb, SentryHint hint)
{
hint.AddAttachmentsFromScope(this);

if (beforeBreadcrumb(breadcrumb, hint) is { } processedBreadcrumb)
Breadcrumb? processedBreadcrumb;
try
{
breadcrumb = processedBreadcrumb;
processedBreadcrumb = beforeBreadcrumb(breadcrumb, hint);
}
else
catch (Exception e)
{
Options.LogError(e, "BeforeBreadcrumb callback failed.");
return;
}

if (processedBreadcrumb is null)
{
// Callback returned null, which means the breadcrumb should be dropped
return;
}

breadcrumb = processedBreadcrumb;
}

if (Options.MaxBreadcrumbs <= 0)
Expand Down
13 changes: 12 additions & 1 deletion src/Sentry/SentryClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,18 @@ public void CaptureTransaction(SentryTransaction transaction, Scope? scope, Sent
var processedTransaction = transaction;
foreach (var processor in scope.GetAllTransactionProcessors())
{
processedTransaction = processor.DoProcessTransaction(processedTransaction, hint);
try
{
processedTransaction = processor.DoProcessTransaction(processedTransaction, hint);
}
catch (Exception e)
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.CallbackError, DataCategory.Transaction);
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.CallbackError, DataCategory.Span, spanCount);
_options.LogError(e, "Transaction processor {0} threw an exception. The transaction will be dropped.", processor.GetType().Name);
return;
}

if (processedTransaction == null) // Rejected transaction
{
_options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.EventProcessor, DataCategory.Transaction);
Expand Down
Loading
Loading