Skip to content

Improve event debouncing and throtteling #2004

@bitsandfoxes

Description

@bitsandfoxes

Goal

The goal is to provide more granular control over event debouncing. Particularly, for high-frequency events like those from Update() functions. This allows users to preserve quota while keeping error reporting intact.

Current Problem

  1. Events from Update() functions that run every frame can quickly consume error reporting quotas
  2. Current debouncing is not flexible enough for different types of events.
    i.e. There's not debouncing for exceptions
  3. Existing workarounds in BeforeSend (stack trace checking + random sampling) are hacky and might miss important errors

Current Implementation

We're using the following debouncer https://github.com/getsentry/sentry-unity/blob/main/src/Sentry.Unity/TimeDebounceBase.cs

in the Application Logging Integration

if (_options?.EnableLogDebouncing is true)
{
var debounced = logType switch
{
LogType.Error or LogType.Assert => _errorTimeDebounce?.Debounced(),
LogType.Log => _logTimeDebounce?.Debounced(),
LogType.Warning => _warningTimeDebounce?.Debounced(),
_ => true
};
if (debounced is not true)
{
return;
}
}

Proposal

Replace the current solution with a content-based deduplication system using an interface pattern similar to callbacks in the SDK (like BeforeSend, BeforeBreadcrumb, TracesSampler etc.).

The idea is to add an IDebounce to the SentryUnityOptions with a default implementation that can be overwritten by the user.
The default Implementation would take the log message and a couple of stack frames, create a hash and hold a fixed size buffer of those for a set amount of time. The individual variables would not be configurable, users can implement their own solution.
The added benefit is that we would run this before IL2CPP stack trace processing, further minimizing the overhead.

Additional Consideration

The .NET SDK has its own debouncer now (for memory dumps). Can this be reused?

The Godot SDK has event throtteling implemented as part of its logging intgration.

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    No status

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions