1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
//! Sampling logic for performing sampling decisions of incoming events.
//!
//! In order to allow Sentry to offer performance at scale, Relay extracts key `metrics` from all
//! transactions, but only forwards a random sample of raw transaction payloads to the upstream.
//! What exact percentage is sampled is determined by `dynamic sampling rules`, and depends on the
//! project, the environment, the transaction name, etc.
//!
//! In order to determine the sample rate, Relay uses a [`SamplingConfig`] which contains a set of
//! [`SamplingRule`](crate::config::SamplingRule)s that are matched against incoming data.
//!
//! # Types of Sampling
//!
//! There are two main types of dynamic sampling:
//!
//! 1. **Trace sampling** ensures that either all transactions of a trace are sampled or none. Rules
//! have access to information in the [`DynamicSamplingContext`].
//! 2. **Transaction sampling** does not guarantee complete traces and instead applies to individual
//! transactions. Rules have access to the full data in transaction events.
//!
//! # Components
//!
//! The sampling system implemented in Relay is composed of the following components:
//!
//! - [`DynamicSamplingContext`]: a container for information associated with the trace.
//! - [`SamplingRule`](crate::config::SamplingRule): a rule that is matched against incoming data.
//! It specifies a condition that acts as predicate on the incoming payload.
//! - [`SamplingMatch`](crate::evaluation::SamplingMatch): the result of the matching of one or more
//! rules.
//!
//! # How It Works
//!
//! - The incoming data is received by Relay.
//! - Relay resolves the [`SamplingConfig`] of the project to which the incoming data belongs.
//! Additionally, it tries to resolve the configuration of the project that started the trace, the
//! so-called "root project".
//! - The two [`SamplingConfig`]s are merged together and dynamic sampling evaluates a result. The
//! algorithm goes over each rule and compute either a factor or sample rate based on the
//! value of the rule.
//! - The [`SamplingMatch`](crate::evaluation::SamplingMatch) is finally returned containing the
//! final `sample_rate` and some additional data that will be used in `relay_server` to perform
//! the sampling decision.
//!
//! # Determinism
//!
//! The concept of determinism is a core concept for dynamic sampling. Deterministic sampling
//! decisions allow to:
//!
//! - Run dynamic sampling repeatedly over a **chain of Relays** (e.g., we don't want to drop an
//! event that was retained by a previous Relay and vice-versa).
//! - Run dynamic sampling independently on **transactions of the same trace** (e.g., we want to be
//! able to sample all the transactions of the same trace, even though some exceptions apply).
//!
//! In order to perform deterministic sampling, Relay uses teh trace ID or event ID as the seed for
//! the random number generator.
//!
//! # Examples
//!
//! ## [`SamplingConfig`]
//!
//! ```json
#![doc = include_str!("../tests/fixtures/sampling_config.json")]
//! ```
//!
//! ## [`DynamicSamplingContext`]
//!
//! ```json
#![doc = include_str!("../tests/fixtures/dynamic_sampling_context.json")]
//! ```
#![doc(
html_logo_url = "https://raw.githubusercontent.com/getsentry/relay/master/artwork/relay-icon.png",
html_favicon_url = "https://raw.githubusercontent.com/getsentry/relay/master/artwork/relay-icon.png"
)]
#![warn(missing_docs)]
pub mod config;
pub mod dsc;
pub mod evaluation;
#[cfg(feature = "redis")]
mod redis_sampling;
pub use config::SamplingConfig;
pub use dsc::DynamicSamplingContext;