1336d762aSopenharmony_ci# env_logger 2336d762aSopenharmony_ci 3336d762aSopenharmony_ci[](https://crates.io/crates/env_logger) 4336d762aSopenharmony_ci[](https://docs.rs/env_logger) 5336d762aSopenharmony_ci[](https://env-logger-rs.github.io/env_logger/env_logger/index.html) 6336d762aSopenharmony_ci 7336d762aSopenharmony_ciImplements a logger that can be configured via environment variables. 8336d762aSopenharmony_ci 9336d762aSopenharmony_ci## Usage 10336d762aSopenharmony_ci 11336d762aSopenharmony_ci### In libraries 12336d762aSopenharmony_ci 13336d762aSopenharmony_ci`env_logger` makes sense when used in executables (binary projects). Libraries should use the [`log`](https://docs.rs/log) crate instead. 14336d762aSopenharmony_ci 15336d762aSopenharmony_ci### In executables 16336d762aSopenharmony_ci 17336d762aSopenharmony_ciIt must be added along with `log` to the project dependencies: 18336d762aSopenharmony_ci 19336d762aSopenharmony_ci```toml 20336d762aSopenharmony_ci[dependencies] 21336d762aSopenharmony_cilog = "0.4.0" 22336d762aSopenharmony_cienv_logger = "0.9.0" 23336d762aSopenharmony_ci``` 24336d762aSopenharmony_ci 25336d762aSopenharmony_ci`env_logger` must be initialized as early as possible in the project. After it's initialized, you can use the `log` macros to do actual logging. 26336d762aSopenharmony_ci 27336d762aSopenharmony_ci```rust 28336d762aSopenharmony_ci#[macro_use] 29336d762aSopenharmony_ciextern crate log; 30336d762aSopenharmony_ci 31336d762aSopenharmony_cifn main() { 32336d762aSopenharmony_ci env_logger::init(); 33336d762aSopenharmony_ci 34336d762aSopenharmony_ci info!("starting up"); 35336d762aSopenharmony_ci 36336d762aSopenharmony_ci // ... 37336d762aSopenharmony_ci} 38336d762aSopenharmony_ci``` 39336d762aSopenharmony_ci 40336d762aSopenharmony_ciThen when running the executable, specify a value for the **`RUST_LOG`** 41336d762aSopenharmony_cienvironment variable that corresponds with the log messages you want to show. 42336d762aSopenharmony_ci 43336d762aSopenharmony_ci```bash 44336d762aSopenharmony_ci$ RUST_LOG=info ./main 45336d762aSopenharmony_ci[2018-11-03T06:09:06Z INFO default] starting up 46336d762aSopenharmony_ci``` 47336d762aSopenharmony_ci 48336d762aSopenharmony_ciThe letter case is not significant for the logging level names; e.g., `debug`, 49336d762aSopenharmony_ci`DEBUG`, and `dEbuG` all represent the same logging level. Therefore, the 50336d762aSopenharmony_ciprevious example could also have been written this way, specifying the log 51336d762aSopenharmony_cilevel as `INFO` rather than as `info`: 52336d762aSopenharmony_ci 53336d762aSopenharmony_ci```bash 54336d762aSopenharmony_ci$ RUST_LOG=INFO ./main 55336d762aSopenharmony_ci[2018-11-03T06:09:06Z INFO default] starting up 56336d762aSopenharmony_ci``` 57336d762aSopenharmony_ci 58336d762aSopenharmony_ciSo which form should you use? For consistency, our convention is to use lower 59336d762aSopenharmony_cicase names. Where our docs do use other forms, they do so in the context of 60336d762aSopenharmony_cispecific examples, so you won't be surprised if you see similar usage in the 61336d762aSopenharmony_ciwild. 62336d762aSopenharmony_ci 63336d762aSopenharmony_ciThe log levels that may be specified correspond to the [`log::Level`][level-enum] 64336d762aSopenharmony_cienum from the `log` crate. They are: 65336d762aSopenharmony_ci 66336d762aSopenharmony_ci * `error` 67336d762aSopenharmony_ci * `warn` 68336d762aSopenharmony_ci * `info` 69336d762aSopenharmony_ci * `debug` 70336d762aSopenharmony_ci * `trace` 71336d762aSopenharmony_ci 72336d762aSopenharmony_ci[level-enum]: https://docs.rs/log/latest/log/enum.Level.html "log::Level (docs.rs)" 73336d762aSopenharmony_ci 74336d762aSopenharmony_ciThere is also a pseudo logging level, `off`, which may be specified to disable 75336d762aSopenharmony_ciall logging for a given module or for the entire application. As with the 76336d762aSopenharmony_cilogging levels, the letter case is not significant. 77336d762aSopenharmony_ci 78336d762aSopenharmony_ci`env_logger` can be configured in other ways besides an environment variable. See [the examples](https://github.com/env-logger-rs/env_logger/tree/main/examples) for more approaches. 79336d762aSopenharmony_ci 80336d762aSopenharmony_ci### In tests 81336d762aSopenharmony_ci 82336d762aSopenharmony_ciTests can use the `env_logger` crate to see log messages generated during that test: 83336d762aSopenharmony_ci 84336d762aSopenharmony_ci```toml 85336d762aSopenharmony_ci[dependencies] 86336d762aSopenharmony_cilog = "0.4.0" 87336d762aSopenharmony_ci 88336d762aSopenharmony_ci[dev-dependencies] 89336d762aSopenharmony_cienv_logger = "0.9.0" 90336d762aSopenharmony_ci``` 91336d762aSopenharmony_ci 92336d762aSopenharmony_ci```rust 93336d762aSopenharmony_ci#[macro_use] 94336d762aSopenharmony_ciextern crate log; 95336d762aSopenharmony_ci 96336d762aSopenharmony_cifn add_one(num: i32) -> i32 { 97336d762aSopenharmony_ci info!("add_one called with {}", num); 98336d762aSopenharmony_ci num + 1 99336d762aSopenharmony_ci} 100336d762aSopenharmony_ci 101336d762aSopenharmony_ci#[cfg(test)] 102336d762aSopenharmony_cimod tests { 103336d762aSopenharmony_ci use super::*; 104336d762aSopenharmony_ci 105336d762aSopenharmony_ci fn init() { 106336d762aSopenharmony_ci let _ = env_logger::builder().is_test(true).try_init(); 107336d762aSopenharmony_ci } 108336d762aSopenharmony_ci 109336d762aSopenharmony_ci #[test] 110336d762aSopenharmony_ci fn it_adds_one() { 111336d762aSopenharmony_ci init(); 112336d762aSopenharmony_ci 113336d762aSopenharmony_ci info!("can log from the test too"); 114336d762aSopenharmony_ci assert_eq!(3, add_one(2)); 115336d762aSopenharmony_ci } 116336d762aSopenharmony_ci 117336d762aSopenharmony_ci #[test] 118336d762aSopenharmony_ci fn it_handles_negative_numbers() { 119336d762aSopenharmony_ci init(); 120336d762aSopenharmony_ci 121336d762aSopenharmony_ci info!("logging from another test"); 122336d762aSopenharmony_ci assert_eq!(-7, add_one(-8)); 123336d762aSopenharmony_ci } 124336d762aSopenharmony_ci} 125336d762aSopenharmony_ci``` 126336d762aSopenharmony_ci 127336d762aSopenharmony_ciAssuming the module under test is called `my_lib`, running the tests with the 128336d762aSopenharmony_ci`RUST_LOG` filtering to info messages from this module looks like: 129336d762aSopenharmony_ci 130336d762aSopenharmony_ci```bash 131336d762aSopenharmony_ci$ RUST_LOG=my_lib=info cargo test 132336d762aSopenharmony_ci Running target/debug/my_lib-... 133336d762aSopenharmony_ci 134336d762aSopenharmony_cirunning 2 tests 135336d762aSopenharmony_ci[INFO my_lib::tests] logging from another test 136336d762aSopenharmony_ci[INFO my_lib] add_one called with -8 137336d762aSopenharmony_citest tests::it_handles_negative_numbers ... ok 138336d762aSopenharmony_ci[INFO my_lib::tests] can log from the test too 139336d762aSopenharmony_ci[INFO my_lib] add_one called with 2 140336d762aSopenharmony_citest tests::it_adds_one ... ok 141336d762aSopenharmony_ci 142336d762aSopenharmony_citest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured 143336d762aSopenharmony_ci``` 144336d762aSopenharmony_ci 145336d762aSopenharmony_ciNote that `env_logger::try_init()` needs to be called in each test in which you 146336d762aSopenharmony_ciwant to enable logging. Additionally, the default behavior of tests to 147336d762aSopenharmony_cirun in parallel means that logging output may be interleaved with test output. 148336d762aSopenharmony_ciEither run tests in a single thread by specifying `RUST_TEST_THREADS=1` or by 149336d762aSopenharmony_cirunning one test by specifying its name as an argument to the test binaries as 150336d762aSopenharmony_cidirected by the `cargo test` help docs: 151336d762aSopenharmony_ci 152336d762aSopenharmony_ci```bash 153336d762aSopenharmony_ci$ RUST_LOG=my_lib=info cargo test it_adds_one 154336d762aSopenharmony_ci Running target/debug/my_lib-... 155336d762aSopenharmony_ci 156336d762aSopenharmony_cirunning 1 test 157336d762aSopenharmony_ci[INFO my_lib::tests] can log from the test too 158336d762aSopenharmony_ci[INFO my_lib] add_one called with 2 159336d762aSopenharmony_citest tests::it_adds_one ... ok 160336d762aSopenharmony_ci 161336d762aSopenharmony_citest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured 162336d762aSopenharmony_ci``` 163336d762aSopenharmony_ci 164336d762aSopenharmony_ci## Configuring log target 165336d762aSopenharmony_ci 166336d762aSopenharmony_ciBy default, `env_logger` logs to stderr. If you want to log to stdout instead, 167336d762aSopenharmony_ciyou can use the `Builder` to change the log target: 168336d762aSopenharmony_ci 169336d762aSopenharmony_ci```rust 170336d762aSopenharmony_ciuse std::env; 171336d762aSopenharmony_ciuse env_logger::{Builder, Target}; 172336d762aSopenharmony_ci 173336d762aSopenharmony_cilet mut builder = Builder::from_default_env(); 174336d762aSopenharmony_cibuilder.target(Target::Stdout); 175336d762aSopenharmony_ci 176336d762aSopenharmony_cibuilder.init(); 177336d762aSopenharmony_ci``` 178336d762aSopenharmony_ci 179336d762aSopenharmony_ci## Stability of the default format 180336d762aSopenharmony_ci 181336d762aSopenharmony_ciThe default format won't optimise for long-term stability, and explicitly makes no guarantees about the stability of its output across major, minor or patch version bumps during `0.x`. 182336d762aSopenharmony_ci 183336d762aSopenharmony_ciIf you want to capture or interpret the output of `env_logger` programmatically then you should use a custom format. 184