Skip to content
Open
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 0.49.2
- Added `override_sampling_rate` to `ClientOptions` to allow user defined function to override sampling rate when capturing an event. ([#1128](https://github.com/getsentry/sentry-rust/pull/1128)).

## 0.49.1

### Fixes
Expand Down
10 changes: 8 additions & 2 deletions sentry-core/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,14 @@ impl Client {
scope.update_session_from_event(&event);
}

let sample_rate = event_sample_rate(&self.options.event_sampling_strategy);
if !self.sample_should_send(sample_rate) {
let sampling_rate = self
.options()
.override_sampling_rate
.as_ref()
.and_then(|f| f(&event))
.unwrap_or_else(|| event_sample_rate(&self.options.event_sampling_strategy));

if !self.sample_should_send(sampling_rate) {
self.record_lost_event(ClientReportReason::SampleRate);
None
Comment on lines +403 to 409

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The override_sampling_rate callback lacks validation for NaN values, causing sample_should_send to always return false and silently drop all events.
Severity: MEDIUM

Suggested Fix

Validate the f32 value returned from the override_sampling_rate callback. One option is to panic if the value is invalid (e.g., NaN, not in the [0.0, 1.0] range), which would be consistent with other sampling rate setters like sample_rate(). Alternatively, clamp invalid values to a safe default (like 0.0) and document the behavior.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: sentry-core/src/client/mod.rs#L403-L409

Potential issue: The `override_sampling_rate` callback does not validate the `f32` value
it returns. If a user's callback returns a `NaN` value (e.g., through a division by
zero), this value is passed to the `sample_should_send` function. Due to IEEE 754
floating-point semantics, all comparisons with `NaN` (`>= 1.0`, `<= 0.0`, and `< rate`)
evaluate to `false`. This causes `sample_should_send` to always return `false`,
resulting in all events being silently dropped. This behavior is inconsistent with other
sampling rate setters in the SDK which panic on invalid values.

Did we get this right? 👍 / 👎 to inform future reviews.

} else {
Expand Down
19 changes: 19 additions & 0 deletions sentry-core/src/clientoptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ use crate::{Integration, IntoDsn, TransportFactory};
/// Type alias for before event/breadcrumb handlers.
pub type BeforeCallback<T> = Arc<dyn Fn(T) -> Option<T> + Send + Sync>;

/// Type alias for override sample rate callback.
pub type OverrideSamplingRateCallback = Arc<dyn Fn(&Event<'static>) -> Option<f32> + Send + Sync>;

/// The Session Mode of the SDK.
///
/// Depending on the use-case, the SDK can be set to two different session modes:
Expand Down Expand Up @@ -220,6 +223,8 @@ pub struct ClientOptions {
///
/// See [`before_breadcrumb`](method@ClientOptions::before_breadcrumb) for details.
pub before_breadcrumb: Option<BeforeCallback<Breadcrumb>>,
/// Callback allowing for setting sampling rate based on user defined function.
pub override_sampling_rate: Option<OverrideSamplingRateCallback>,
Comment thread
cursor[bot] marked this conversation as resolved.
/// Callback that is executed for each Log being added.
///
/// See [`before_send_log`](method@ClientOptions::before_send_log) for details.
Expand Down Expand Up @@ -580,6 +585,19 @@ impl ClientOptions {
}
}

/// Sets the [callback](field@ClientOptions::override_sampling_rate) that is used to override the
/// sampling rate.
#[inline]
pub fn override_sampling_rate(
self,
override_func: impl Fn(&Event<'static>) -> Option<f32> + Send + Sync + 'static,
) -> Self {
Self {
override_sampling_rate: Some(Arc::new(override_func)),
..self
}
}

/// Sets the [callback](field@ClientOptions::before_send_log) that is executed before sending
/// each log.
#[cfg(feature = "logs")]
Expand Down Expand Up @@ -860,6 +878,7 @@ impl Default for ClientOptions {
before_send_log: None,
enable_metrics: true,
before_send_metric: None,
override_sampling_rate: None,
}
}
}
Expand Down