sentry_core/
clientoptions.rs

1use std::borrow::Cow;
2use std::fmt;
3use std::sync::Arc;
4use std::time::Duration;
5
6use crate::constants::USER_AGENT;
7use crate::performance::TracesSampler;
8use crate::protocol::{Breadcrumb, Event};
9use crate::types::Dsn;
10use crate::{Integration, IntoDsn, TransportFactory};
11
12/// Type alias for before event/breadcrumb handlers.
13pub type BeforeCallback<T> = Arc<dyn Fn(T) -> Option<T> + Send + Sync>;
14
15/// The Session Mode of the SDK.
16///
17/// Depending on the use-case, the SDK can be set to two different session modes:
18///
19/// * **Application Mode Sessions**:
20///   This mode should be used for user-attended programs, which typically have
21///   a single long running session that span the applications' lifetime.
22///
23/// * **Request Mode Sessions**:
24///   This mode is intended for servers that use one session per incoming
25///   request, and thus have a lot of very short lived sessions.
26///
27/// Setting the SDK to *request-mode* sessions means that session durations will
28/// not be tracked, and sessions will be pre-aggregated before being sent upstream.
29/// This applies both to automatic and manually triggered sessions.
30///
31/// **NOTE**: Support for *request-mode* sessions was added in Sentry `21.2`.
32///
33/// See the [Documentation on Session Modes](https://develop.sentry.dev/sdk/sessions/#sdk-considerations)
34/// for more information.
35#[derive(Copy, Clone, Debug, PartialEq, Eq)]
36pub enum SessionMode {
37    /// Long running application session.
38    Application,
39    /// Lots of short per-request sessions.
40    Request,
41}
42
43/// Configuration settings for the client.
44///
45/// These options are explained in more detail in the general
46/// [sentry documentation](https://docs.sentry.io/error-reporting/configuration/?platform=rust).
47///
48/// # Examples
49///
50/// ```
51/// let _options = sentry::ClientOptions {
52///     debug: true,
53///     ..Default::default()
54/// };
55/// ```
56#[derive(Clone)]
57pub struct ClientOptions {
58    // Common options
59    /// The DSN to use.  If not set the client is effectively disabled.
60    pub dsn: Option<Dsn>,
61    /// Enables debug mode.
62    ///
63    /// In debug mode debug information is printed to stderr to help you understand what
64    /// sentry is doing.  When the `log` feature is enabled, Sentry will instead
65    /// log to the `sentry` logger independently of this flag with the `Debug` level.
66    pub debug: bool,
67    /// The release to be sent with events.
68    pub release: Option<Cow<'static, str>>,
69    /// The environment to be sent with events.
70    ///
71    /// Defaults to either `"development"` or `"production"` depending on the
72    /// `debug_assertions` cfg-attribute.
73    pub environment: Option<Cow<'static, str>>,
74    /// The sample rate for event submission. (0.0 - 1.0, defaults to 1.0)
75    pub sample_rate: f32,
76    /// The sample rate for tracing transactions. (0.0 - 1.0, defaults to 0.0)
77    pub traces_sample_rate: f32,
78    /// If given, called with a SamplingContext for each transaction to determine the sampling rate.
79    ///
80    /// Return a sample rate between 0.0 and 1.0 for the transaction in question.
81    /// Takes priority over the `sample_rate`.
82    pub traces_sampler: Option<Arc<TracesSampler>>,
83    /// Maximum number of breadcrumbs. (defaults to 100)
84    pub max_breadcrumbs: usize,
85    /// Attaches stacktraces to messages.
86    pub attach_stacktrace: bool,
87    /// If turned on some default PII informat is attached.
88    pub send_default_pii: bool,
89    /// The server name to be reported.
90    pub server_name: Option<Cow<'static, str>>,
91    /// Module prefixes that are always considered "in_app".
92    pub in_app_include: Vec<&'static str>,
93    /// Module prefixes that are never "in_app".
94    pub in_app_exclude: Vec<&'static str>,
95    // Integration options
96    /// A list of integrations to enable.
97    ///
98    /// See [`sentry::integrations`](integrations/index.html#installing-integrations) for
99    /// how to use this to enable extra integrations.
100    pub integrations: Vec<Arc<dyn Integration>>,
101    /// Whether to add default integrations.
102    ///
103    /// See [`sentry::integrations`](integrations/index.html#default-integrations) for
104    /// details how this works and interacts with manually installed integrations.
105    pub default_integrations: bool,
106    // Hooks
107    /// Callback that is executed before event sending.
108    pub before_send: Option<BeforeCallback<Event<'static>>>,
109    /// Callback that is executed for each Breadcrumb being added.
110    pub before_breadcrumb: Option<BeforeCallback<Breadcrumb>>,
111    // Transport options
112    /// The transport to use.
113    ///
114    /// This is typically either a boxed function taking the client options by
115    /// reference and returning a `Transport`, a boxed `Arc<Transport>` or
116    /// alternatively the `DefaultTransportFactory`.
117    pub transport: Option<Arc<dyn TransportFactory>>,
118    /// An optional HTTP proxy to use.
119    ///
120    /// This will default to the `http_proxy` environment variable.
121    pub http_proxy: Option<Cow<'static, str>>,
122    /// An optional HTTPS proxy to use.
123    ///
124    /// This will default to the `HTTPS_PROXY` environment variable
125    /// or `http_proxy` if that one exists.
126    pub https_proxy: Option<Cow<'static, str>>,
127    /// The timeout on client drop for draining events on shutdown.
128    pub shutdown_timeout: Duration,
129    // Other options not documented in Unified API
130    /// Disable SSL verification.
131    ///
132    /// # Warning
133    ///
134    /// This introduces significant vulnerabilities, and should only be used as a last resort.
135    pub accept_invalid_certs: bool,
136    /// Enable Release Health Session tracking.
137    ///
138    /// When automatic session tracking is enabled, a new "user-mode" session
139    /// is started at the time of `sentry::init`, and will persist for the
140    /// application lifetime.
141    pub auto_session_tracking: bool,
142    /// Determine how Sessions are being tracked.
143    pub session_mode: SessionMode,
144    /// Border frames which indicate a border from a backtrace to
145    /// useless internals. Some are automatically included.
146    pub extra_border_frames: Vec<&'static str>,
147    /// Automatically trim backtraces of junk before sending. (defaults to true)
148    pub trim_backtraces: bool,
149    /// The user agent that should be reported.
150    pub user_agent: Cow<'static, str>,
151}
152
153impl ClientOptions {
154    /// Creates new Options.
155    pub fn new() -> Self {
156        Self::default()
157    }
158
159    /// Adds a configured integration to the options.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// struct MyIntegration;
165    ///
166    /// impl sentry::Integration for MyIntegration {}
167    ///
168    /// let options = sentry::ClientOptions::new().add_integration(MyIntegration);
169    /// assert_eq!(options.integrations.len(), 1);
170    /// ```
171    #[must_use]
172    pub fn add_integration<I: Integration>(mut self, integration: I) -> Self {
173        self.integrations.push(Arc::new(integration));
174        self
175    }
176}
177
178impl fmt::Debug for ClientOptions {
179    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180        #[derive(Debug)]
181        struct BeforeSend;
182        let before_send = self.before_send.as_ref().map(|_| BeforeSend);
183        #[derive(Debug)]
184        struct BeforeBreadcrumb;
185        let before_breadcrumb = self.before_breadcrumb.as_ref().map(|_| BeforeBreadcrumb);
186        #[derive(Debug)]
187        struct TransportFactory;
188
189        let integrations: Vec<_> = self.integrations.iter().map(|i| i.name()).collect();
190
191        f.debug_struct("ClientOptions")
192            .field("dsn", &self.dsn)
193            .field("debug", &self.debug)
194            .field("release", &self.release)
195            .field("environment", &self.environment)
196            .field("sample_rate", &self.sample_rate)
197            .field("traces_sample_rate", &self.traces_sample_rate)
198            .field(
199                "traces_sampler",
200                &self
201                    .traces_sampler
202                    .as_ref()
203                    .map(|arc| std::ptr::addr_of!(**arc)),
204            )
205            .field("max_breadcrumbs", &self.max_breadcrumbs)
206            .field("attach_stacktrace", &self.attach_stacktrace)
207            .field("send_default_pii", &self.send_default_pii)
208            .field("server_name", &self.server_name)
209            .field("in_app_include", &self.in_app_include)
210            .field("in_app_exclude", &self.in_app_exclude)
211            .field("integrations", &integrations)
212            .field("default_integrations", &self.default_integrations)
213            .field("before_send", &before_send)
214            .field("before_breadcrumb", &before_breadcrumb)
215            .field("transport", &TransportFactory)
216            .field("http_proxy", &self.http_proxy)
217            .field("https_proxy", &self.https_proxy)
218            .field("shutdown_timeout", &self.shutdown_timeout)
219            .field("accept_invalid_certs", &self.accept_invalid_certs)
220            .field("auto_session_tracking", &self.auto_session_tracking)
221            .field("session_mode", &self.session_mode)
222            .field("extra_border_frames", &self.extra_border_frames)
223            .field("trim_backtraces", &self.trim_backtraces)
224            .field("user_agent", &self.user_agent)
225            .finish()
226    }
227}
228
229impl Default for ClientOptions {
230    fn default() -> ClientOptions {
231        ClientOptions {
232            dsn: None,
233            debug: false,
234            release: None,
235            environment: None,
236            sample_rate: 1.0,
237            traces_sample_rate: 0.0,
238            traces_sampler: None,
239            max_breadcrumbs: 100,
240            attach_stacktrace: false,
241            send_default_pii: false,
242            server_name: None,
243            in_app_include: vec![],
244            in_app_exclude: vec![],
245            integrations: vec![],
246            default_integrations: true,
247            before_send: None,
248            before_breadcrumb: None,
249            transport: None,
250            http_proxy: None,
251            https_proxy: None,
252            shutdown_timeout: Duration::from_secs(2),
253            accept_invalid_certs: false,
254            auto_session_tracking: false,
255            session_mode: SessionMode::Application,
256            extra_border_frames: vec![],
257            trim_backtraces: true,
258            user_agent: Cow::Borrowed(USER_AGENT),
259        }
260    }
261}
262
263impl<T: IntoDsn> From<(T, ClientOptions)> for ClientOptions {
264    fn from((into_dsn, mut opts): (T, ClientOptions)) -> ClientOptions {
265        opts.dsn = into_dsn.into_dsn().expect("invalid value for DSN");
266        opts
267    }
268}
269
270impl<T: IntoDsn> From<T> for ClientOptions {
271    fn from(into_dsn: T) -> ClientOptions {
272        ClientOptions {
273            dsn: into_dsn.into_dsn().expect("invalid value for DSN"),
274            ..ClientOptions::default()
275        }
276    }
277}