Skip to content

Commit

Permalink
Merge pull request #187 from alisha17/setlogger
Browse files Browse the repository at this point in the history
Change set_logger to panic on error
  • Loading branch information
brson committed Jul 5, 2017
2 parents 26d6497 + a1e0bca commit f21e9e8
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 37 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -72,7 +72,7 @@ extern crate log;
extern crate env_logger;

fn main() {
env_logger::init().unwrap();
env_logger::init();

info!("starting up");

Expand Down Expand Up @@ -185,5 +185,5 @@ builder.target(Target::Stdout);
if env::var("RUST_LOG").is_ok() {
builder.parse(&env::var("RUST_LOG").unwrap());
}
builder.init().unwrap();
builder.init();
```
39 changes: 33 additions & 6 deletions env/src/lib.rs
Expand Up @@ -20,7 +20,7 @@
//! use log::Level;
//!
//! fn main() {
//! env_logger::init().unwrap();
//! env_logger::init();
//!
//! debug!("this is a debug {}", "message");
//! error!("this is printed by default");
Expand Down Expand Up @@ -194,7 +194,7 @@ pub struct Logger {
/// builder.parse(&env::var("RUST_LOG").unwrap());
/// }
///
/// builder.init().unwrap();
/// builder.init();
///
/// error!("error message");
/// info!("info message");
Expand Down Expand Up @@ -273,15 +273,27 @@ impl Builder {
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization
/// attempts will return an error.
pub fn init(&mut self) -> Result<(), SetLoggerError> {
log::set_logger(|max_level| {
/// attempts will return error.
pub fn try_init(&mut self) -> Result<(), SetLoggerError> {
log::try_set_logger(|max_level| {
let logger = self.build();
max_level.set(logger.filter());
Box::new(logger)
})
}

/// Initializes the global logger with an env logger.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization
/// attempts will panic.
pub fn init(&mut self) {
let logger = self.build();
let filter = logger.filter();
let logger = Box::new(logger);
log::set_logger(logger, filter);
}

/// Build an env logger.
pub fn build(&mut self) -> Logger {
if self.directives.is_empty() {
Expand Down Expand Up @@ -375,7 +387,22 @@ struct Directive {
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
pub fn init() -> Result<(), SetLoggerError> {
pub fn try_init() -> Result<(), SetLoggerError> {
let mut builder = Builder::new();

if let Ok(s) = env::var("RUST_LOG") {
builder.parse(&s);
}

builder.try_init()
}

/// Initializes the global logger with an env logger.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will panic.
pub fn init() {
let mut builder = Builder::new();

if let Ok(s) = env::var("RUST_LOG") {
Expand Down
2 changes: 1 addition & 1 deletion env/tests/regexp_filter.rs
Expand Up @@ -14,7 +14,7 @@ fn main() {
}

fn child_main() {
env_logger::init().unwrap();
env_logger::init();
info!("XYZ Message");
}

Expand Down
50 changes: 37 additions & 13 deletions src/lib.rs
Expand Up @@ -83,7 +83,7 @@
//! fn main() {
//! // Select env_logger, one possible logger implementation
//! // (see https://doc.rust-lang.org/log/env_logger/index.html)
//! env_logger::init().unwrap();
//! env_logger::init();
//!
//! info!("starting up");
//! error!("error: {}", 404);
Expand Down Expand Up @@ -162,11 +162,10 @@
//! # }
//! # fn main() {}
//! # #[cfg(feature = "use_std")]
//! pub fn init() -> Result<(), SetLoggerError> {
//! log::set_logger(|max_level| {
//! max_level.set(LevelFilter::Info);
//! Box::new(SimpleLogger)
//! })
//! pub fn init() {
//! let filter = LevelFilter::Info;
//! let logger = Box::new(SimpleLogger);
//! log::set_logger(logger, filter);
//! }
//! ```
//!
Expand All @@ -192,7 +191,7 @@
//! # fn flush(&self) {}
//! # }
//! # fn main() {}
//! pub fn init() -> Result<(), SetLoggerError> {
//! pub fn try_init() -> Result<(), SetLoggerError> {
//! unsafe {
//! log::set_logger_raw(|max_level| {
//! static LOGGER: SimpleLogger = SimpleLogger;
Expand Down Expand Up @@ -855,12 +854,12 @@ pub fn max_level() -> LevelFilter {
/// highest log level that the logger will not ignore.
///
/// This function may only be called once in the lifetime of a program. Any log
/// events that occur before the call to `set_logger` completes will be
/// events that occur before the call to `try_set_logger` completes will be
/// ignored.
///
/// This function does not typically need to be called manually. Logger
/// implementations should provide an initialization method that calls
/// `set_logger` internally.
/// `try_set_logger` internally.
///
/// Requires the `use_std` feature (enabled by default).
///
Expand Down Expand Up @@ -895,11 +894,11 @@ pub fn max_level() -> LevelFilter {
/// }
/// }
///
/// fn init() -> Result<(), SetLoggerError> {
/// log::set_logger(|max_log_level| {
/// fn try_init() -> Result<(), SetLoggerError> {
/// log::try_set_logger(|max_log_level| {
/// max_log_level.set(LevelFilter::Info);
/// Box::new(ConsoleLogger)
/// })?;
/// });
///
/// info!("hello log");
/// warn!("warning");
Expand All @@ -912,12 +911,37 @@ pub fn max_level() -> LevelFilter {
///
/// [`Log`]: trait.Log.html
#[cfg(feature = "use_std")]
pub fn set_logger<M>(make_logger: M) -> Result<(), SetLoggerError>
pub fn try_set_logger<M>(make_logger: M) -> Result<(), SetLoggerError>
where M: FnOnce(MaxLevelFilter) -> Box<Log>
{
unsafe { set_logger_raw(|max_level| mem::transmute(make_logger(max_level))) }
}

/// Sets the global logger.
///
/// This function may only be called once in the lifetime of a program. Any log
/// events that occur before the call to `set_logger` completes will be
/// ignored.
///
/// This function will panic on future initialization attempts.
///
/// This function does not typically need to be called manually. Logger
/// implementations should provide an initialization method that calls
/// `set_logger` internally.
///
/// Requires the `use_std` feature (enabled by default).
///
/// # Panics
///
/// The function will panic if it is called more than once.
#[cfg(feature = "use_std")]
pub fn set_logger(logger: Box<Log>, filter: LevelFilter) {
match try_set_logger(|max| { max.set(filter); logger }) {
Ok(()) => {}
Err(_) => panic!("global logger is already initialized"),
}
}

/// Sets the global logger from a raw pointer.
///
/// This function is similar to [`set_logger`] except that it is usable in
Expand Down
21 changes: 10 additions & 11 deletions tests/filters.rs
Expand Up @@ -6,9 +6,9 @@ use log::{Level, LevelFilter, Log, Record, Metadata};
use log::MaxLevelFilter;

#[cfg(feature = "use_std")]
use log::set_logger;
use log::try_set_logger;
#[cfg(not(feature = "use_std"))]
fn set_logger<M>(make_logger: M) -> Result<(), log::SetLoggerError>
fn try_set_logger<M>(make_logger: M) -> Result<(), log::SetLoggerError>
where M: FnOnce(MaxLevelFilter) -> Box<Log>
{
unsafe { log::set_logger_raw(|x| std::mem::transmute(make_logger(x))) }
Expand All @@ -33,15 +33,14 @@ impl Log for Logger {

fn main() {
let mut a = None;
set_logger(|max| {
let me = Arc::new(State {
last_log: Mutex::new(None),
filter: max,
});
a = Some(me.clone());
Box::new(Logger(me))
})
.unwrap();
try_set_logger(|max| {
let me = Arc::new(State {
last_log: Mutex::new(None),
filter: max,
});
a = Some(me.clone());
Box::new(Logger(me))
}).unwrap();
let a = a.unwrap();

test(&a, LevelFilter::Off);
Expand Down
9 changes: 5 additions & 4 deletions tests/max_level_features/main.rs
@@ -1,13 +1,14 @@
#[macro_use] extern crate log;
#[macro_use]
extern crate log;

use std::sync::{Arc, Mutex};
use log::{Level, LevelFilter, Log, Record, Metadata};
use log::MaxLevelFilter;

#[cfg(feature = "use_std")]
use log::set_logger;
use log::try_set_logger;
#[cfg(not(feature = "use_std"))]
fn set_logger<M>(make_logger: M) -> Result<(), log::SetLoggerError>
fn try_set_logger<M>(make_logger: M) -> Result<(), log::SetLoggerError>
where M: FnOnce(MaxLevelFilter) -> Box<Log> {
unsafe {
log::set_logger_raw(|x| std::mem::transmute(make_logger(x)))
Expand All @@ -33,7 +34,7 @@ impl Log for Logger {

fn main() {
let mut a = None;
set_logger(|max| {
try_set_logger(|max| {
let me = Arc::new(State {
last_log: Mutex::new(None),
filter: max,
Expand Down

0 comments on commit f21e9e8

Please sign in to comment.