Skip to content

ref: Make the fields of ClientOptions private #266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sentry-actix/src/lib.rs
Original file line number Diff line number Diff line change
@@ -218,7 +218,7 @@ impl<S: 'static> Middleware<S> for SentryMiddleware {
if cached_data.is_none() && req.is_valid() {
let with_pii = client
.as_ref()
.map_or(false, |x| x.options().send_default_pii);
.map_or(false, |x| x.options().send_default_pii());
*cached_data = Some(extract_request(&req.get(), with_pii));
}

2 changes: 1 addition & 1 deletion sentry-anyhow/src/lib.rs
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ impl Integration for AnyhowIntegration {
}

fn setup(&self, cfg: &mut ClientOptions) {
cfg.in_app_exclude.push("anyhow::");
cfg.add_in_app_exclude(&["anyhow::"]);
}
}

2 changes: 1 addition & 1 deletion sentry-backtrace/src/integration.rs
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ impl Integration for AttachStacktraceIntegration {
mut event: Event<'static>,
options: &ClientOptions,
) -> Option<Event<'static>> {
if options.attach_stacktrace && event.exception.is_empty() {
if options.attach_stacktrace() && event.exception.is_empty() {
let thread = current_thread(true);
if thread.stacktrace.is_some() {
event.threads.values.push(thread);
8 changes: 4 additions & 4 deletions sentry-backtrace/src/process.rs
Original file line number Diff line number Diff line change
@@ -15,10 +15,10 @@ use crate::{Frame, Stacktrace};
/// `ClientOptions`.
pub fn process_event_stacktrace(stacktrace: &mut Stacktrace, options: &ClientOptions) {
// automatically trim backtraces
if options.trim_backtraces {
if options.trim_backtraces() {
trim_stacktrace(stacktrace, |frame, _| {
if let Some(ref func) = frame.function {
options.extra_border_frames.contains(&func.as_str())
options.extra_border_frames().contains(&func.as_str())
} else {
false
}
@@ -49,7 +49,7 @@ pub fn process_event_stacktrace(stacktrace: &mut Stacktrace, options: &ClientOpt
None => {}
}

for m in &options.in_app_exclude {
for m in options.in_app_exclude() {
if function_starts_with(func_name, m) {
frame.in_app = Some(false);
break;
@@ -60,7 +60,7 @@ pub fn process_event_stacktrace(stacktrace: &mut Stacktrace, options: &ClientOpt
continue;
}

for m in &options.in_app_include {
for m in options.in_app_include() {
if function_starts_with(func_name, m) {
frame.in_app = Some(true);
any_in_app = true;
4 changes: 2 additions & 2 deletions sentry-contexts/src/integration.rs
Original file line number Diff line number Diff line change
@@ -44,8 +44,8 @@ impl Integration for ContextIntegration {
}

fn setup(&self, options: &mut ClientOptions) {
if options.server_name.is_none() {
options.server_name = server_name().map(Cow::Owned);
if options.server_name().is_none() {
options.set_server_name(server_name().map(Cow::Owned));
}
}

27 changes: 15 additions & 12 deletions sentry-core/src/client.rs
Original file line number Diff line number Diff line change
@@ -93,12 +93,14 @@ impl Client {
/// If the DSN on the options is set to `None` the client will be entirely
/// disabled.
pub fn with_options(mut options: ClientOptions) -> Client {
#![allow(deprecated)]

// Create the main hub eagerly to avoid problems with the background thread
// See https://github.com/getsentry/sentry-rust/issues/237
Hub::with(|_| {});

let create_transport = || {
options.dsn.as_ref()?;
options.dsn()?;
let factory = options.transport.as_ref()?;
Some(factory.create_transport(&options))
};
@@ -142,6 +144,8 @@ impl Client {
mut event: Event<'static>,
scope: Option<&Scope>,
) -> Option<Event<'static>> {
#![allow(deprecated)]

if let Some(scope) = scope {
scope.update_session_from_event(&event);
}
@@ -180,13 +184,13 @@ impl Client {
}

if event.release.is_none() {
event.release = self.options.release.clone();
event.release = self.options.release();
}
if event.environment.is_none() {
event.environment = self.options.environment.clone();
event.environment = self.options.environment();
}
if event.server_name.is_none() {
event.server_name = self.options.server_name.clone();
event.server_name = self.options.server_name();
}
if &event.platform == "other" {
event.platform = "native".into();
@@ -211,7 +215,7 @@ impl Client {

/// Returns the DSN that constructed this client.
pub fn dsn(&self) -> Option<&Dsn> {
self.options.dsn.as_ref()
self.options.dsn()
}

/// Quick check to see if the client is enabled.
@@ -230,15 +234,14 @@ impl Client {
/// let transport = sentry::test::TestTransport::new();
/// let client = sentry::Client::from((
/// dsn,
/// sentry::ClientOptions {
/// transport: Some(Arc::new(transport)),
/// ..Default::default()
/// },
/// sentry::ClientOptions::configure(|o| {
/// o.set_transport(Arc::new(transport))
/// }),
/// ));
/// assert!(client.is_enabled());
/// ```
pub fn is_enabled(&self) -> bool {
self.options.dsn.is_some() && self.transport.read().unwrap().is_some()
self.options.dsn().is_some() && self.transport.read().unwrap().is_some()
}

/// Captures an event and sends it to sentry.
@@ -282,15 +285,15 @@ impl Client {
let transport_opt = self.transport.write().unwrap().take();
if let Some(transport) = transport_opt {
sentry_debug!("client close; request transport to shut down");
transport.shutdown(timeout.unwrap_or(self.options.shutdown_timeout))
transport.shutdown(timeout.unwrap_or_else(|| self.options.shutdown_timeout()))
} else {
sentry_debug!("client close; no transport to shut down");
true
}
}

fn sample_should_send(&self) -> bool {
let rate = self.options.sample_rate;
let rate = self.options.sample_rate();
if rate >= 1.0 {
true
} else {
288 changes: 283 additions & 5 deletions sentry-core/src/clientoptions.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(deprecated)]

use std::borrow::Cow;
use std::fmt;
use std::sync::Arc;
@@ -19,81 +21,103 @@ pub type BeforeCallback<T> = Arc<dyn Fn(T) -> Option<T> + Send + Sync>;
/// # Examples
///
/// ```
/// let _options = sentry::ClientOptions {
/// debug: true,
/// ..Default::default()
/// };
/// let _options = sentry::ClientOptions::configure(|o| {
/// o.set_debug(true)
/// });
/// ```
#[derive(Clone)]
pub struct ClientOptions {
// Common options
/// The DSN to use. If not set the client is effectively disabled.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub dsn: Option<Dsn>,
/// Enables debug mode.
///
/// In debug mode debug information is printed to stderr to help you understand what
/// sentry is doing. When the `log` feature is enabled, Sentry will instead
/// log to the `sentry` logger independently of this flag with the `Debug` level.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub debug: bool,
/// The release to be sent with events.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub release: Option<Cow<'static, str>>,
/// The environment to be sent with events.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub environment: Option<Cow<'static, str>>,
/// The sample rate for event submission. (0.0 - 1.0, defaults to 1.0)
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub sample_rate: f32,
/// Maximum number of breadcrumbs. (defaults to 100)
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub max_breadcrumbs: usize,
/// Attaches stacktraces to messages.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub attach_stacktrace: bool,
/// If turned on some default PII informat is attached.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub send_default_pii: bool,
/// The server name to be reported.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub server_name: Option<Cow<'static, str>>,
/// Module prefixes that are always considered "in_app".
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub in_app_include: Vec<&'static str>,
/// Module prefixes that are never "in_app".
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub in_app_exclude: Vec<&'static str>,
// Integration options
/// A list of integrations to enable.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub integrations: Vec<Arc<dyn Integration>>,
/// Whether to add default integrations.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub default_integrations: bool,
// Hooks
/// Callback that is executed before event sending.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub before_send: Option<BeforeCallback<Event<'static>>>,
/// Callback that is executed for each Breadcrumb being added.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub before_breadcrumb: Option<BeforeCallback<Breadcrumb>>,
// Transport options
/// The transport to use.
///
/// This is typically either a boxed function taking the client options by
/// reference and returning a `Transport`, a boxed `Arc<Transport>` or
/// alternatively the `DefaultTransportFactory`.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub transport: Option<Arc<dyn TransportFactory>>,
/// An optional HTTP proxy to use.
///
/// This will default to the `http_proxy` environment variable.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub http_proxy: Option<Cow<'static, str>>,
/// An optional HTTPS proxy to use.
///
/// This will default to the `HTTPS_PROXY` environment variable
/// or `http_proxy` if that one exists.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub https_proxy: Option<Cow<'static, str>>,
/// The timeout on client drop for draining events on shutdown.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub shutdown_timeout: Duration,
// Other options not documented in Unified API
/// Enable Release Health Session tracking.
///
/// When automatic session tracking is enabled, a new "user-mode" session
/// is started at the time of `sentry::init`, and will persist for the
/// application lifetime.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub auto_session_tracking: bool,
/// Border frames which indicate a border from a backtrace to
/// useless internals. Some are automatically included.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub extra_border_frames: Vec<&'static str>,
/// Automatically trim backtraces of junk before sending. (defaults to true)
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub trim_backtraces: bool,
/// The user agent that should be reported.
#[deprecated = "use accessor functions instead; direct field access will be removed soon"]
pub user_agent: Cow<'static, str>,
}

@@ -102,6 +126,261 @@ impl ClientOptions {
pub fn new() -> Self {
Self::default()
}

/// Creates new Options and immediately configures them.
pub fn configure<F>(f: F) -> Self
where
F: FnOnce(&mut ClientOptions) -> &mut ClientOptions,
{
let mut opts = Self::new();
f(&mut opts);
opts
}

/// Set a DSN to use.
///
/// If not set the client is effectively disabled.
pub fn set_dsn(&mut self, dsn: Dsn) -> &mut Self {
self.dsn = Some(dsn);
self
}
/// The configured DSN.
pub fn dsn(&self) -> Option<&Dsn> {
self.dsn.as_ref()
}

/// Enables/disables debug mode.
///
/// In debug mode debug information is printed to stderr to help you understand what
/// sentry is doing. When the `log` feature is enabled, Sentry will instead
/// log to the `sentry` logger independently of this flag with the `Debug` level.
pub fn set_debug(&mut self, debug: bool) -> &mut Self {
self.debug = debug;
self
}
/// Whether debug logging is enabled.
pub fn debug(&self) -> bool {
self.debug
}

/// Set the release to be sent with events.
pub fn set_release(&mut self, release: Option<Cow<'static, str>>) -> &mut Self {
self.release = release;
self
}
/// The release to be sent with events.
pub fn release(&self) -> Option<Cow<'static, str>> {
self.release.clone()
}

/// Set the environment to be sent with events.
pub fn set_environment(&mut self, environment: Option<Cow<'static, str>>) -> &mut Self {
self.environment = environment;
self
}
/// The environment to be sent with events.
pub fn environment(&self) -> Option<Cow<'static, str>> {
self.environment.clone()
}

/// Set the sample rate for event submission. (0.0 - 1.0, defaults to 1.0)
pub fn set_sample_rate(&mut self, sample_rate: f32) -> &mut Self {
self.sample_rate = sample_rate;
self
}
/// The sample rate for event submission.
pub fn sample_rate(&self) -> f32 {
self.sample_rate
}

/// Set the maximum number of breadcrumbs. (defaults to 100)
pub fn set_max_breadcrumbs(&mut self, max_breadcrumbs: usize) -> &mut Self {
self.max_breadcrumbs = max_breadcrumbs;
self
}
/// Maximum number of breadcrumbs.
pub fn max_breadcrumbs(&self) -> usize {
self.max_breadcrumbs
}

/// Enable attaching stacktraces to message events.
pub fn set_attach_stacktrace(&mut self, attach_stacktrace: bool) -> &mut Self {
self.attach_stacktrace = attach_stacktrace;
self
}
/// Attach stacktraces to message events.
pub fn attach_stacktrace(&self) -> bool {
self.attach_stacktrace
}

/// Attach some default PII informat to events.
pub fn set_send_default_pii(&mut self, send_default_pii: bool) -> &mut Self {
self.send_default_pii = send_default_pii;
self
}
/// If turned on some default PII informat is attached to events.
pub fn send_default_pii(&self) -> bool {
self.send_default_pii
}

/// Set the server name to be reported.
pub fn set_server_name(&mut self, server_name: Option<Cow<'static, str>>) -> &mut Self {
self.server_name = server_name;
self
}
/// The server name to be reported.
pub fn server_name(&self) -> Option<Cow<'static, str>> {
self.server_name.clone()
}

/// Add module prefixes that are always considered "in_app".
pub fn add_in_app_include(&mut self, in_app_include: &[&'static str]) -> &mut Self {
self.in_app_include.extend_from_slice(in_app_include);
self
}
/// Module prefixes that are always considered "in_app".
pub fn in_app_include(&self) -> &[&'static str] {
&self.in_app_include
}

/// Add module prefixes that are never "in_app".
pub fn add_in_app_exclude(&mut self, in_app_exclude: &[&'static str]) -> &mut Self {
self.in_app_exclude.extend_from_slice(in_app_exclude);
self
}
/// Module prefixes that are never "in_app".
pub fn in_app_exclude(&self) -> &[&'static str] {
&self.in_app_exclude
}

/// Enable adding default integrations on init.
pub fn set_default_integrations(&mut self, default_integrations: bool) -> &mut Self {
self.default_integrations = default_integrations;
self
}
/// Whether to add default integrations.
pub fn default_integrations(&self) -> bool {
self.default_integrations
}

/// Adds another integration *in front* of the already registered ones.
// pub fn unshift_integration<I: Integration>(&mut self, integration: I) -> &mut Self {
// self.integrations.push_front(Arc::new(integration));
// self
// }

/// Set a callback that is executed before event sending.
pub fn set_before_send<F>(&mut self, before_send: F) -> &mut Self
where
F: Fn(Event<'static>) -> Option<Event<'static>> + Send + Sync + 'static,
{
self.before_send = Some(Arc::new(before_send));
self
}

/// Set a callback that is executed for each Breadcrumb being added.
pub fn set_before_breadcrumb<F>(&mut self, before_breadcrumb: F) -> &mut Self
where
F: Fn(Breadcrumb) -> Option<Breadcrumb> + Send + Sync + 'static,
{
self.before_breadcrumb = Some(Arc::new(before_breadcrumb));
self
}

/// The transport to use.
///
/// This is typically either a boxed function taking the client options by
/// reference and returning a `Transport`, a boxed `Arc<Transport>` or
/// alternatively the `DefaultTransportFactory`.
pub fn set_transport<F>(&mut self, transport: F) -> &mut Self
where
F: TransportFactory + 'static,
{
self.transport = Some(Arc::new(transport));
self
}
/// Whether a [`TransportFactory`] has been set on these options.
pub fn has_transport(&self) -> bool {
self.transport.is_some()
}

/// An optional HTTP proxy to use.
///
/// This will default to the `http_proxy` environment variable.
pub fn set_http_proxy(&mut self, http_proxy: Option<Cow<'static, str>>) -> &mut Self {
self.http_proxy = http_proxy;
self
}
/// The HTTP proxy Sentry will use.
pub fn http_proxy(&self) -> Option<Cow<'static, str>> {
self.http_proxy.clone()
}

/// Set an optional HTTPS proxy to use.
///
/// This will default to the `HTTPS_PROXY` environment variable
/// or `http_proxy` if that one exists.
pub fn set_https_proxy(&mut self, https_proxy: Option<Cow<'static, str>>) -> &mut Self {
self.https_proxy = https_proxy;
self
}
/// The HTTPS proxy Sentry will use.
pub fn https_proxy(&self) -> Option<Cow<'static, str>> {
self.https_proxy.clone()
}

/// The timeout on client drop for draining events on shutdown.
pub fn shutdown_timeout(&self) -> Duration {
self.shutdown_timeout
}

/// Enable Release Health Session tracking.
///
/// When automatic session tracking is enabled, a new "user-mode" session
/// is started at the time of `sentry::init`, and will persist for the
/// application lifetime.
pub fn set_auto_session_tracking(&mut self, auto_session_tracking: bool) -> &mut Self {
self.auto_session_tracking = auto_session_tracking;
self
}
/// Whether automatic session tracking is enabled.
pub fn auto_session_tracking(&self) -> bool {
self.auto_session_tracking
}

/// Add extra border frames which indicate a border from a backtrace to
/// useless internals.
pub fn add_extra_border_frames(&mut self, extra_border_frames: &[&'static str]) -> &mut Self {
self.extra_border_frames
.extend_from_slice(extra_border_frames);
self
}
/// Border frames which indicate a border from a backtrace to
/// useless internals. Some are automatically included.
pub fn extra_border_frames(&self) -> &[&'static str] {
&self.extra_border_frames
}

/// Automatically trim backtraces of junk before sending. (defaults to true)
pub fn set_trim_backtraces(&mut self, trim_backtraces: bool) -> &mut Self {
self.trim_backtraces = trim_backtraces;
self
}
/// Automatically trim backtraces of junk before sending.
pub fn trim_backtraces(&self) -> bool {
self.trim_backtraces
}

/// Set the user agent that should be reported.
pub fn set_user_agent(&mut self, user_agent: Cow<'static, str>) -> &mut Self {
self.user_agent = user_agent;
self
}
/// The user agent that should be reported.
pub fn user_agent(&self) -> Cow<'static, str> {
self.user_agent.clone()
}

/// Adds a configured integration to the options.
///
/// # Examples
@@ -112,7 +391,6 @@ impl ClientOptions {
/// impl sentry::Integration for MyIntegration {}
///
/// let options = sentry::ClientOptions::new().add_integration(MyIntegration);
/// assert_eq!(options.integrations.len(), 1);
/// ```
pub fn add_integration<I: Integration>(mut self, integration: I) -> Self {
self.integrations.push(Arc::new(integration));
3 changes: 2 additions & 1 deletion sentry-core/src/hub.rs
Original file line number Diff line number Diff line change
@@ -415,14 +415,15 @@ impl Hub {
let scope = Arc::make_mut(&mut top.scope);
let options = client.options();
for breadcrumb in breadcrumb.into_breadcrumbs() {
#[allow(deprecated)]
let breadcrumb_opt = match options.before_breadcrumb {
Some(ref callback) => callback(breadcrumb),
None => Some(breadcrumb)
};
if let Some(breadcrumb) = breadcrumb_opt {
scope.breadcrumbs.push_back(breadcrumb);
}
while scope.breadcrumbs.len() > options.max_breadcrumbs {
while scope.breadcrumbs.len() > options.max_breadcrumbs() {
scope.breadcrumbs.pop_front();
}
}
9 changes: 4 additions & 5 deletions sentry-core/src/macros.rs
Original file line number Diff line number Diff line change
@@ -8,10 +8,9 @@
/// ```
/// # #[macro_use] extern crate sentry;
/// # fn main() {
/// let _sentry = sentry::init(sentry::ClientOptions {
/// release: sentry::release_name!(),
/// ..Default::default()
/// });
/// let _sentry = sentry::init(sentry::ClientOptions::configure(|o| {
/// o.set_release(sentry::release_name!())
/// }));
/// # }
/// ```
#[macro_export]
@@ -60,7 +59,7 @@ macro_rules! sentry_debug {
}
#[cfg(not(feature = "debug-logs"))] {
$crate::Hub::with(|hub| {
if hub.client().map_or(false, |c| c.options().debug) {
if hub.client().map_or(false, |c| c.options().debug()) {
eprint!("[sentry] ");
eprintln!($($arg)*);
}
18 changes: 7 additions & 11 deletions sentry-core/src/session.rs
Original file line number Diff line number Diff line change
@@ -57,8 +57,8 @@ impl Session {
status: SessionStatus::Ok,
errors: 0,
attributes: SessionAttributes {
release: options.release.clone()?,
environment: options.environment.clone(),
release: options.release()?,
environment: options.environment(),
ip_address: None,
user_agent: None,
},
@@ -125,10 +125,7 @@ mod tests {
{
crate::test::with_captured_envelopes_options(
f,
crate::ClientOptions {
release: Some("some-release".into()),
..Default::default()
},
crate::ClientOptions::configure(|opts| opts.set_release(Some("some-release".into()))),
)
}

@@ -197,11 +194,10 @@ mod tests {
sentry::capture_error(&err);
}
},
crate::ClientOptions {
release: Some("some-release".into()),
sample_rate: 0.5,
..Default::default()
},
crate::ClientOptions::configure(|opts| {
opts.set_release(Some("some-release".into()))
.set_sample_rate(0.5)
}),
);
assert!(envelopes.len() > 25);
assert!(envelopes.len() < 75);
15 changes: 9 additions & 6 deletions sentry-core/src/test.rs
Original file line number Diff line number Diff line change
@@ -39,11 +39,10 @@ lazy_static::lazy_static! {
/// use std::sync::Arc;
///
/// let transport = TestTransport::new();
/// let options = ClientOptions {
/// dsn: Some("https://public@example.com/1".parse().unwrap()),
/// transport: Some(Arc::new(transport.clone())),
/// ..ClientOptions::default()
/// };
/// let options = ClientOptions::configure(|o| {
/// o.set_dsn("https://public@example.com/1".parse().unwrap())
/// .set_transport(transport.clone())
/// });
/// Hub::current().bind_client(Some(Arc::new(options.into())));
/// ```
pub struct TestTransport {
@@ -121,9 +120,13 @@ pub fn with_captured_envelopes_options<F: FnOnce(), O: Into<ClientOptions>>(
f: F,
options: O,
) -> Vec<Envelope> {
#![allow(deprecated)]

let transport = TestTransport::new();
let mut options = options.into();
options.dsn = Some(options.dsn.unwrap_or_else(|| TEST_DSN.clone()));
if options.dsn().is_none() {
options.set_dsn(TEST_DSN.clone());
}
options.transport = Some(Arc::new(transport.clone()));
Hub::run(
Arc::new(Hub::new(
4 changes: 2 additions & 2 deletions sentry-error-chain/src/lib.rs
Original file line number Diff line number Diff line change
@@ -126,7 +126,7 @@ impl Integration for ErrorChainIntegration {
}

fn setup(&self, cfg: &mut ClientOptions) {
cfg.in_app_exclude.push("error_chain::");
cfg.extra_border_frames.push("error_chain::make_backtrace");
cfg.add_in_app_exclude(&["error_chain::"]);
cfg.add_extra_border_frames(&["error_chain::make_backtrace"]);
}
}
4 changes: 2 additions & 2 deletions sentry-failure/src/lib.rs
Original file line number Diff line number Diff line change
@@ -58,8 +58,8 @@ impl Integration for FailureIntegration {
}

fn setup(&self, cfg: &mut ClientOptions) {
cfg.in_app_exclude.push("failure::");
cfg.extra_border_frames.extend_from_slice(&[
cfg.add_in_app_exclude(&["failure::"]);
cfg.add_extra_border_frames(&[
"failure::error_message::err_msg",
"failure::backtrace::Backtrace::new",
"failure::backtrace::internal::InternalBacktrace::new",
5 changes: 2 additions & 3 deletions sentry-log/src/integration.rs
Original file line number Diff line number Diff line change
@@ -33,9 +33,8 @@ impl Integration for LogIntegration {
}

fn setup(&self, cfg: &mut ClientOptions) {
cfg.in_app_exclude.push("log::");
cfg.extra_border_frames
.push("<sentry_log::Logger as log::Log>::log");
cfg.add_in_app_exclude(&["log::"]);
cfg.add_extra_border_frames(&["<sentry_log::Logger as log::Log>::log"]);

let filter = self.effective_global_filter();
if filter > log::max_level() {
7 changes: 3 additions & 4 deletions sentry/examples/anyhow-demo.rs
Original file line number Diff line number Diff line change
@@ -6,10 +6,9 @@ fn execute() -> anyhow::Result<usize> {
}

fn main() {
let _sentry = sentry::init(sentry::ClientOptions {
release: sentry::release_name!(),
..Default::default()
});
let _sentry = sentry::init(sentry::ClientOptions::configure(|o| {
o.set_release(sentry::release_name!())
}));

if let Err(err) = execute() {
println!("error: {}", err);
13 changes: 5 additions & 8 deletions sentry/examples/before-send.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
use std::sync::Arc;

fn main() {
let _sentry = sentry::init(sentry::ClientOptions {
before_send: Some(Arc::new(|mut event| {
let _sentry = sentry::init(sentry::ClientOptions::configure(|o| {
o.set_before_send(|mut event| {
event.request = Some(sentry::protocol::Request {
url: Some("https://example.com/".parse().unwrap()),
method: Some("GET".into()),
..Default::default()
});
Some(event)
})),
debug: true,
..Default::default()
});
})
.set_debug(true)
}));

let id = sentry::capture_message("An HTTP request failed.", sentry::Level::Error);
println!("sent event {}", id);
7 changes: 3 additions & 4 deletions sentry/examples/failure-demo.rs
Original file line number Diff line number Diff line change
@@ -20,10 +20,9 @@ fn execute() -> Result<(), failure::Error> {
}

fn main() {
let _sentry = sentry::init(sentry::ClientOptions {
release: sentry::release_name!(),
..Default::default()
});
let _sentry = sentry::init(sentry::ClientOptions::configure(|o| {
o.set_release(sentry::release_name!())
}));

if let Err(err) = execute() {
println!("error: {}", err);
10 changes: 4 additions & 6 deletions sentry/examples/health.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
fn main() {
let _sentry = sentry::init(sentry::ClientOptions {
let _sentry = sentry::init(sentry::ClientOptions::configure(|o|
// release health requires a release to be set
release: sentry::release_name!(),
debug: true,
o.set_release(sentry::release_name!())
.set_debug(true)
// session tracking is enabled by default, but we want to explicitly
// create the session
auto_session_tracking: false,
..Default::default()
});
.set_auto_session_tracking(false)));

let handle = std::thread::spawn(|| {
// this session will be set to crashed
7 changes: 2 additions & 5 deletions sentry/examples/log-demo.rs
Original file line number Diff line number Diff line change
@@ -7,11 +7,8 @@ fn main() {
sentry_log::LogIntegration::default().with_env_logger_dest(Some(log_builder.build()));

let _sentry = sentry::init(
sentry::ClientOptions {
release: sentry::release_name!(),
..Default::default()
}
.add_integration(log_integration),
sentry::ClientOptions::configure(|o| o.set_release(sentry::release_name!()))
.add_integration(log_integration),
);

debug!("System is booting");
7 changes: 3 additions & 4 deletions sentry/examples/panic-demo.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
fn main() {
let _sentry = sentry::init(sentry::ClientOptions {
release: sentry::release_name!(),
..Default::default()
});
let _sentry = sentry::init(sentry::ClientOptions::configure(|o| {
o.set_release(sentry::release_name!())
}));

{
let _guard = sentry::Hub::current().push_scope();
7 changes: 2 additions & 5 deletions sentry/examples/thread-demo.rs
Original file line number Diff line number Diff line change
@@ -14,11 +14,8 @@ fn main() {
// special behavior in that all other threads spawned will get a hub based on
// the hub from here.
let _sentry = sentry::init(
sentry::ClientOptions {
release: sentry::release_name!(),
..Default::default()
}
.add_integration(log_integration),
sentry::ClientOptions::configure(|o| o.set_release(sentry::release_name!()))
.add_integration(log_integration),
);

// the log integration sends to Hub::current()
86 changes: 49 additions & 37 deletions sentry/src/defaults.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![cfg_attr(feature = "error-chain", allow(deprecated))]
#![cfg_attr(feature = "failure", allow(deprecated))]
#![allow(deprecated)]

use std::borrow::Cow;
use std::env;
use std::{borrow::Cow, sync::Arc};
use std::sync::Arc;

use crate::transports::DefaultTransportFactory;
use crate::types::Dsn;
@@ -36,12 +36,12 @@ use crate::{ClientOptions, Integration};
/// std::env::set_var("SENTRY_RELEASE", "release-from-env");
///
/// let options = sentry::ClientOptions::default();
/// assert_eq!(options.release, None);
/// assert!(options.transport.is_none());
/// assert_eq!(options.release(), None);
/// assert!(!options.has_transport());
///
/// let options = sentry::apply_defaults(options);
/// assert_eq!(options.release, Some("release-from-env".into()));
/// assert!(options.transport.is_some());
/// assert_eq!(options.release(), Some("release-from-env".into()));
/// assert!(options.has_transport());
/// ```
///
/// [`AttachStacktraceIntegration`]: integrations/backtrace/struct.AttachStacktraceIntegration.html
@@ -52,13 +52,14 @@ use crate::{ClientOptions, Integration};
/// [`PanicIntegration`]: integrations/panic/struct.PanicIntegration.html
/// [`ProcessStacktraceIntegration`]: integrations/backtrace/struct.ProcessStacktraceIntegration.html
pub fn apply_defaults(mut opts: ClientOptions) -> ClientOptions {
if opts.transport.is_none() {
opts.transport = Some(Arc::new(DefaultTransportFactory));
if !opts.has_transport() {
opts.set_transport(DefaultTransportFactory);
}
if opts.default_integrations {
if opts.default_integrations() {
// default integrations need to be ordered *before* custom integrations,
// since they also process events in order
let mut integrations: Vec<Arc<dyn Integration>> = vec![];

#[cfg(feature = "backtrace")]
{
integrations.push(Arc::new(
@@ -101,41 +102,52 @@ pub fn apply_defaults(mut opts: ClientOptions) -> ClientOptions {
sentry_backtrace::ProcessStacktraceIntegration::default(),
));
}

integrations.reverse();
integrations.extend(opts.integrations.into_iter());
opts.integrations = integrations;
}
if opts.dsn.is_none() {
opts.dsn = env::var("SENTRY_DSN")
if opts.dsn().is_none() {
if let Some(dsn) = env::var("SENTRY_DSN")
.ok()
.and_then(|dsn| dsn.parse::<Dsn>().ok());
.and_then(|dsn| dsn.parse::<Dsn>().ok())
{
opts.set_dsn(dsn);
}
}
if opts.release.is_none() {
opts.release = env::var("SENTRY_RELEASE").ok().map(Cow::Owned);
if opts.release().is_none() {
opts.set_release(env::var("SENTRY_RELEASE").ok().map(Cow::Owned));
}
if opts.environment.is_none() {
opts.environment = env::var("SENTRY_ENVIRONMENT")
.ok()
.map(Cow::Owned)
.or_else(|| {
Some(Cow::Borrowed(if cfg!(debug_assertions) {
"debug"
} else {
"release"
}))
});
if opts.environment().is_none() {
opts.set_environment(
env::var("SENTRY_ENVIRONMENT")
.ok()
.map(Cow::Owned)
.or_else(|| {
Some(Cow::Borrowed(if cfg!(debug_assertions) {
"debug"
} else {
"release"
}))
}),
);
}
if opts.http_proxy.is_none() {
opts.http_proxy = std::env::var("HTTP_PROXY")
.ok()
.map(Cow::Owned)
.or_else(|| std::env::var("http_proxy").ok().map(Cow::Owned));
if opts.http_proxy().is_none() {
opts.set_http_proxy(
std::env::var("HTTP_PROXY")
.ok()
.map(Cow::Owned)
.or_else(|| std::env::var("http_proxy").ok().map(Cow::Owned)),
);
}
if opts.https_proxy.is_none() {
opts.https_proxy = std::env::var("HTTPS_PROXY")
.ok()
.map(Cow::Owned)
.or_else(|| std::env::var("https_proxy").ok().map(Cow::Owned))
.or_else(|| opts.http_proxy.clone());
if opts.https_proxy().is_none() {
opts.set_https_proxy(
std::env::var("HTTPS_PROXY")
.ok()
.map(Cow::Owned)
.or_else(|| std::env::var("https_proxy").ok().map(Cow::Owned))
.or_else(|| opts.http_proxy()),
);
}
opts
}
9 changes: 4 additions & 5 deletions sentry/src/init.rs
Original file line number Diff line number Diff line change
@@ -65,10 +65,9 @@ impl Drop for ClientInitGuard {
/// created to enable further configuration:
///
/// ```
/// let sentry = sentry::init(sentry::ClientOptions {
/// release: Some("foo-bar-baz@1.0.0".into()),
/// ..Default::default()
/// });
/// let sentry = sentry::init(sentry::ClientOptions::configure(|o| {
/// o.set_release(Some("foo-bar-baz@1.0.0".into()))
/// }));
/// if sentry.is_enabled() {
/// // some other initialization
/// }
@@ -91,7 +90,7 @@ where
C: Into<ClientOptions>,
{
let opts = apply_defaults(opts.into());
let auto_session_tracking = opts.auto_session_tracking;
let auto_session_tracking = opts.auto_session_tracking();
let client = Arc::new(Client::from(opts));

Hub::with(|hub| hub.bind_client(Some(client.clone())));
20 changes: 10 additions & 10 deletions sentry/src/transport.rs
Original file line number Diff line number Diff line change
@@ -184,12 +184,12 @@ implement_http_transport! {
queue_size: Arc<Mutex<usize>>,
http_client: Option<ReqwestClient>,
) {
let dsn = options.dsn.clone().unwrap();
let user_agent = options.user_agent.to_string();
let dsn = options.dsn().cloned().unwrap();
let user_agent = options.user_agent().to_string();

let mut disabled = None::<SystemTime>;
let http_proxy = options.http_proxy.as_ref().map(ToString::to_string);
let https_proxy = options.https_proxy.as_ref().map(ToString::to_string);
let http_proxy = options.http_proxy().as_ref().map(ToString::to_string);
let https_proxy = options.https_proxy().as_ref().map(ToString::to_string);

thread::Builder::new()
.name("sentry-transport".to_string())
@@ -293,10 +293,10 @@ implement_http_transport! {
queue_size: Arc<Mutex<usize>>,
http_client: curl::easy::Easy,
) {
let dsn = options.dsn.clone().unwrap();
let user_agent = options.user_agent.to_string();
let http_proxy = options.http_proxy.as_ref().map(ToString::to_string);
let https_proxy = options.https_proxy.as_ref().map(ToString::to_string);
let dsn = options.dsn().cloned().unwrap();
let user_agent = options.user_agent().to_string();
let http_proxy = options.http_proxy().as_ref().map(ToString::to_string);
let https_proxy = options.https_proxy().as_ref().map(ToString::to_string);

let mut disabled = None::<SystemTime>;
let mut handle = http_client;
@@ -426,8 +426,8 @@ implement_http_transport! {
queue_size: Arc<Mutex<usize>>,
http_client: SurfClient<NativeClient>,
) {
let dsn = options.dsn.clone().unwrap();
let user_agent = options.user_agent.to_string();
let dsn = options.dsn().cloned().unwrap();
let user_agent = options.user_agent().to_string();
let mut disabled = None::<SystemTime>;

thread::Builder::new()
13 changes: 6 additions & 7 deletions sentry/tests/test_basic.rs
Original file line number Diff line number Diff line change
@@ -97,16 +97,15 @@ fn test_factory() {
let events = Arc::new(AtomicUsize::new(0));

let events_for_options = events.clone();
let options = sentry::ClientOptions {
dsn: "http://foo@example.com/42".parse().ok(),
transport: Some(Arc::new(
let dsn = "http://foo@example.com/42".parse().unwrap();
let options = sentry::ClientOptions::configure(|o| {
o.set_dsn(dsn).set_transport(
move |opts: &sentry::ClientOptions| -> Arc<dyn sentry::Transport> {
assert_eq!(opts.dsn.as_ref().unwrap().host(), "example.com");
assert_eq!(opts.dsn().unwrap().host(), "example.com");
Arc::new(TestTransport(events_for_options.clone()))
},
)),
..Default::default()
};
)
});

sentry::Hub::run(
Arc::new(sentry::Hub::new(
18 changes: 7 additions & 11 deletions sentry/tests/test_client.rs
Original file line number Diff line number Diff line change
@@ -16,31 +16,27 @@ fn test_into_client() {

let c: sentry::Client = sentry::Client::from_config((
"https://public@example.com/42",
sentry::ClientOptions {
release: Some("foo@1.0".into()),
..Default::default()
},
sentry::ClientOptions::configure(|o| o.set_release(Some("foo@1.0".into()))),
));
{
let dsn = c.dsn().unwrap();
assert_eq!(dsn.public_key(), "public");
assert_eq!(dsn.host(), "example.com");
assert_eq!(dsn.scheme(), sentry::types::Scheme::Https);
assert_eq!(dsn.project_id().value(), 42);
assert_eq!(&c.options().release.as_ref().unwrap(), &"foo@1.0");
assert_eq!(&c.options().release().unwrap(), "foo@1.0");
}

assert!(sentry::Client::from_config(()).options().dsn.is_none());
assert!(sentry::Client::from_config(()).options().dsn().is_none());
}

#[test]
fn test_unwind_safe() {
let transport = sentry::test::TestTransport::new();
let options = sentry::ClientOptions {
dsn: Some("https://public@example.com/1".parse().unwrap()),
transport: Some(Arc::new(transport.clone())),
..sentry::ClientOptions::default()
};
let options = sentry::ClientOptions::configure(|o| {
o.set_dsn("https://public@example.com/1".parse().unwrap())
.set_transport(Arc::new(transport.clone()))
});

let client: Arc<sentry::Client> = Arc::new(options.into());

21 changes: 6 additions & 15 deletions sentry/tests/test_processors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#![cfg(feature = "test")]

use std::sync::Arc;

#[test]
fn test_event_processors() {
let events = sentry::test::with_captured_events(|| {
@@ -52,11 +50,10 @@ fn test_before_callbacks() {
});
sentry::capture_message("Hello World!", sentry::Level::Warning);
},
sentry::ClientOptions {
before_send: Some(Arc::new(Box::new(before_send))),
before_breadcrumb: Some(Arc::new(Box::new(before_breadcrumb))),
..Default::default()
},
sentry::ClientOptions::configure(|o| {
o.set_before_send(before_send)
.set_before_breadcrumb(before_breadcrumb)
}),
);

assert_eq!(events.len(), 1);
@@ -85,10 +82,7 @@ fn test_before_event_callback_drop() {
});
sentry::capture_message("Hello World!", sentry::Level::Warning);
},
sentry::ClientOptions {
before_send: Some(Arc::new(Box::new(before_send))),
..Default::default()
},
sentry::ClientOptions::configure(|o| o.set_before_send(before_send)),
);

assert_eq!(events.len(), 0);
@@ -109,10 +103,7 @@ fn test_before_breadcrumb_callback_drop() {
});
sentry::capture_message("Hello World!", sentry::Level::Warning);
},
sentry::ClientOptions {
before_breadcrumb: Some(Arc::new(Box::new(before_breadcrumb))),
..Default::default()
},
sentry::ClientOptions::configure(|o| o.set_before_breadcrumb(before_breadcrumb)),
);

assert_eq!(events.len(), 1);