Skip to content
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

Make log target configurable #105

Merged
merged 1 commit into from Apr 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Expand Up @@ -158,3 +158,20 @@ test tests::it_adds_one ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
```

## Configuring log target

By default, `env_logger` logs to stderr. If you want to log to stdout instead,
you can use the `LogBuilder` to change the log target:

```rust
use std::env;
use env_logger::{LogBuilder, LogTarget};

let mut builder = LogBuilder::new();
builder.target(LogTarget::Stdout);
if env::var("RUST_LOG").is_ok() {
builder.parse(&env::var("RUST_LOG").unwrap());
}
builder.init().unwrap();
```
26 changes: 25 additions & 1 deletion env/src/lib.rs
Expand Up @@ -152,11 +152,19 @@ mod filter;
#[path = "string.rs"]
mod filter;

/// Log target, either stdout or stderr.
#[derive(Debug)]
pub enum LogTarget {
Stdout,
Stderr,
}

/// The logger.
pub struct Logger {
directives: Vec<LogDirective>,
filter: Option<filter::Filter>,
format: Box<Fn(&LogRecord) -> String + Sync + Send>,
target: LogTarget,
}

/// LogBuilder acts as builder for initializing the Logger.
Expand Down Expand Up @@ -196,6 +204,7 @@ pub struct LogBuilder {
directives: Vec<LogDirective>,
filter: Option<filter::Filter>,
format: Box<Fn(&LogRecord) -> String + Sync + Send>,
target: LogTarget,
}

impl LogBuilder {
Expand All @@ -208,6 +217,7 @@ impl LogBuilder {
format!("{}:{}: {}", record.level(),
record.location().module_path(), record.args())
}),
target: LogTarget::Stderr,
}
}

Expand Down Expand Up @@ -236,6 +246,14 @@ impl LogBuilder {
self
}

/// Sets the target for the log output.
///
/// Env logger can log to either stdout or stderr. The default is stderr.
pub fn target(&mut self, target: LogTarget) -> &mut Self {
self.target = target;
self
}

/// Parses the directives string in the same form as the RUST_LOG
/// environment variable.
///
Expand Down Expand Up @@ -286,6 +304,7 @@ impl LogBuilder {
directives: mem::replace(&mut self.directives, Vec::new()),
filter: mem::replace(&mut self.filter, None),
format: mem::replace(&mut self.format, Box::new(|_| String::new())),
target: mem::replace(&mut self.target, LogTarget::Stderr),
}
}
}
Expand Down Expand Up @@ -337,7 +356,12 @@ impl Log for Logger {
}
}

let _ = writeln!(&mut io::stderr(), "{}", (self.format)(record));
match self.target {
LogTarget::Stdout => println!("{}", (self.format)(record)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a writeln! to io::stdout instead? There are some differences around capture in the test harness. Not sure which approach would be more expected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

writeln! with io::stdout is not being captured by the test harness according to my tests.

LogTarget::Stderr => {
let _ = writeln!(&mut io::stderr(), "{}", (self.format)(record));
},
};
}
}

Expand Down