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}