ckb_sentry/
defaults.rs

1#![cfg_attr(feature = "error-chain", allow(deprecated))]
2#![cfg_attr(feature = "failure", allow(deprecated))]
3
4use std::env;
5use std::{borrow::Cow, sync::Arc};
6
7use crate::transports::DefaultTransportFactory;
8use crate::types::Dsn;
9use crate::{ClientOptions, Integration};
10
11/// Apply default client options.
12///
13/// Extends the given `ClientOptions` with default options such as a default
14/// transport, a set of default integrations if not requested otherwise, and
15/// also sets the `dsn`, `release`, `environment`, and proxy settings based on
16/// environment variables.
17///
18/// When the `default_integrations` option is set to `true` (by default), the
19/// following integrations will be added *before* any manually defined
20/// integrations, depending on enabled feature flags:
21///
22/// 1. [`AttachStacktraceIntegration`] (`feature = "backtrace"`)
23/// 2. [`DebugImagesIntegration`] (`feature = "debug-images"`)
24/// 3. [`ErrorChainIntegration`] (`feature = "error-chain"`)
25/// 4. [`ContextIntegration`] (`feature = "contexts"`)
26/// 5. [`FailureIntegration`] (`feature = "failure"`)
27/// 6. [`PanicIntegration`] (`feature = "panic"`)
28/// 7. [`ProcessStacktraceIntegration`] (`feature = "backtrace"`)
29///
30/// Some integrations can be used multiple times, however, the
31/// [`PanicIntegration`] can not, and it will not pick up custom panic
32/// extractors when it is defined multiple times.
33///
34/// # Examples
35/// ```
36/// use ckb_sentry as sentry;
37///
38/// std::env::set_var("SENTRY_RELEASE", "release-from-env");
39///
40/// let options = sentry::ClientOptions::default();
41/// assert_eq!(options.release, None);
42/// assert!(options.transport.is_none());
43///
44/// let options = sentry::apply_defaults(options);
45/// assert_eq!(options.release, Some("release-from-env".into()));
46/// assert!(options.transport.is_some());
47/// ```
48///
49/// [`AttachStacktraceIntegration`]: integrations/backtrace/struct.AttachStacktraceIntegration.html
50/// [`DebugImagesIntegration`]: integrations/debug_images/struct.DebugImagesIntegration.html
51/// [`ErrorChainIntegration`]: integrations/error_chain/struct.ErrorChainIntegration.html
52/// [`ContextIntegration`]: integrations/contexts/struct.ContextIntegration.html
53/// [`FailureIntegration`]: integrations/failure/struct.FailureIntegration.html
54/// [`PanicIntegration`]: integrations/panic/struct.PanicIntegration.html
55/// [`ProcessStacktraceIntegration`]: integrations/backtrace/struct.ProcessStacktraceIntegration.html
56pub fn apply_defaults(mut opts: ClientOptions) -> ClientOptions {
57    if opts.transport.is_none() {
58        opts.transport = Some(Arc::new(DefaultTransportFactory));
59    }
60    if opts.default_integrations {
61        // default integrations need to be ordered *before* custom integrations,
62        // since they also process events in order
63        let mut integrations: Vec<Arc<dyn Integration>> = vec![];
64        #[cfg(feature = "backtrace")]
65        {
66            integrations.push(Arc::new(
67                sentry_backtrace::AttachStacktraceIntegration::default(),
68            ));
69        }
70        #[cfg(feature = "debug-images")]
71        {
72            integrations.push(Arc::new(
73                sentry_debug_images::DebugImagesIntegration::default(),
74            ))
75        }
76        #[cfg(feature = "error-chain")]
77        {
78            integrations.push(Arc::new(
79                sentry_error_chain::ErrorChainIntegration::default(),
80            ))
81        }
82        #[cfg(feature = "contexts")]
83        {
84            integrations.push(Arc::new(sentry_contexts::ContextIntegration::default()));
85        }
86        #[cfg(feature = "failure")]
87        {
88            integrations.push(Arc::new(sentry_failure::FailureIntegration::default()));
89        }
90        #[cfg(feature = "panic")]
91        {
92            #[allow(unused_mut)]
93            let mut integration = sentry_panic::PanicIntegration::default();
94            #[cfg(feature = "failure")]
95            {
96                integration = integration.add_extractor(sentry_failure::panic_extractor);
97            }
98            integrations.push(Arc::new(integration));
99        }
100        #[cfg(feature = "backtrace")]
101        {
102            integrations.push(Arc::new(
103                sentry_backtrace::ProcessStacktraceIntegration::default(),
104            ));
105        }
106        integrations.extend(opts.integrations.into_iter());
107        opts.integrations = integrations;
108    }
109    if opts.dsn.is_none() {
110        opts.dsn = env::var("SENTRY_DSN")
111            .ok()
112            .and_then(|dsn| dsn.parse::<Dsn>().ok());
113    }
114    if opts.release.is_none() {
115        opts.release = env::var("SENTRY_RELEASE").ok().map(Cow::Owned);
116    }
117    if opts.environment.is_none() {
118        opts.environment = env::var("SENTRY_ENVIRONMENT")
119            .ok()
120            .map(Cow::Owned)
121            .or_else(|| {
122                Some(Cow::Borrowed(if cfg!(debug_assertions) {
123                    "debug"
124                } else {
125                    "release"
126                }))
127            });
128    }
129    if opts.http_proxy.is_none() {
130        opts.http_proxy = std::env::var("HTTP_PROXY")
131            .ok()
132            .map(Cow::Owned)
133            .or_else(|| std::env::var("http_proxy").ok().map(Cow::Owned));
134    }
135    if opts.https_proxy.is_none() {
136        opts.https_proxy = std::env::var("HTTPS_PROXY")
137            .ok()
138            .map(Cow::Owned)
139            .or_else(|| std::env::var("https_proxy").ok().map(Cow::Owned))
140            .or_else(|| opts.http_proxy.clone());
141    }
142    opts
143}