1 use std::borrow::Cow; 2 use std::fmt; 3 use std::sync::Arc; 4 use std::time::Duration; 5 6 use crate::constants::USER_AGENT; 7 use crate::protocol::{Breadcrumb, Event}; 8 use crate::types::Dsn; 9 use crate::{Integration, IntoDsn, TransportFactory}; 10 11 /// Type alias for before event/breadcrumb handlers. 12 pub type BeforeCallback<T> = Arc<dyn Fn(T) -> Option<T> + Send + Sync>; 13 14 /// The Session Mode of the SDK. 15 /// 16 /// Depending on the use-case, the SDK can be set to two different session modes: 17 /// 18 /// * **Application Mode Sessions**: 19 /// This mode should be used for user-attended programs, which typically have 20 /// a single long running session that span the applications' lifetime. 21 /// 22 /// * **Request Mode Sessions**: 23 /// This mode is intended for servers that use one session per incoming 24 /// request, and thus have a lot of very short lived sessions. 25 /// 26 /// Setting the SDK to *request-mode* sessions means that session durations will 27 /// not be tracked, and sessions will be pre-aggregated before being sent upstream. 28 /// This applies both to automatic and manually triggered sessions. 29 /// 30 /// **NOTE**: Support for *request-mode* sessions was added in Sentry `21.2`. 31 /// 32 /// See the [Documentation on Session Modes](https://develop.sentry.dev/sdk/sessions/#sdk-considerations) 33 /// for more information. 34 #[derive(Copy, Clone, Debug, PartialEq)] 35 pub enum SessionMode { 36 /// Long running application session. 37 Application, 38 /// Lots of short per-request sessions. 39 Request, 40 } 41 42 /// Configuration settings for the client. 43 /// 44 /// These options are explained in more detail in the general 45 /// [sentry documentation](https://docs.sentry.io/error-reporting/configuration/?platform=rust). 46 /// 47 /// # Examples 48 /// 49 /// ``` 50 /// let _options = sentry::ClientOptions { 51 /// debug: true, 52 /// ..Default::default() 53 /// }; 54 /// ``` 55 #[derive(Clone)] 56 pub struct ClientOptions { 57 // Common options 58 /// The DSN to use. If not set the client is effectively disabled. 59 pub dsn: Option<Dsn>, 60 /// Enables debug mode. 61 /// 62 /// In debug mode debug information is printed to stderr to help you understand what 63 /// sentry is doing. When the `log` feature is enabled, Sentry will instead 64 /// log to the `sentry` logger independently of this flag with the `Debug` level. 65 pub debug: bool, 66 /// The release to be sent with events. 67 pub release: Option<Cow<'static, str>>, 68 /// The environment to be sent with events. 69 /// 70 /// Defaults to either `"development"` or `"production"` depending on the 71 /// `debug_assertions` cfg-attribute. 72 pub environment: Option<Cow<'static, str>>, 73 /// The sample rate for event submission. (0.0 - 1.0, defaults to 1.0) 74 pub sample_rate: f32, 75 /// Maximum number of breadcrumbs. (defaults to 100) 76 pub max_breadcrumbs: usize, 77 /// Attaches stacktraces to messages. 78 pub attach_stacktrace: bool, 79 /// If turned on some default PII informat is attached. 80 pub send_default_pii: bool, 81 /// The server name to be reported. 82 pub server_name: Option<Cow<'static, str>>, 83 /// Module prefixes that are always considered "in_app". 84 pub in_app_include: Vec<&'static str>, 85 /// Module prefixes that are never "in_app". 86 pub in_app_exclude: Vec<&'static str>, 87 // Integration options 88 /// A list of integrations to enable. 89 /// 90 /// See [`sentry::integrations`](integrations/index.html#installing-integrations) for 91 /// how to use this to enable extra integrations. 92 pub integrations: Vec<Arc<dyn Integration>>, 93 /// Whether to add default integrations. 94 /// 95 /// See [`sentry::integrations`](integrations/index.html#default-integrations) for 96 /// details how this works and interacts with manually installed integrations. 97 pub default_integrations: bool, 98 // Hooks 99 /// Callback that is executed before event sending. 100 pub before_send: Option<BeforeCallback<Event<'static>>>, 101 /// Callback that is executed for each Breadcrumb being added. 102 pub before_breadcrumb: Option<BeforeCallback<Breadcrumb>>, 103 // Transport options 104 /// The transport to use. 105 /// 106 /// This is typically either a boxed function taking the client options by 107 /// reference and returning a `Transport`, a boxed `Arc<Transport>` or 108 /// alternatively the `DefaultTransportFactory`. 109 pub transport: Option<Arc<dyn TransportFactory>>, 110 /// An optional HTTP proxy to use. 111 /// 112 /// This will default to the `http_proxy` environment variable. 113 pub http_proxy: Option<Cow<'static, str>>, 114 /// An optional HTTPS proxy to use. 115 /// 116 /// This will default to the `HTTPS_PROXY` environment variable 117 /// or `http_proxy` if that one exists. 118 pub https_proxy: Option<Cow<'static, str>>, 119 /// The timeout on client drop for draining events on shutdown. 120 pub shutdown_timeout: Duration, 121 // Other options not documented in Unified API 122 /// Enable Release Health Session tracking. 123 /// 124 /// When automatic session tracking is enabled, a new "user-mode" session 125 /// is started at the time of `sentry::init`, and will persist for the 126 /// application lifetime. 127 pub auto_session_tracking: bool, 128 /// Determine how Sessions are being tracked. 129 pub session_mode: SessionMode, 130 /// Border frames which indicate a border from a backtrace to 131 /// useless internals. Some are automatically included. 132 pub extra_border_frames: Vec<&'static str>, 133 /// Automatically trim backtraces of junk before sending. (defaults to true) 134 pub trim_backtraces: bool, 135 /// The user agent that should be reported. 136 pub user_agent: Cow<'static, str>, 137 } 138 139 impl ClientOptions { 140 /// Creates new Options. new() -> Self141 pub fn new() -> Self { 142 Self::default() 143 } 144 145 /// Adds a configured integration to the options. 146 /// 147 /// # Examples 148 /// 149 /// ``` 150 /// struct MyIntegration; 151 /// 152 /// impl sentry::Integration for MyIntegration {} 153 /// 154 /// let options = sentry::ClientOptions::new().add_integration(MyIntegration); 155 /// assert_eq!(options.integrations.len(), 1); 156 /// ``` add_integration<I: Integration>(mut self, integration: I) -> Self157 pub fn add_integration<I: Integration>(mut self, integration: I) -> Self { 158 self.integrations.push(Arc::new(integration)); 159 self 160 } 161 } 162 163 impl fmt::Debug for ClientOptions { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 165 #[derive(Debug)] 166 struct BeforeSend; 167 let before_send = self.before_send.as_ref().map(|_| BeforeSend); 168 #[derive(Debug)] 169 struct BeforeBreadcrumb; 170 let before_breadcrumb = self.before_breadcrumb.as_ref().map(|_| BeforeBreadcrumb); 171 #[derive(Debug)] 172 struct TransportFactory; 173 174 let integrations: Vec<_> = self.integrations.iter().map(|i| i.name()).collect(); 175 176 f.debug_struct("ClientOptions") 177 .field("dsn", &self.dsn) 178 .field("debug", &self.debug) 179 .field("release", &self.release) 180 .field("environment", &self.environment) 181 .field("sample_rate", &self.sample_rate) 182 .field("max_breadcrumbs", &self.max_breadcrumbs) 183 .field("attach_stacktrace", &self.attach_stacktrace) 184 .field("send_default_pii", &self.send_default_pii) 185 .field("server_name", &self.server_name) 186 .field("in_app_include", &self.in_app_include) 187 .field("in_app_exclude", &self.in_app_exclude) 188 .field("integrations", &integrations) 189 .field("default_integrations", &self.default_integrations) 190 .field("before_send", &before_send) 191 .field("before_breadcrumb", &before_breadcrumb) 192 .field("transport", &TransportFactory) 193 .field("http_proxy", &self.http_proxy) 194 .field("https_proxy", &self.https_proxy) 195 .field("shutdown_timeout", &self.shutdown_timeout) 196 .field("auto_session_tracking", &self.auto_session_tracking) 197 .field("session_mode", &self.session_mode) 198 .field("extra_border_frames", &self.extra_border_frames) 199 .field("trim_backtraces", &self.trim_backtraces) 200 .field("user_agent", &self.user_agent) 201 .finish() 202 } 203 } 204 205 impl Default for ClientOptions { default() -> ClientOptions206 fn default() -> ClientOptions { 207 ClientOptions { 208 dsn: None, 209 debug: false, 210 release: None, 211 environment: None, 212 sample_rate: 1.0, 213 max_breadcrumbs: 100, 214 attach_stacktrace: false, 215 send_default_pii: false, 216 server_name: None, 217 in_app_include: vec![], 218 in_app_exclude: vec![], 219 integrations: vec![], 220 default_integrations: true, 221 before_send: None, 222 before_breadcrumb: None, 223 transport: None, 224 http_proxy: None, 225 https_proxy: None, 226 shutdown_timeout: Duration::from_secs(2), 227 auto_session_tracking: false, 228 session_mode: SessionMode::Application, 229 extra_border_frames: vec![], 230 trim_backtraces: true, 231 user_agent: Cow::Borrowed(&USER_AGENT), 232 } 233 } 234 } 235 236 impl<T: IntoDsn> From<(T, ClientOptions)> for ClientOptions { from((into_dsn, mut opts): (T, ClientOptions)) -> ClientOptions237 fn from((into_dsn, mut opts): (T, ClientOptions)) -> ClientOptions { 238 opts.dsn = into_dsn.into_dsn().expect("invalid value for DSN"); 239 opts 240 } 241 } 242 243 impl<T: IntoDsn> From<T> for ClientOptions { from(into_dsn: T) -> ClientOptions244 fn from(into_dsn: T) -> ClientOptions { 245 ClientOptions { 246 dsn: into_dsn.into_dsn().expect("invalid value for DSN"), 247 ..ClientOptions::default() 248 } 249 } 250 } 251