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;
8use crate::protocol::{Breadcrumb, Event};
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 [Documentation on Session Modes](https://develop.sentry.dev/sdk/sessions/#sdk-considerations)
34/// for more information.
35///
36/// **NOTE**: The `release-health` feature (enabled by default) needs to be enabled for this option to have
37/// any effect.
38#[derive(Copy, Clone, Debug, PartialEq, Eq)]
39pub enum SessionMode {
40 /// Long running application session.
41 Application,
42 /// Lots of short per-request sessions.
43 Request,
44}
45
46/// The maximum size of an HTTP request body that the SDK captures.
47///
48/// Only request bodies that parse as JSON or form data are currently captured.
49/// See the [Documentation on attaching request body](https://develop.sentry.dev/sdk/expected-features/#attaching-request-body-in-server-sdks)
50/// and the [Documentation on handling sensitive data](https://develop.sentry.dev/sdk/expected-features/data-handling/#sensitive-data)
51/// for more information.
52#[derive(Clone, Copy, PartialEq)]
53pub enum MaxRequestBodySize {
54 /// Don't capture request body
55 None,
56 /// Capture up to 1000 bytes
57 Small,
58 /// Capture up to 10000 bytes
59 Medium,
60 /// Capture entire body
61 Always,
62 /// Capture up to a specific size
63 Explicit(usize),
64}
65
66impl MaxRequestBodySize {
67 /// Check if the content length is within the size limit.
68 pub fn is_within_size_limit(&self, content_length: usize) -> bool {
69 match self {
70 MaxRequestBodySize::None => false,
71 MaxRequestBodySize::Small => content_length <= 1_000,
72 MaxRequestBodySize::Medium => content_length <= 10_000,
73 MaxRequestBodySize::Always => true,
74 MaxRequestBodySize::Explicit(size) => content_length <= *size,
75 }
76 }
77}
78
79/// Configuration settings for the client.
80///
81/// These options are explained in more detail in the general
82/// [sentry documentation](https://docs.sentry.io/error-reporting/configuration/?platform=rust).
83///
84/// # Examples
85///
86/// ```
87/// let _options = sentry::ClientOptions {
88/// debug: true,
89/// ..Default::default()
90/// };
91/// ```
92#[derive(Clone)]
93pub struct ClientOptions {
94 // Common options
95 /// The DSN to use. If not set the client is effectively disabled.
96 pub dsn: Option<Dsn>,
97 /// Enables debug mode.
98 ///
99 /// In debug mode debug information is printed to stderr to help you understand what
100 /// sentry is doing. When the `log` feature is enabled, Sentry will instead
101 /// log to the `sentry` logger independently of this flag with the `Debug` level.
102 pub debug: bool,
103 /// The release to be sent with events.
104 pub release: Option<Cow<'static, str>>,
105 /// The environment to be sent with events.
106 ///
107 /// Defaults to either `"development"` or `"production"` depending on the
108 /// `debug_assertions` cfg-attribute.
109 pub environment: Option<Cow<'static, str>>,
110 /// The sample rate for event submission. (0.0 - 1.0, defaults to 1.0)
111 pub sample_rate: f32,
112 /// The sample rate for tracing transactions. (0.0 - 1.0, defaults to 0.0)
113 pub traces_sample_rate: f32,
114 /// If given, called with a SamplingContext for each transaction to determine the sampling rate.
115 ///
116 /// Return a sample rate between 0.0 and 1.0 for the transaction in question.
117 /// Takes priority over the `sample_rate`.
118 pub traces_sampler: Option<Arc<TracesSampler>>,
119 /// Maximum number of breadcrumbs. (defaults to 100)
120 pub max_breadcrumbs: usize,
121 /// Attaches stacktraces to messages.
122 pub attach_stacktrace: bool,
123 /// If turned on, some information that can be considered PII is captured, such as potentially sensitive HTTP headers and user IP address in HTTP server integrations.
124 pub send_default_pii: bool,
125 /// The server name to be reported.
126 pub server_name: Option<Cow<'static, str>>,
127 /// Module prefixes that are always considered "in_app".
128 pub in_app_include: Vec<&'static str>,
129 /// Module prefixes that are never "in_app".
130 pub in_app_exclude: Vec<&'static str>,
131 // Integration options
132 /// A list of integrations to enable.
133 ///
134 /// See [`sentry::integrations`](integrations/index.html#installing-integrations) for
135 /// how to use this to enable extra integrations.
136 pub integrations: Vec<Arc<dyn Integration>>,
137 /// Whether to add default integrations.
138 ///
139 /// See [`sentry::integrations`](integrations/index.html#default-integrations) for
140 /// details how this works and interacts with manually installed integrations.
141 pub default_integrations: bool,
142 // Hooks
143 /// Callback that is executed before event sending.
144 pub before_send: Option<BeforeCallback<Event<'static>>>,
145 /// Callback that is executed for each Breadcrumb being added.
146 pub before_breadcrumb: Option<BeforeCallback<Breadcrumb>>,
147 // Transport options
148 /// The transport to use.
149 ///
150 /// This is typically either a boxed function taking the client options by
151 /// reference and returning a `Transport`, a boxed `Arc<Transport>` or
152 /// alternatively the `DefaultTransportFactory`.
153 pub transport: Option<Arc<dyn TransportFactory>>,
154 /// An optional HTTP proxy to use.
155 ///
156 /// This will default to the `http_proxy` environment variable.
157 pub http_proxy: Option<Cow<'static, str>>,
158 /// An optional HTTPS proxy to use.
159 ///
160 /// This will default to the `HTTPS_PROXY` environment variable
161 /// or `http_proxy` if that one exists.
162 pub https_proxy: Option<Cow<'static, str>>,
163 /// The timeout on client drop for draining events on shutdown.
164 pub shutdown_timeout: Duration,
165 // Other options not documented in Unified API
166 /// Disable SSL verification.
167 ///
168 /// # Warning
169 ///
170 /// This introduces significant vulnerabilities, and should only be used as a last resort.
171 pub accept_invalid_certs: bool,
172 /// Enable Release Health Session tracking.
173 ///
174 /// When automatic session tracking is enabled, a new "user-mode" session
175 /// is started at the time of `sentry::init`, and will persist for the
176 /// application lifetime.
177 #[cfg(feature = "release-health")]
178 pub auto_session_tracking: bool,
179 /// Determine how Sessions are being tracked.
180 #[cfg(feature = "release-health")]
181 pub session_mode: SessionMode,
182 /// Border frames which indicate a border from a backtrace to
183 /// useless internals. Some are automatically included.
184 pub extra_border_frames: Vec<&'static str>,
185 /// Automatically trim backtraces of junk before sending. (defaults to true)
186 pub trim_backtraces: bool,
187 /// The user agent that should be reported.
188 pub user_agent: Cow<'static, str>,
189 /// Controls how much of request bodies are captured
190 pub max_request_body_size: MaxRequestBodySize,
191}
192
193impl ClientOptions {
194 /// Creates new Options.
195 pub fn new() -> Self {
196 Self::default()
197 }
198
199 /// Adds a configured integration to the options.
200 ///
201 /// # Examples
202 ///
203 /// ```
204 /// struct MyIntegration;
205 ///
206 /// impl sentry::Integration for MyIntegration {}
207 ///
208 /// let options = sentry::ClientOptions::new().add_integration(MyIntegration);
209 /// assert_eq!(options.integrations.len(), 1);
210 /// ```
211 #[must_use]
212 pub fn add_integration<I: Integration>(mut self, integration: I) -> Self {
213 self.integrations.push(Arc::new(integration));
214 self
215 }
216}
217
218impl fmt::Debug for ClientOptions {
219 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
220 #[derive(Debug)]
221 struct BeforeSend;
222 let before_send = self.before_send.as_ref().map(|_| BeforeSend);
223 #[derive(Debug)]
224 struct BeforeBreadcrumb;
225 let before_breadcrumb = self.before_breadcrumb.as_ref().map(|_| BeforeBreadcrumb);
226 #[derive(Debug)]
227 struct TransportFactory;
228
229 let integrations: Vec<_> = self.integrations.iter().map(|i| i.name()).collect();
230
231 let mut debug_struct = f.debug_struct("ClientOptions");
232 debug_struct
233 .field("dsn", &self.dsn)
234 .field("debug", &self.debug)
235 .field("release", &self.release)
236 .field("environment", &self.environment)
237 .field("sample_rate", &self.sample_rate)
238 .field("traces_sample_rate", &self.traces_sample_rate)
239 .field(
240 "traces_sampler",
241 &self
242 .traces_sampler
243 .as_ref()
244 .map(|arc| std::ptr::addr_of!(**arc)),
245 )
246 .field("max_breadcrumbs", &self.max_breadcrumbs)
247 .field("attach_stacktrace", &self.attach_stacktrace)
248 .field("send_default_pii", &self.send_default_pii)
249 .field("server_name", &self.server_name)
250 .field("in_app_include", &self.in_app_include)
251 .field("in_app_exclude", &self.in_app_exclude)
252 .field("integrations", &integrations)
253 .field("default_integrations", &self.default_integrations)
254 .field("before_send", &before_send)
255 .field("before_breadcrumb", &before_breadcrumb)
256 .field("transport", &TransportFactory)
257 .field("http_proxy", &self.http_proxy)
258 .field("https_proxy", &self.https_proxy)
259 .field("shutdown_timeout", &self.shutdown_timeout)
260 .field("accept_invalid_certs", &self.accept_invalid_certs);
261
262 #[cfg(feature = "release-health")]
263 debug_struct
264 .field("auto_session_tracking", &self.auto_session_tracking)
265 .field("session_mode", &self.session_mode);
266
267 debug_struct
268 .field("extra_border_frames", &self.extra_border_frames)
269 .field("trim_backtraces", &self.trim_backtraces)
270 .field("user_agent", &self.user_agent)
271 .finish()
272 }
273}
274
275impl Default for ClientOptions {
276 fn default() -> ClientOptions {
277 ClientOptions {
278 dsn: None,
279 debug: false,
280 release: None,
281 environment: None,
282 sample_rate: 1.0,
283 traces_sample_rate: 0.0,
284 traces_sampler: None,
285 max_breadcrumbs: 100,
286 attach_stacktrace: false,
287 send_default_pii: false,
288 server_name: None,
289 in_app_include: vec![],
290 in_app_exclude: vec![],
291 integrations: vec![],
292 default_integrations: true,
293 before_send: None,
294 before_breadcrumb: None,
295 transport: None,
296 http_proxy: None,
297 https_proxy: None,
298 shutdown_timeout: Duration::from_secs(2),
299 accept_invalid_certs: false,
300 #[cfg(feature = "release-health")]
301 auto_session_tracking: false,
302 #[cfg(feature = "release-health")]
303 session_mode: SessionMode::Application,
304 extra_border_frames: vec![],
305 trim_backtraces: true,
306 user_agent: Cow::Borrowed(USER_AGENT),
307 max_request_body_size: MaxRequestBodySize::Medium,
308 }
309 }
310}
311
312impl<T: IntoDsn> From<(T, ClientOptions)> for ClientOptions {
313 fn from((into_dsn, mut opts): (T, ClientOptions)) -> ClientOptions {
314 opts.dsn = into_dsn.into_dsn().expect("invalid value for DSN");
315 opts
316 }
317}
318
319impl<T: IntoDsn> From<T> for ClientOptions {
320 fn from(into_dsn: T) -> ClientOptions {
321 ClientOptions {
322 dsn: into_dsn.into_dsn().expect("invalid value for DSN"),
323 ..ClientOptions::default()
324 }
325 }
326}