diff --git a/Cargo.toml b/Cargo.toml index ecd968a3..3efc2cb8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,12 +16,13 @@ build = "build.rs" all-features = true [features] -default = ["with_client_implementation", "with_panic", "with_failure", "with_log", "with_device_info", "with_rust_info"] +default = ["with_client_implementation", "with_panic", "with_failure", "with_log", "with_env_logger", "with_device_info", "with_rust_info"] with_client_implementation = ["reqwest", "im", "url", "with_backtrace"] with_backtrace = ["backtrace", "regex"] with_panic = ["with_backtrace"] with_failure = ["failure", "with_backtrace"] with_log = ["log", "with_backtrace"] +with_env_logger = ["with_log", "env_logger"] with_error_chain = ["error-chain", "with_backtrace"] with_device_info = ["libc", "hostname", "uname", "with_client_implementation"] with_rust_info = ["rustc_version", "with_client_implementation"] @@ -36,6 +37,7 @@ log = { version = "0.4.1", optional = true } serde = "1.0.66" serde_json = "1.0.19" sentry-types = "0.5.3" +env_logger = { version = "0.5.10", optional = true } reqwest = { version = "0.8.6", optional = true } uuid = { version = "0.6.5", features = ["v4"] } lazy_static = "1.0.1" diff --git a/examples/log-demo.rs b/examples/log-demo.rs index e1c60728..b65cf020 100644 --- a/examples/log-demo.rs +++ b/examples/log-demo.rs @@ -15,7 +15,7 @@ fn main() { let mut log_builder = pretty_env_logger::formatted_builder().unwrap(); log_builder.parse("info"); - sentry::integrations::log::init(Some(Box::new(log_builder.build())), Default::default()); + sentry::integrations::env_logger::init(Some(log_builder.build()), Default::default()); sentry::integrations::panic::register_panic_handler(); info!("System is booting"); diff --git a/src/integrations/env_logger.rs b/src/integrations/env_logger.rs new file mode 100644 index 00000000..fc1276b0 --- /dev/null +++ b/src/integrations/env_logger.rs @@ -0,0 +1,43 @@ +//! Adds support for automatic breadcrumb capturing from logs with `env_logger`. +//! +//! **Feature:** `with_env_logger` (*enabled by default*) +//! +//! # Configuration +//! +//! In the most trivial version you call this crate's init function instead of the one +//! from `env_logger` and pass `None` as logger: +//! +//! ```no_run +//! # extern crate sentry; +//! sentry::integrations::env_logger::init(None, Default::default()); +//! ``` +//! +//! This parses the default `RUST_LOG` environment variable and configures both `env_logger` +//! and this crate appropriately. If you want to create your own logger you can forward it +//! accordingly: +//! +//! ```no_run +//! # extern crate sentry; +//! # extern crate pretty_env_logger; +//! let mut log_builder = pretty_env_logger::formatted_builder().unwrap(); +//! log_builder.parse("info,foo=debug"); +//! sentry::integrations::env_logger::init(Some(log_builder.build()), Default::default()); +//! ``` +use env_logger; + +use integrations::log::{self as sentry_log, LoggerOptions}; + +/// Initializes the environment logger. +/// +/// If a logger is given then it is used, otherwise a new logger is created in the same +/// way as `env_logger::init` does normally. The `global_filter` on the options is set +/// to the filter of the logger. +pub fn init(logger: Option, mut options: LoggerOptions) { + let logger = + logger.unwrap_or_else(|| env_logger::Builder::from_env(env_logger::Env::default()).build()); + let filter = logger.filter(); + if options.global_filter.is_none() { + options.global_filter = Some(filter); + } + sentry_log::init(Some(Box::new(logger)), options); +} diff --git a/src/integrations/log.rs b/src/integrations/log.rs index 2c03db2b..c705605f 100644 --- a/src/integrations/log.rs +++ b/src/integrations/log.rs @@ -18,9 +18,17 @@ //! # extern crate pretty_env_logger; //! let mut log_builder = pretty_env_logger::formatted_builder().unwrap(); //! log_builder.parse("info"); // or env::var("RUST_LOG") -//! sentry::integrations::log::init(Some( -//! Box::new(log_builder.build())), Default::default()); +//! let logger = log_builder.build(); +//! let options = sentry::integrations::log::LoggerOptions { +//! global_filter: Some(logger.filter()), +//! ..Default::default() +//! }; +//! sentry::integrations::log::init(Some(Box::new(logger)), options); //! ``` +//! +//! For loggers based on `env_logger` (like `pretty_env_logger`) you can also +//! use the [`env_logger`](../env_logger/index.html) integration which is +//! much easier to use. use log; use api::add_breadcrumb; @@ -52,6 +60,25 @@ impl Default for LoggerOptions { } } +impl LoggerOptions { + /// Returns the effective global filter. + /// + /// This is what is set for these logger options when the log level + /// needs to be set globally. This is the greater of `global_filter` + /// and `filter`. + fn effective_global_filter(&self) -> log::LevelFilter { + if let Some(filter) = self.global_filter { + if filter < self.filter { + self.filter + } else { + filter + } + } else { + self.filter + } + } +} + /// Provides a dispatching logger. pub struct Logger { dest: Option>, @@ -170,14 +197,20 @@ fn convert_log_level(level: log::Level) -> Level { /// use env_logger; /// /// let builder = env_logger::Builder::from_default_env(); -/// log::init(Some(Box::new(builder.build())), Default::default()); +/// let logger = builder.build(); +/// log::init(Some(Box::new(builder.build())), LoggerOptions { +/// global_filter: Some(logger.filter()), +/// ..Default::default() +/// }); /// ``` +/// +/// (For using `env_logger` you can also use the `env_logger` integration +/// which simplifies this). pub fn init(dest: Option>, options: LoggerOptions) { let logger = Logger::new(dest, options); - if let Some(filter) = logger.options().global_filter { + let filter = logger.options().effective_global_filter(); + if filter > log::max_level() { log::set_max_level(filter); - } else { - log::set_max_level(logger.options().filter); } log::set_boxed_logger(Box::new(logger)).unwrap(); } diff --git a/src/integrations/mod.rs b/src/integrations/mod.rs index b0f1c9b2..0ba2709c 100644 --- a/src/integrations/mod.rs +++ b/src/integrations/mod.rs @@ -10,5 +10,8 @@ pub mod error_chain; #[cfg(feature = "with_log")] pub mod log; +#[cfg(feature = "with_env_logger")] +pub mod env_logger; + #[cfg(feature = "with_panic")] pub mod panic; diff --git a/src/lib.rs b/src/lib.rs index f37f5a23..42d57b95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -135,6 +135,9 @@ extern crate error_chain; #[cfg(feature = "with_log")] extern crate log; +#[cfg(feature = "with_env_logger")] +extern crate env_logger; + #[cfg(feature = "with_debug_meta")] extern crate findshlibs;