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 /// Deprecated. Setting this to `false` only disables automatic log capture by the
249 /// log-capturing integrations (`log` and `tracing` with the `logs` feature); it does not
250 /// disable logs captured manually via [`Hub::capture_log`](crate::Hub::capture_log) and the
251 /// `logger_*` macros. Defaults to `true`.
252 ///
253 /// To stop an integration from sending logs, use its own options to configure what it
254 /// captures.
255 #[deprecated = "logs captured manually are always sent; only automatic capture by integrations respects this option"]
256 pub enable_logs: bool,
257 /// Deprecated no-op. Metrics are always enabled, regardless of this option's value.
258 #[deprecated = "this option is a deprecated no-op"]
259 pub enable_metrics: bool,
260 /// Callback that is executed for each [`Metric`] before sending.
261 ///
262 /// See [`before_send_metric`](method@ClientOptions::before_send_metric) for details.
263 pub before_send_metric: Option<BeforeCallback<Metric>>,
264 // Other options not documented in Unified API
265 /// Whether to disable SSL verification.
266 ///
267 /// See [`accept_invalid_certs`](method@ClientOptions::accept_invalid_certs) for details.
268 pub accept_invalid_certs: bool,
269 /// Whether Release Health Session tracking is enabled.
270 ///
271 /// See [`auto_session_tracking`](method@ClientOptions::auto_session_tracking) for details.
272 pub auto_session_tracking: bool,
273 /// Determine how Sessions are being tracked.
274 ///
275 /// See [`session_mode`](method@ClientOptions::session_mode) for details.
276 pub session_mode: SessionMode,
277 /// The user agent that should be reported.
278 ///
279 /// See [`user_agent`](method@ClientOptions::user_agent) for details.
280 pub user_agent: Cow<'static, str>,
281}
282
283impl ClientOptions {
284 /// Creates new Options.
285 #[inline]
286 pub fn new() -> Self {
287 Self::default()
288 }
289
290 /// Sets the [DSN](field@ClientOptions::dsn) to use.
291 ///
292 /// # Panics
293 ///
294 /// Panics if the value fails to parse as a [DSN](`Dsn`).
295 #[inline]
296 pub fn dsn(self, dsn: &str) -> Self {
297 let dsn = Some(dsn.parse().expect("invalid value for DSN"));
298 Self { dsn, ..self }
299 }
300
301 /// Enables or disables [debug mode](field@ClientOptions::debug).
302 ///
303 /// In debug mode debug information is printed to stderr to help you understand what sentry is
304 /// doing. Defaults to `false`.
305 #[inline]
306 pub fn debug(self, debug: bool) -> Self {
307 Self { debug, ..self }
308 }
309
310 /// Sets the [release](field@ClientOptions::release) to be sent with events.
311 #[inline]
312 pub fn release<T>(self, release: T) -> Self
313 where
314 T: Into<Cow<'static, str>>,
315 {
316 let release = Some(release.into());
317 Self { release, ..self }
318 }
319
320 /// Sets the [release](field@ClientOptions::release) to be sent with events if one is provided.
321 ///
322 /// Use this with [`release_name!`](crate::release_name), which returns the release as an
323 /// `Option`.
324 #[inline]
325 pub fn maybe_release<T>(self, release: Option<T>) -> Self
326 where
327 T: Into<Cow<'static, str>>,
328 {
329 match release {
330 Some(release) => self.release(release),
331 None => self,
332 }
333 }
334
335 /// Sets the [environment](field@ClientOptions::environment) to be sent with events.
336 ///
337 /// Defaults to either `"development"` or `"production"` depending on the `debug_assertions`
338 /// cfg-attribute.
339 #[inline]
340 pub fn environment<T>(self, environment: T) -> Self
341 where
342 T: Into<Cow<'static, str>>,
343 {
344 let environment = Some(environment.into());
345 Self {
346 environment,
347 ..self
348 }
349 }
350
351 /// Sets the [event sampling strategy](field@ClientOptions::event_sampling_strategy) to a fixed
352 /// sample rate for event submission.
353 ///
354 /// Must be between `0.0` and `1.0`. Defaults to `1.0`.
355 ///
356 /// # Panics
357 ///
358 /// Panics if the `sample_rate` is outside the allowed range.
359 #[inline]
360 pub fn sample_rate(self, sample_rate: f32) -> Self {
361 if !(0.0..=1.0).contains(&sample_rate) {
362 panic!("Sample rate {sample_rate} is outside the allowed range [0.0, 1.0].")
363 }
364
365 let event_sampling_strategy = EventSamplingStrategy::FixedRate(sample_rate);
366
367 Self {
368 event_sampling_strategy,
369 ..self
370 }
371 }
372
373 /// Sets the [traces sampling strategy](field@ClientOptions::traces_sampling_strategy) to a
374 /// fixed sample rate for tracing transactions.
375 ///
376 /// Must be between `0.0` and `1.0`.
377 ///
378 /// Calling this method stores an explicit fixed-rate traces sampling strategy, even when the
379 /// rate is `0.0`. That is distinct from leaving traces sampling unset, which uses
380 /// [`TracesSamplingStrategy::Disabled`].
381 ///
382 /// # Panics
383 ///
384 /// Panics if the `traces_sample_rate` is outside the allowed range.
385 #[inline]
386 pub fn traces_sample_rate(self, traces_sample_rate: f32) -> Self {
387 if !(0.0..=1.0).contains(&traces_sample_rate) {
388 panic!(
389 "Traces sample rate {traces_sample_rate} is outside the allowed range [0.0, 1.0]."
390 )
391 }
392
393 let traces_sampling_strategy = TracesSamplingStrategy::FixedRate(traces_sample_rate);
394
395 Self {
396 traces_sampling_strategy,
397 ..self
398 }
399 }
400
401 /// Sets the [traces sampling strategy](field@ClientOptions::traces_sampling_strategy) to a
402 /// sampler callback for tracing transactions.
403 ///
404 /// Return a sample rate between `0.0` and `1.0` for the transaction in question. This replaces
405 /// any fixed-rate strategy configured with [`Self::traces_sample_rate`] and is distinct from
406 /// leaving traces sampling unset.
407 #[inline]
408 pub fn traces_sampler<F>(self, traces_sampler: F) -> Self
409 where
410 F: Fn(&TransactionContext) -> f32 + Send + Sync + 'static,
411 {
412 let traces_sampling_strategy =
413 TracesSamplingStrategy::Function(Arc::new(traces_sampler) as Arc<TracesSampler>);
414
415 Self {
416 traces_sampling_strategy,
417 ..self
418 }
419 }
420
421 /// Sets the [organization ID](field@ClientOptions::org_id) used for trace continuation.
422 ///
423 /// By default, we infer the organization ID from the DSN when available. Setting this option
424 /// overrides the DSN-derived organization ID.
425 ///
426 /// This option should be used in local Relay and self-hosted setups, as the organization ID
427 /// cannot be inferred from the DSN in these cases.
428 #[inline]
429 pub fn org_id(self, org_id: OrganizationId) -> Self {
430 let org_id = Some(org_id);
431 Self { org_id, ..self }
432 }
433
434 /// Enables or disables [strict trace continuation](field@ClientOptions::strict_trace_continuation).
435 ///
436 /// Strict trace continuation helps prevent the SDK from continuing traces that originate from
437 /// services instrumented with Sentry by another organization.
438 ///
439 /// By default, the SDK will always continue incoming traces, unless this SDK has an org ID
440 /// embedded in the DSN or explicitly set with [`Self::org_id`] **and** the incoming trace
441 /// includes a different org ID.
442 ///
443 /// When strict trace continuation is enabled, the SDK additionally will not continue traces in
444 /// the case where one of the SDK's org ID or the incoming trace org ID are missing.
445 #[inline]
446 pub fn strict_trace_continuation(self, strict_trace_continuation: bool) -> Self {
447 Self {
448 strict_trace_continuation,
449 ..self
450 }
451 }
452
453 /// Sets the [maximum number of breadcrumbs](field@ClientOptions::max_breadcrumbs).
454 ///
455 /// Defaults to `100`.
456 #[inline]
457 pub fn max_breadcrumbs(self, max_breadcrumbs: usize) -> Self {
458 Self {
459 max_breadcrumbs,
460 ..self
461 }
462 }
463
464 /// Enables or disables [attaching stacktraces](field@ClientOptions::attach_stacktrace) to
465 /// messages.
466 ///
467 /// Defaults to `false`.
468 #[inline]
469 pub fn attach_stacktrace(self, attach_stacktrace: bool) -> Self {
470 Self {
471 attach_stacktrace,
472 ..self
473 }
474 }
475
476 /// Enables or disables sending [default PII](field@ClientOptions::send_default_pii).
477 ///
478 /// This includes information such as potentially sensitive HTTP headers and user IP addresses
479 /// in HTTP server integrations. Defaults to `false`.
480 #[inline]
481 pub fn send_default_pii(self, send_default_pii: bool) -> Self {
482 Self {
483 send_default_pii,
484 ..self
485 }
486 }
487
488 /// Sets the [server name](field@ClientOptions::server_name) to be reported.
489 #[inline]
490 pub fn server_name<T>(self, server_name: T) -> Self
491 where
492 T: Into<Cow<'static, str>>,
493 {
494 let server_name = Some(server_name.into());
495 Self {
496 server_name,
497 ..self
498 }
499 }
500
501 /// Sets [module prefixes](field@ClientOptions::in_app_include) that are always considered
502 /// in-app.
503 #[inline]
504 pub fn in_app_include<I>(self, in_app_include: I) -> Self
505 where
506 I: IntoIterator<Item = &'static str>,
507 {
508 let in_app_include = in_app_include.into_iter().collect();
509 Self {
510 in_app_include,
511 ..self
512 }
513 }
514
515 /// Sets [module prefixes](field@ClientOptions::in_app_exclude) that are never considered
516 /// in-app.
517 #[inline]
518 pub fn in_app_exclude<I>(self, in_app_exclude: I) -> Self
519 where
520 I: IntoIterator<Item = &'static str>,
521 {
522 let in_app_exclude = in_app_exclude.into_iter().collect();
523 Self {
524 in_app_exclude,
525 ..self
526 }
527 }
528
529 /// Sets the [integrations](field@ClientOptions::integrations) to enable, replacing the
530 /// existing list.
531 ///
532 /// See [`sentry::integrations`](integrations/index.html#installing-integrations) for how to
533 /// use this to enable extra integrations. Use
534 /// [`add_integration`](method@ClientOptions::add_integration) to append.
535 #[inline]
536 pub fn integrations<I>(self, integrations: I) -> Self
537 where
538 I: IntoIterator<Item = Arc<dyn Integration>>,
539 {
540 let integrations = integrations.into_iter().collect();
541 Self {
542 integrations,
543 ..self
544 }
545 }
546
547 /// Enables or disables [default integrations](field@ClientOptions::default_integrations).
548 ///
549 /// See [`sentry::integrations`](integrations/index.html#default-integrations) for details.
550 /// Defaults to `true`.
551 #[inline]
552 pub fn default_integrations(self, default_integrations: bool) -> Self {
553 Self {
554 default_integrations,
555 ..self
556 }
557 }
558
559 /// Sets the [callback](field@ClientOptions::before_send) that is executed before event
560 /// sending.
561 #[inline]
562 pub fn before_send<F>(self, before_send: F) -> Self
563 where
564 F: Fn(Event<'static>) -> Option<Event<'static>> + Send + Sync + 'static,
565 {
566 let before_send = Some(Arc::new(before_send) as BeforeCallback<Event<'static>>);
567 Self {
568 before_send,
569 ..self
570 }
571 }
572
573 /// Sets the [callback](field@ClientOptions::before_breadcrumb) that is executed before adding
574 /// each breadcrumb.
575 #[inline]
576 pub fn before_breadcrumb<F>(self, before_breadcrumb: F) -> Self
577 where
578 F: Fn(Breadcrumb) -> Option<Breadcrumb> + Send + Sync + 'static,
579 {
580 let before_breadcrumb = Some(Arc::new(before_breadcrumb) as BeforeCallback<Breadcrumb>);
581 Self {
582 before_breadcrumb,
583 ..self
584 }
585 }
586
587 /// Sets the [callback](field@ClientOptions::before_send_log) that is executed before sending
588 /// each log.
589 #[cfg(feature = "logs")]
590 #[inline]
591 pub fn before_send_log<F>(self, before_send_log: F) -> Self
592 where
593 F: Fn(Log) -> Option<Log> + Send + Sync + 'static,
594 {
595 let before_send_log = Some(Arc::new(before_send_log) as BeforeCallback<Log>);
596 Self {
597 before_send_log,
598 ..self
599 }
600 }
601
602 /// Sets the [callback](field@ClientOptions::before_send_metric) that is executed before
603 /// sending each metric.
604 ///
605 /// This callback can modify a metric or return `None` to drop it.
606 #[cfg(feature = "metrics")]
607 #[inline]
608 pub fn before_send_metric<F>(self, before_send_metric: F) -> Self
609 where
610 F: Fn(Metric) -> Option<Metric> + Send + Sync + 'static,
611 {
612 let before_send_metric = Some(Arc::new(before_send_metric) as BeforeCallback<Metric>);
613 Self {
614 before_send_metric,
615 ..self
616 }
617 }
618
619 /// Sets the [transport](field@ClientOptions::transport) to use.
620 ///
621 /// This is typically either a function taking the client options by reference and returning a
622 /// transport, an `Arc<Transport>`, or the `DefaultTransportFactory`. Types that do not
623 /// implement [`TransportFactory`] use direct field assignment.
624 #[inline]
625 pub fn transport<T: TransportFactory + 'static>(self, transport: T) -> Self {
626 let transport = Some(Arc::new(transport) as Arc<dyn TransportFactory>);
627 Self { transport, ..self }
628 }
629
630 /// Sets the optional [HTTP proxy](field@ClientOptions::http_proxy) to use.
631 ///
632 /// This defaults to the `http_proxy` environment variable.
633 #[inline]
634 pub fn http_proxy<T>(self, http_proxy: T) -> Self
635 where
636 T: Into<Cow<'static, str>>,
637 {
638 let http_proxy = Some(http_proxy.into());
639 Self { http_proxy, ..self }
640 }
641
642 /// Sets the optional [HTTPS proxy](field@ClientOptions::https_proxy) to use.
643 ///
644 /// This defaults to the `HTTPS_PROXY` environment variable, or `http_proxy` if that one
645 /// exists.
646 #[inline]
647 pub fn https_proxy<T>(self, https_proxy: T) -> Self
648 where
649 T: Into<Cow<'static, str>>,
650 {
651 let https_proxy = Some(https_proxy.into());
652 Self {
653 https_proxy,
654 ..self
655 }
656 }
657
658 /// Sets the [shutdown drain timeout](field@ClientOptions::shutdown_timeout).
659 ///
660 /// Defaults to 2 seconds.
661 #[inline]
662 pub fn shutdown_timeout(self, shutdown_timeout: Duration) -> Self {
663 Self {
664 shutdown_timeout,
665 ..self
666 }
667 }
668
669 /// Sets the [maximum request body size](field@ClientOptions::max_request_body_size) to
670 /// capture.
671 ///
672 /// Controls the maximum size of an HTTP request body that can be captured when using HTTP
673 /// server integrations. Needs [`send_default_pii`](method@ClientOptions::send_default_pii) to
674 /// be enabled to have any effect. Defaults to [`MaxRequestBodySize::Medium`].
675 #[inline]
676 pub fn max_request_body_size(self, max_request_body_size: MaxRequestBodySize) -> Self {
677 Self {
678 max_request_body_size,
679 ..self
680 }
681 }
682
683 /// Deprecated. Setting [`enable_logs`](field@ClientOptions::enable_logs) to `false` only
684 /// disables automatic log capture by the log-capturing integrations (`log` and `tracing`
685 /// with the `logs` feature); it does not disable logs captured manually via
686 /// [`Hub::capture_log`](crate::Hub::capture_log) and the `logger_*` macros.
687 ///
688 /// To stop an integration from sending logs, use its own options to configure what it
689 /// captures. Alternatively, use [`Self::before_send_log`] to filter logs.
690 #[deprecated = "logs captured manually are always sent; only automatic capture by integrations respects this option"]
691 #[inline]
692 pub fn enable_logs(self, enable_logs: bool) -> Self {
693 Self {
694 #[expect(deprecated, reason = "need to set deprecated field")]
695 enable_logs,
696 ..self
697 }
698 }
699
700 /// This function is a no-op, as it sets the deprecated field
701 /// [`enable_metrics`](field@ClientOptions::enable_metrics). Metrics are always enabled.
702 ///
703 /// To stop sending metrics, simply remove any calls to our metrics APIs.
704 #[deprecated = "this function sets a no-op option"]
705 #[inline]
706 pub fn enable_metrics(self, enable_metrics: bool) -> Self {
707 Self {
708 #[expect(deprecated, reason = "need to set deprecated field")]
709 enable_metrics,
710 ..self
711 }
712 }
713
714 /// Enables or disables
715 /// [accepting invalid TLS certificates](field@ClientOptions::accept_invalid_certs).
716 ///
717 /// This introduces significant vulnerabilities, and should only be used as a last resort.
718 /// Defaults to `false`.
719 #[inline]
720 pub fn accept_invalid_certs(self, accept_invalid_certs: bool) -> Self {
721 Self {
722 accept_invalid_certs,
723 ..self
724 }
725 }
726
727 /// Enables or disables
728 /// [automatic session tracking](field@ClientOptions::auto_session_tracking).
729 ///
730 /// When enabled, a new "user-mode" session is started at `sentry::init` and persists for the
731 /// application lifetime. Defaults to `false`.
732 #[cfg(feature = "release-health")]
733 #[inline]
734 pub fn auto_session_tracking(self, auto_session_tracking: bool) -> Self {
735 Self {
736 auto_session_tracking,
737 ..self
738 }
739 }
740
741 /// Sets how [sessions are tracked](field@ClientOptions::session_mode).
742 ///
743 /// See [`SessionMode`] for the available modes. Defaults to [`SessionMode::Application`].
744 #[cfg(feature = "release-health")]
745 #[inline]
746 pub fn session_mode(self, session_mode: SessionMode) -> Self {
747 Self {
748 session_mode,
749 ..self
750 }
751 }
752
753 /// Sets the [user agent](field@ClientOptions::user_agent) that should be reported.
754 ///
755 /// Defaults to the SDK user agent.
756 #[inline]
757 pub fn user_agent<T>(self, user_agent: T) -> Self
758 where
759 T: Into<Cow<'static, str>>,
760 {
761 let user_agent = user_agent.into();
762 Self { user_agent, ..self }
763 }
764
765 /// Adds a configured integration to the options.
766 ///
767 /// # Examples
768 ///
769 /// ```
770 /// struct MyIntegration;
771 ///
772 /// impl sentry::Integration for MyIntegration {}
773 ///
774 /// let options = sentry::ClientOptions::new().add_integration(MyIntegration);
775 /// assert_eq!(options.integrations.len(), 1);
776 /// ```
777 #[inline]
778 pub fn add_integration<I: Integration>(mut self, integration: I) -> Self {
779 self.integrations.push(Arc::new(integration));
780 self
781 }
782}
783impl fmt::Debug for ClientOptions {
784 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
785 #[derive(Debug)]
786 struct BeforeSend;
787 let before_send = self.before_send.as_ref().map(|_| BeforeSend);
788 #[derive(Debug)]
789 struct BeforeBreadcrumb;
790 let before_breadcrumb = self.before_breadcrumb.as_ref().map(|_| BeforeBreadcrumb);
791 let before_send_log = {
792 #[derive(Debug)]
793 struct BeforeSendLog;
794 self.before_send_log.as_ref().map(|_| BeforeSendLog)
795 };
796 let before_send_metric = {
797 #[derive(Debug)]
798 struct BeforeSendMetric;
799 self.before_send_metric.as_ref().map(|_| BeforeSendMetric)
800 };
801 #[derive(Debug)]
802 struct TransportFactory;
803
804 let integrations: Vec<_> = self.integrations.iter().map(|i| i.name()).collect();
805
806 let mut debug_struct = f.debug_struct("ClientOptions");
807 debug_struct
808 .field("dsn", &self.dsn)
809 .field("debug", &self.debug)
810 .field("release", &self.release)
811 .field("environment", &self.environment)
812 .field("event_sampling_strategy", &self.event_sampling_strategy)
813 .field("traces_sampling_strategy", &self.traces_sampling_strategy)
814 .field("max_breadcrumbs", &self.max_breadcrumbs)
815 .field("attach_stacktrace", &self.attach_stacktrace)
816 .field("send_default_pii", &self.send_default_pii)
817 .field("server_name", &self.server_name)
818 .field("in_app_include", &self.in_app_include)
819 .field("in_app_exclude", &self.in_app_exclude)
820 .field("integrations", &integrations)
821 .field("default_integrations", &self.default_integrations)
822 .field("before_send", &before_send)
823 .field("before_breadcrumb", &before_breadcrumb)
824 .field("transport", &TransportFactory)
825 .field("http_proxy", &self.http_proxy)
826 .field("https_proxy", &self.https_proxy)
827 .field("shutdown_timeout", &self.shutdown_timeout)
828 .field("accept_invalid_certs", &self.accept_invalid_certs)
829 .field("auto_session_tracking", &self.auto_session_tracking)
830 .field("session_mode", &self.session_mode)
831 .field(
832 "enable_logs",
833 #[expect(deprecated, reason = "still need to debug-log this field")]
834 &self.enable_logs,
835 )
836 .field("before_send_log", &before_send_log)
837 .field(
838 "enable_metrics",
839 #[expect(deprecated, reason = "still need to debug-log this field")]
840 &self.enable_metrics,
841 )
842 .field("before_send_metric", &before_send_metric)
843 .field("org_id", &self.org_id)
844 .field("strict_trace_continuation", &self.strict_trace_continuation)
845 .field("user_agent", &self.user_agent)
846 .finish()
847 }
848}
849
850impl Default for ClientOptions {
851 fn default() -> ClientOptions {
852 ClientOptions {
853 dsn: None,
854 org_id: None,
855 strict_trace_continuation: false,
856 debug: false,
857 release: None,
858 environment: None,
859 event_sampling_strategy: Default::default(),
860 traces_sampling_strategy: Default::default(),
861 max_breadcrumbs: 100,
862 attach_stacktrace: false,
863 send_default_pii: false,
864 server_name: None,
865 in_app_include: vec![],
866 in_app_exclude: vec![],
867 integrations: vec![],
868 default_integrations: true,
869 before_send: None,
870 before_breadcrumb: None,
871 transport: None,
872 http_proxy: None,
873 https_proxy: None,
874 shutdown_timeout: Duration::from_secs(2),
875 accept_invalid_certs: false,
876 auto_session_tracking: false,
877 session_mode: SessionMode::Application,
878 user_agent: Cow::Borrowed(USER_AGENT),
879 max_request_body_size: MaxRequestBodySize::Medium,
880 #[expect(deprecated, reason = "still need to set deprecated fields")]
881 enable_logs: true,
882 before_send_log: None,
883 #[expect(deprecated, reason = "still need to set deprecated fields")]
884 enable_metrics: true,
885 before_send_metric: None,
886 }
887 }
888}
889
890impl<T: IntoDsn> From<(T, ClientOptions)> for ClientOptions {
891 fn from((into_dsn, mut opts): (T, ClientOptions)) -> ClientOptions {
892 opts.dsn = into_dsn.into_dsn().expect("invalid value for DSN");
893 opts
894 }
895}
896
897impl<T: IntoDsn> From<T> for ClientOptions {
898 fn from(into_dsn: T) -> ClientOptions {
899 ClientOptions {
900 dsn: into_dsn.into_dsn().expect("invalid value for DSN"),
901 ..ClientOptions::default()
902 }
903 }
904}