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}