Skip to main content

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, TransactionContext};
8use crate::protocol::{Breadcrumb, Event, Log, Metric, OrganizationId};
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
34/// [Documentation on Session Modes](https://develop.sentry.dev/sdk/sessions/#sdk-considerations)
35/// for more information.
36///
37/// **NOTE**: The `release-health` feature (enabled by default) needs to be enabled for this
38/// option to have any effect.
39#[derive(Copy, Clone, Debug, PartialEq, Eq)]
40pub enum SessionMode {
41    /// Long running application session.
42    Application,
43    /// Lots of short per-request sessions.
44    Request,
45}
46
47/// The maximum size of an HTTP request body that the SDK captures.
48///
49/// Only request bodies that parse as JSON or form data are currently captured.
50/// See the Sentry documentation on [attaching request bodies] and [handling sensitive data] for
51/// more information.
52///
53/// [attaching request bodies]: https://develop.sentry.dev/sdk/expected-features/#attaching-request-body-in-server-sdks
54/// [handling sensitive data]: https://develop.sentry.dev/sdk/expected-features/data-handling/#sensitive-data
55#[derive(Clone, Copy, PartialEq)]
56pub enum MaxRequestBodySize {
57    /// Don't capture request body
58    None,
59    /// Capture up to 1000 bytes
60    Small,
61    /// Capture up to 10000 bytes
62    Medium,
63    /// Capture entire body
64    Always,
65    /// Capture up to a specific size
66    Explicit(usize),
67}
68
69impl MaxRequestBodySize {
70    /// Check if the content length is within the size limit.
71    pub fn is_within_size_limit(&self, content_length: usize) -> bool {
72        match self {
73            MaxRequestBodySize::None => false,
74            MaxRequestBodySize::Small => content_length <= 1_000,
75            MaxRequestBodySize::Medium => content_length <= 10_000,
76            MaxRequestBodySize::Always => true,
77            MaxRequestBodySize::Explicit(size) => content_length <= *size,
78        }
79    }
80}
81
82/// Defines how traces should be sampled.
83///
84/// Leaving this at [`Disabled`](Self::Disabled) is distinct from explicitly configuring
85/// [`FixedRate`](Self::FixedRate) with a rate of `0.0`. Both disable local transaction sampling
86/// when there is no parent sampling decision, but an explicit fixed-rate strategy can still honor
87/// an inherited sampling decision.
88#[derive(Clone, Default)]
89#[non_exhaustive]
90pub enum TracesSamplingStrategy {
91    /// Sample the trace at a fixed sample rate. The rate should be between 0.0 and 1.0, inclusive.
92    FixedRate(f32),
93    /// Sample the traces using a [`TracesSampler`] function.
94    Function(Arc<TracesSampler>),
95    /// Disable tracing.
96    #[default]
97    Disabled,
98}
99
100impl fmt::Debug for TracesSamplingStrategy {
101    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102        match self {
103            Self::FixedRate(rate) => f.debug_tuple("FixedRate").field(rate).finish(),
104            Self::Function(callback) => f
105                .debug_tuple("Function")
106                .field(&format_args!("{:p}", Arc::as_ptr(callback)))
107                .finish(),
108            Self::Disabled => f.write_str("Disabled"),
109        }
110    }
111}
112
113/// The sampling strategy for events.
114///
115/// Currently, we only support fixed rates. This defaults to `Self::FixedRate(1.0)`.
116#[derive(Clone, Debug)]
117#[non_exhaustive]
118pub enum EventSamplingStrategy {
119    /// Sample events at a fixed sample rate. The rate should be between 0.0 and 1.0, inclusive.
120    FixedRate(f32),
121}
122
123impl Default for EventSamplingStrategy {
124    fn default() -> Self {
125        Self::FixedRate(1.0)
126    }
127}
128
129/// Configuration settings for the client.
130///
131/// These options are explained in more detail in the general
132/// [sentry documentation](https://docs.sentry.io/error-reporting/configuration/?platform=rust).
133///
134/// # Examples
135///
136/// ```
137/// let _options = sentry::ClientOptions::new().debug(true);
138/// ```
139#[derive(Clone)]
140#[must_use = "ClientOptions must be passed to sentry::init to have any effect"]
141#[non_exhaustive]
142pub struct ClientOptions {
143    // Common options
144    /// The DSN to use.
145    ///
146    /// See [`dsn`](method@ClientOptions::dsn) for details.
147    pub dsn: Option<Dsn>,
148    /// Enables debug mode.
149    ///
150    /// See [`debug`](method@ClientOptions::debug) for details.
151    pub debug: bool,
152    /// The release to be sent with events.
153    ///
154    /// See [`release`](method@ClientOptions::release) for details.
155    pub release: Option<Cow<'static, str>>,
156    /// The environment to be sent with events.
157    ///
158    /// See [`environment`](method@ClientOptions::environment) for details.
159    pub environment: Option<Cow<'static, str>>,
160    /// The sampling strategy for event submission.
161    ///
162    /// This can be set to with [`sample_rate`](method@ClientOptions::sample_rate).
163    pub event_sampling_strategy: EventSamplingStrategy,
164    /// The traces sampling strategy.
165    ///
166    /// This can be set to a fixed rate with
167    /// [`traces_sample_rate`](method@ClientOptions::traces_sample_rate), a function with
168    /// [`traces_sampler`](method@ClientOptions::traces_sampler), or can be left at the default
169    /// disabled value.
170    pub traces_sampling_strategy: TracesSamplingStrategy,
171    /// The organization ID used for trace continuation.
172    ///
173    /// See [`org_id`](method@ClientOptions::org_id) for details.
174    pub org_id: Option<OrganizationId>,
175    /// Enables strict trace continuation.
176    ///
177    /// See [`strict_trace_continuation`](method@ClientOptions::strict_trace_continuation) for
178    /// details.
179    pub strict_trace_continuation: bool,
180    /// Maximum number of breadcrumbs.
181    ///
182    /// See [`max_breadcrumbs`](method@ClientOptions::max_breadcrumbs) for details.
183    pub max_breadcrumbs: usize,
184    /// Attaches stacktraces to messages.
185    ///
186    /// See [`attach_stacktrace`](method@ClientOptions::attach_stacktrace) for details.
187    pub attach_stacktrace: bool,
188    /// Whether to send default PII.
189    ///
190    /// See [`send_default_pii`](method@ClientOptions::send_default_pii) for details.
191    pub send_default_pii: bool,
192    /// The server name to be reported.
193    ///
194    /// See [`server_name`](method@ClientOptions::server_name) for details.
195    pub server_name: Option<Cow<'static, str>>,
196    /// Module prefixes that are always considered "in_app".
197    ///
198    /// See [`in_app_include`](method@ClientOptions::in_app_include) for details.
199    pub in_app_include: Vec<&'static str>,
200    /// Module prefixes that are never "in_app".
201    ///
202    /// See [`in_app_exclude`](method@ClientOptions::in_app_exclude) for details.
203    pub in_app_exclude: Vec<&'static str>,
204    // Integration options
205    /// A list of integrations to enable.
206    ///
207    /// See [`integrations`](method@ClientOptions::integrations) and
208    /// [`add_integration`](method@ClientOptions::add_integration) for details.
209    pub integrations: Vec<Arc<dyn Integration>>,
210    /// Whether to add default integrations.
211    ///
212    /// See [`default_integrations`](method@ClientOptions::default_integrations) for details.
213    pub default_integrations: bool,
214    // Hooks
215    /// Callback that is executed before event sending.
216    ///
217    /// See [`before_send`](method@ClientOptions::before_send) for details.
218    pub before_send: Option<BeforeCallback<Event<'static>>>,
219    /// Callback that is executed for each Breadcrumb being added.
220    ///
221    /// See [`before_breadcrumb`](method@ClientOptions::before_breadcrumb) for details.
222    pub before_breadcrumb: Option<BeforeCallback<Breadcrumb>>,
223    /// Callback that is executed for each Log being added.
224    ///
225    /// See [`before_send_log`](method@ClientOptions::before_send_log) for details.
226    pub before_send_log: Option<BeforeCallback<Log>>,
227    // Transport options
228    /// The transport to use.
229    ///
230    /// See [`transport`](method@ClientOptions::transport) for details.
231    pub transport: Option<Arc<dyn TransportFactory>>,
232    /// An optional HTTP proxy to use.
233    ///
234    /// See [`http_proxy`](method@ClientOptions::http_proxy) for details.
235    pub http_proxy: Option<Cow<'static, str>>,
236    /// An optional HTTPS proxy to use.
237    ///
238    /// See [`https_proxy`](method@ClientOptions::https_proxy) for details.
239    pub https_proxy: Option<Cow<'static, str>>,
240    /// The timeout on client drop for draining events on shutdown.
241    ///
242    /// See [`shutdown_timeout`](method@ClientOptions::shutdown_timeout) for details.
243    pub shutdown_timeout: Duration,
244    /// The maximum size of an HTTP request body to capture.
245    ///
246    /// See [`max_request_body_size`](method@ClientOptions::max_request_body_size) for details.
247    pub max_request_body_size: MaxRequestBodySize,
248    /// Whether captured structured logs should be sent to Sentry.
249    ///
250    /// See [`enable_logs`](method@ClientOptions::enable_logs) for details.
251    pub enable_logs: bool,
252    /// Whether metric capture APIs should capture metrics.
253    ///
254    /// See [`enable_metrics`](method@ClientOptions::enable_metrics) for details.
255    pub enable_metrics: bool,
256    /// Callback that is executed for each [`Metric`] before sending.
257    ///
258    /// See [`before_send_metric`](method@ClientOptions::before_send_metric) for details.
259    pub before_send_metric: Option<BeforeCallback<Metric>>,
260    // Other options not documented in Unified API
261    /// Whether to disable SSL verification.
262    ///
263    /// See [`accept_invalid_certs`](method@ClientOptions::accept_invalid_certs) for details.
264    pub accept_invalid_certs: bool,
265    /// Whether Release Health Session tracking is enabled.
266    ///
267    /// See [`auto_session_tracking`](method@ClientOptions::auto_session_tracking) for details.
268    pub auto_session_tracking: bool,
269    /// Determine how Sessions are being tracked.
270    ///
271    /// See [`session_mode`](method@ClientOptions::session_mode) for details.
272    pub session_mode: SessionMode,
273    /// The user agent that should be reported.
274    ///
275    /// See [`user_agent`](method@ClientOptions::user_agent) for details.
276    pub user_agent: Cow<'static, str>,
277}
278
279impl ClientOptions {
280    /// Creates new Options.
281    #[inline]
282    pub fn new() -> Self {
283        Self::default()
284    }
285
286    /// Sets the [DSN](field@ClientOptions::dsn) to use.
287    ///
288    /// # Panics
289    ///
290    /// Panics if the value fails to parse as a [DSN](`Dsn`).
291    #[inline]
292    pub fn dsn(self, dsn: &str) -> Self {
293        let dsn = Some(dsn.parse().expect("invalid value for DSN"));
294        Self { dsn, ..self }
295    }
296
297    /// Enables or disables [debug mode](field@ClientOptions::debug).
298    ///
299    /// In debug mode debug information is printed to stderr to help you understand what sentry is
300    /// doing. Defaults to `false`.
301    #[inline]
302    pub fn debug(self, debug: bool) -> Self {
303        Self { debug, ..self }
304    }
305
306    /// Sets the [release](field@ClientOptions::release) to be sent with events.
307    #[inline]
308    pub fn release<T>(self, release: T) -> Self
309    where
310        T: Into<Cow<'static, str>>,
311    {
312        let release = Some(release.into());
313        Self { release, ..self }
314    }
315
316    /// Sets the [release](field@ClientOptions::release) to be sent with events if one is provided.
317    ///
318    /// Use this with [`release_name!`](crate::release_name), which returns the release as an
319    /// `Option`.
320    #[inline]
321    pub fn maybe_release<T>(self, release: Option<T>) -> Self
322    where
323        T: Into<Cow<'static, str>>,
324    {
325        match release {
326            Some(release) => self.release(release),
327            None => self,
328        }
329    }
330
331    /// Sets the [environment](field@ClientOptions::environment) to be sent with events.
332    ///
333    /// Defaults to either `"development"` or `"production"` depending on the `debug_assertions`
334    /// cfg-attribute.
335    #[inline]
336    pub fn environment<T>(self, environment: T) -> Self
337    where
338        T: Into<Cow<'static, str>>,
339    {
340        let environment = Some(environment.into());
341        Self {
342            environment,
343            ..self
344        }
345    }
346
347    /// Sets the [event sampling strategy](field@ClientOptions::event_sampling_strategy) to a fixed
348    /// sample rate for event submission.
349    ///
350    /// Must be between `0.0` and `1.0`. Defaults to `1.0`.
351    ///
352    /// # Panics
353    ///
354    /// Panics if the `sample_rate` is outside the allowed range.
355    #[inline]
356    pub fn sample_rate(self, sample_rate: f32) -> Self {
357        if !(0.0..=1.0).contains(&sample_rate) {
358            panic!("Sample rate {sample_rate} is outside the allowed range [0.0, 1.0].")
359        }
360
361        let event_sampling_strategy = EventSamplingStrategy::FixedRate(sample_rate);
362
363        Self {
364            event_sampling_strategy,
365            ..self
366        }
367    }
368
369    /// Sets the [traces sampling strategy](field@ClientOptions::traces_sampling_strategy) to a
370    /// fixed sample rate for tracing transactions.
371    ///
372    /// Must be between `0.0` and `1.0`.
373    ///
374    /// Calling this method stores an explicit fixed-rate traces sampling strategy, even when the
375    /// rate is `0.0`. That is distinct from leaving traces sampling unset, which uses
376    /// [`TracesSamplingStrategy::Disabled`].
377    ///
378    /// # Panics
379    ///
380    /// Panics if the `traces_sample_rate` is outside the allowed range.
381    #[inline]
382    pub fn traces_sample_rate(self, traces_sample_rate: f32) -> Self {
383        if !(0.0..=1.0).contains(&traces_sample_rate) {
384            panic!(
385                "Traces sample rate {traces_sample_rate} is outside the allowed range [0.0, 1.0]."
386            )
387        }
388
389        let traces_sampling_strategy = TracesSamplingStrategy::FixedRate(traces_sample_rate);
390
391        Self {
392            traces_sampling_strategy,
393            ..self
394        }
395    }
396
397    /// Sets the [traces sampling strategy](field@ClientOptions::traces_sampling_strategy) to a
398    /// sampler callback for tracing transactions.
399    ///
400    /// Return a sample rate between `0.0` and `1.0` for the transaction in question. This replaces
401    /// any fixed-rate strategy configured with [`Self::traces_sample_rate`] and is distinct from
402    /// leaving traces sampling unset.
403    #[inline]
404    pub fn traces_sampler<F>(self, traces_sampler: F) -> Self
405    where
406        F: Fn(&TransactionContext) -> f32 + Send + Sync + 'static,
407    {
408        let traces_sampling_strategy =
409            TracesSamplingStrategy::Function(Arc::new(traces_sampler) as Arc<TracesSampler>);
410
411        Self {
412            traces_sampling_strategy,
413            ..self
414        }
415    }
416
417    /// Sets the [organization ID](field@ClientOptions::org_id) used for trace continuation.
418    ///
419    /// By default, we infer the organization ID from the DSN when available. Setting this option
420    /// overrides the DSN-derived organization ID.
421    ///
422    /// This option should be used in local Relay and self-hosted setups, as the organization ID
423    /// cannot be inferred from the DSN in these cases.
424    #[inline]
425    pub fn org_id(self, org_id: OrganizationId) -> Self {
426        let org_id = Some(org_id);
427        Self { org_id, ..self }
428    }
429
430    /// Enables or disables [strict trace continuation](field@ClientOptions::strict_trace_continuation).
431    ///
432    /// Strict trace continuation helps prevent the SDK from continuing traces that originate from
433    /// services instrumented with Sentry by another organization.
434    ///
435    /// By default, the SDK will always continue incoming traces, unless this SDK has an org ID
436    /// embedded in the DSN or explicitly set with [`Self::org_id`] **and** the incoming trace
437    /// includes a different org ID.
438    ///
439    /// When strict trace continuation is enabled, the SDK additionally will not continue traces in
440    /// the case where one of the SDK's org ID or the incoming trace org ID are missing.
441    #[inline]
442    pub fn strict_trace_continuation(self, strict_trace_continuation: bool) -> Self {
443        Self {
444            strict_trace_continuation,
445            ..self
446        }
447    }
448
449    /// Sets the [maximum number of breadcrumbs](field@ClientOptions::max_breadcrumbs).
450    ///
451    /// Defaults to `100`.
452    #[inline]
453    pub fn max_breadcrumbs(self, max_breadcrumbs: usize) -> Self {
454        Self {
455            max_breadcrumbs,
456            ..self
457        }
458    }
459
460    /// Enables or disables [attaching stacktraces](field@ClientOptions::attach_stacktrace) to
461    /// messages.
462    ///
463    /// Defaults to `false`.
464    #[inline]
465    pub fn attach_stacktrace(self, attach_stacktrace: bool) -> Self {
466        Self {
467            attach_stacktrace,
468            ..self
469        }
470    }
471
472    /// Enables or disables sending [default PII](field@ClientOptions::send_default_pii).
473    ///
474    /// This includes information such as potentially sensitive HTTP headers and user IP addresses
475    /// in HTTP server integrations. Defaults to `false`.
476    #[inline]
477    pub fn send_default_pii(self, send_default_pii: bool) -> Self {
478        Self {
479            send_default_pii,
480            ..self
481        }
482    }
483
484    /// Sets the [server name](field@ClientOptions::server_name) to be reported.
485    #[inline]
486    pub fn server_name<T>(self, server_name: T) -> Self
487    where
488        T: Into<Cow<'static, str>>,
489    {
490        let server_name = Some(server_name.into());
491        Self {
492            server_name,
493            ..self
494        }
495    }
496
497    /// Sets [module prefixes](field@ClientOptions::in_app_include) that are always considered
498    /// in-app.
499    #[inline]
500    pub fn in_app_include<I>(self, in_app_include: I) -> Self
501    where
502        I: IntoIterator<Item = &'static str>,
503    {
504        let in_app_include = in_app_include.into_iter().collect();
505        Self {
506            in_app_include,
507            ..self
508        }
509    }
510
511    /// Sets [module prefixes](field@ClientOptions::in_app_exclude) that are never considered
512    /// in-app.
513    #[inline]
514    pub fn in_app_exclude<I>(self, in_app_exclude: I) -> Self
515    where
516        I: IntoIterator<Item = &'static str>,
517    {
518        let in_app_exclude = in_app_exclude.into_iter().collect();
519        Self {
520            in_app_exclude,
521            ..self
522        }
523    }
524
525    /// Sets the [integrations](field@ClientOptions::integrations) to enable, replacing the
526    /// existing list.
527    ///
528    /// See [`sentry::integrations`](integrations/index.html#installing-integrations) for how to
529    /// use this to enable extra integrations. Use
530    /// [`add_integration`](method@ClientOptions::add_integration) to append.
531    #[inline]
532    pub fn integrations<I>(self, integrations: I) -> Self
533    where
534        I: IntoIterator<Item = Arc<dyn Integration>>,
535    {
536        let integrations = integrations.into_iter().collect();
537        Self {
538            integrations,
539            ..self
540        }
541    }
542
543    /// Enables or disables [default integrations](field@ClientOptions::default_integrations).
544    ///
545    /// See [`sentry::integrations`](integrations/index.html#default-integrations) for details.
546    /// Defaults to `true`.
547    #[inline]
548    pub fn default_integrations(self, default_integrations: bool) -> Self {
549        Self {
550            default_integrations,
551            ..self
552        }
553    }
554
555    /// Sets the [callback](field@ClientOptions::before_send) that is executed before event
556    /// sending.
557    #[inline]
558    pub fn before_send<F>(self, before_send: F) -> Self
559    where
560        F: Fn(Event<'static>) -> Option<Event<'static>> + Send + Sync + 'static,
561    {
562        let before_send = Some(Arc::new(before_send) as BeforeCallback<Event<'static>>);
563        Self {
564            before_send,
565            ..self
566        }
567    }
568
569    /// Sets the [callback](field@ClientOptions::before_breadcrumb) that is executed before adding
570    /// each breadcrumb.
571    #[inline]
572    pub fn before_breadcrumb<F>(self, before_breadcrumb: F) -> Self
573    where
574        F: Fn(Breadcrumb) -> Option<Breadcrumb> + Send + Sync + 'static,
575    {
576        let before_breadcrumb = Some(Arc::new(before_breadcrumb) as BeforeCallback<Breadcrumb>);
577        Self {
578            before_breadcrumb,
579            ..self
580        }
581    }
582
583    /// Sets the [callback](field@ClientOptions::before_send_log) that is executed before sending
584    /// each log.
585    #[cfg(feature = "logs")]
586    #[inline]
587    pub fn before_send_log<F>(self, before_send_log: F) -> Self
588    where
589        F: Fn(Log) -> Option<Log> + Send + Sync + 'static,
590    {
591        let before_send_log = Some(Arc::new(before_send_log) as BeforeCallback<Log>);
592        Self {
593            before_send_log,
594            ..self
595        }
596    }
597
598    /// Sets the [callback](field@ClientOptions::before_send_metric) that is executed before
599    /// sending each metric.
600    ///
601    /// This callback can modify a metric or return `None` to drop it.
602    #[cfg(feature = "metrics")]
603    #[inline]
604    pub fn before_send_metric<F>(self, before_send_metric: F) -> Self
605    where
606        F: Fn(Metric) -> Option<Metric> + Send + Sync + 'static,
607    {
608        let before_send_metric = Some(Arc::new(before_send_metric) as BeforeCallback<Metric>);
609        Self {
610            before_send_metric,
611            ..self
612        }
613    }
614
615    /// Sets the [transport](field@ClientOptions::transport) to use.
616    ///
617    /// This is typically either a function taking the client options by reference and returning a
618    /// transport, an `Arc<Transport>`, or the `DefaultTransportFactory`. Types that do not
619    /// implement [`TransportFactory`] use direct field assignment.
620    #[inline]
621    pub fn transport<T: TransportFactory + 'static>(self, transport: T) -> Self {
622        let transport = Some(Arc::new(transport) as Arc<dyn TransportFactory>);
623        Self { transport, ..self }
624    }
625
626    /// Sets the optional [HTTP proxy](field@ClientOptions::http_proxy) to use.
627    ///
628    /// This defaults to the `http_proxy` environment variable.
629    #[inline]
630    pub fn http_proxy<T>(self, http_proxy: T) -> Self
631    where
632        T: Into<Cow<'static, str>>,
633    {
634        let http_proxy = Some(http_proxy.into());
635        Self { http_proxy, ..self }
636    }
637
638    /// Sets the optional [HTTPS proxy](field@ClientOptions::https_proxy) to use.
639    ///
640    /// This defaults to the `HTTPS_PROXY` environment variable, or `http_proxy` if that one
641    /// exists.
642    #[inline]
643    pub fn https_proxy<T>(self, https_proxy: T) -> Self
644    where
645        T: Into<Cow<'static, str>>,
646    {
647        let https_proxy = Some(https_proxy.into());
648        Self {
649            https_proxy,
650            ..self
651        }
652    }
653
654    /// Sets the [shutdown drain timeout](field@ClientOptions::shutdown_timeout).
655    ///
656    /// Defaults to 2 seconds.
657    #[inline]
658    pub fn shutdown_timeout(self, shutdown_timeout: Duration) -> Self {
659        Self {
660            shutdown_timeout,
661            ..self
662        }
663    }
664
665    /// Sets the [maximum request body size](field@ClientOptions::max_request_body_size) to
666    /// capture.
667    ///
668    /// Controls the maximum size of an HTTP request body that can be captured when using HTTP
669    /// server integrations. Needs [`send_default_pii`](method@ClientOptions::send_default_pii) to
670    /// be enabled to have any effect. Defaults to [`MaxRequestBodySize::Medium`].
671    #[inline]
672    pub fn max_request_body_size(self, max_request_body_size: MaxRequestBodySize) -> Self {
673        Self {
674            max_request_body_size,
675            ..self
676        }
677    }
678
679    /// Enables or disables sending [structured logs](field@ClientOptions::enable_logs).
680    ///
681    /// The `logs` feature is required to capture logs. Defaults to `true`.
682    #[inline]
683    pub fn enable_logs(self, enable_logs: bool) -> Self {
684        Self {
685            enable_logs,
686            ..self
687        }
688    }
689
690    /// Enables or disables [metric capture APIs](field@ClientOptions::enable_metrics).
691    ///
692    /// The `metrics` feature is required to capture metrics. Defaults to `true`.
693    #[inline]
694    pub fn enable_metrics(self, enable_metrics: bool) -> Self {
695        Self {
696            enable_metrics,
697            ..self
698        }
699    }
700
701    /// Enables or disables
702    /// [accepting invalid TLS certificates](field@ClientOptions::accept_invalid_certs).
703    ///
704    /// This introduces significant vulnerabilities, and should only be used as a last resort.
705    /// Defaults to `false`.
706    #[inline]
707    pub fn accept_invalid_certs(self, accept_invalid_certs: bool) -> Self {
708        Self {
709            accept_invalid_certs,
710            ..self
711        }
712    }
713
714    /// Enables or disables
715    /// [automatic session tracking](field@ClientOptions::auto_session_tracking).
716    ///
717    /// When enabled, a new "user-mode" session is started at `sentry::init` and persists for the
718    /// application lifetime. Defaults to `false`.
719    #[cfg(feature = "release-health")]
720    #[inline]
721    pub fn auto_session_tracking(self, auto_session_tracking: bool) -> Self {
722        Self {
723            auto_session_tracking,
724            ..self
725        }
726    }
727
728    /// Sets how [sessions are tracked](field@ClientOptions::session_mode).
729    ///
730    /// See [`SessionMode`] for the available modes. Defaults to [`SessionMode::Application`].
731    #[cfg(feature = "release-health")]
732    #[inline]
733    pub fn session_mode(self, session_mode: SessionMode) -> Self {
734        Self {
735            session_mode,
736            ..self
737        }
738    }
739
740    /// Sets the [user agent](field@ClientOptions::user_agent) that should be reported.
741    ///
742    /// Defaults to the SDK user agent.
743    #[inline]
744    pub fn user_agent<T>(self, user_agent: T) -> Self
745    where
746        T: Into<Cow<'static, str>>,
747    {
748        let user_agent = user_agent.into();
749        Self { user_agent, ..self }
750    }
751
752    /// Adds a configured integration to the options.
753    ///
754    /// # Examples
755    ///
756    /// ```
757    /// struct MyIntegration;
758    ///
759    /// impl sentry::Integration for MyIntegration {}
760    ///
761    /// let options = sentry::ClientOptions::new().add_integration(MyIntegration);
762    /// assert_eq!(options.integrations.len(), 1);
763    /// ```
764    #[inline]
765    pub fn add_integration<I: Integration>(mut self, integration: I) -> Self {
766        self.integrations.push(Arc::new(integration));
767        self
768    }
769}
770impl fmt::Debug for ClientOptions {
771    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
772        #[derive(Debug)]
773        struct BeforeSend;
774        let before_send = self.before_send.as_ref().map(|_| BeforeSend);
775        #[derive(Debug)]
776        struct BeforeBreadcrumb;
777        let before_breadcrumb = self.before_breadcrumb.as_ref().map(|_| BeforeBreadcrumb);
778        let before_send_log = {
779            #[derive(Debug)]
780            struct BeforeSendLog;
781            self.before_send_log.as_ref().map(|_| BeforeSendLog)
782        };
783        let before_send_metric = {
784            #[derive(Debug)]
785            struct BeforeSendMetric;
786            self.before_send_metric.as_ref().map(|_| BeforeSendMetric)
787        };
788        #[derive(Debug)]
789        struct TransportFactory;
790
791        let integrations: Vec<_> = self.integrations.iter().map(|i| i.name()).collect();
792
793        let mut debug_struct = f.debug_struct("ClientOptions");
794        debug_struct
795            .field("dsn", &self.dsn)
796            .field("debug", &self.debug)
797            .field("release", &self.release)
798            .field("environment", &self.environment)
799            .field("event_sampling_strategy", &self.event_sampling_strategy)
800            .field("traces_sampling_strategy", &self.traces_sampling_strategy)
801            .field("max_breadcrumbs", &self.max_breadcrumbs)
802            .field("attach_stacktrace", &self.attach_stacktrace)
803            .field("send_default_pii", &self.send_default_pii)
804            .field("server_name", &self.server_name)
805            .field("in_app_include", &self.in_app_include)
806            .field("in_app_exclude", &self.in_app_exclude)
807            .field("integrations", &integrations)
808            .field("default_integrations", &self.default_integrations)
809            .field("before_send", &before_send)
810            .field("before_breadcrumb", &before_breadcrumb)
811            .field("transport", &TransportFactory)
812            .field("http_proxy", &self.http_proxy)
813            .field("https_proxy", &self.https_proxy)
814            .field("shutdown_timeout", &self.shutdown_timeout)
815            .field("accept_invalid_certs", &self.accept_invalid_certs)
816            .field("auto_session_tracking", &self.auto_session_tracking)
817            .field("session_mode", &self.session_mode)
818            .field("enable_logs", &self.enable_logs)
819            .field("before_send_log", &before_send_log)
820            .field("enable_metrics", &self.enable_metrics)
821            .field("before_send_metric", &before_send_metric)
822            .field("org_id", &self.org_id)
823            .field("strict_trace_continuation", &self.strict_trace_continuation)
824            .field("user_agent", &self.user_agent)
825            .finish()
826    }
827}
828
829impl Default for ClientOptions {
830    fn default() -> ClientOptions {
831        ClientOptions {
832            dsn: None,
833            org_id: None,
834            strict_trace_continuation: false,
835            debug: false,
836            release: None,
837            environment: None,
838            event_sampling_strategy: Default::default(),
839            traces_sampling_strategy: Default::default(),
840            max_breadcrumbs: 100,
841            attach_stacktrace: false,
842            send_default_pii: false,
843            server_name: None,
844            in_app_include: vec![],
845            in_app_exclude: vec![],
846            integrations: vec![],
847            default_integrations: true,
848            before_send: None,
849            before_breadcrumb: None,
850            transport: None,
851            http_proxy: None,
852            https_proxy: None,
853            shutdown_timeout: Duration::from_secs(2),
854            accept_invalid_certs: false,
855            auto_session_tracking: false,
856            session_mode: SessionMode::Application,
857            user_agent: Cow::Borrowed(USER_AGENT),
858            max_request_body_size: MaxRequestBodySize::Medium,
859            enable_logs: true,
860            before_send_log: None,
861            enable_metrics: true,
862            before_send_metric: None,
863        }
864    }
865}
866
867impl<T: IntoDsn> From<(T, ClientOptions)> for ClientOptions {
868    fn from((into_dsn, mut opts): (T, ClientOptions)) -> ClientOptions {
869        opts.dsn = into_dsn.into_dsn().expect("invalid value for DSN");
870        opts
871    }
872}
873
874impl<T: IntoDsn> From<T> for ClientOptions {
875    fn from(into_dsn: T) -> ClientOptions {
876        ClientOptions {
877            dsn: into_dsn.into_dsn().expect("invalid value for DSN"),
878            ..ClientOptions::default()
879        }
880    }
881}