1 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 2 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license 3 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your 4 // option. This file may not be copied, modified, or distributed 5 // except according to those terms. 6 7 //! A simple logger that can be configured via environment variables, for use 8 //! with the logging facade exposed by the [`log` crate][log-crate-url]. 9 //! 10 //! Despite having "env" in its name, **`env_logger`** can also be configured by 11 //! other means besides environment variables. See [the examples][gh-repo-examples] 12 //! in the source repository for more approaches. 13 //! 14 //! By default, `env_logger` writes logs to `stderr`, but can be configured to 15 //! instead write them to `stdout`. 16 //! 17 //! ## Example 18 //! 19 //! ``` 20 //! use log::{debug, error, log_enabled, info, Level}; 21 //! 22 //! env_logger::init(); 23 //! 24 //! debug!("this is a debug {}", "message"); 25 //! error!("this is printed by default"); 26 //! 27 //! if log_enabled!(Level::Info) { 28 //! let x = 3 * 4; // expensive computation 29 //! info!("the answer was: {}", x); 30 //! } 31 //! ``` 32 //! 33 //! Assumes the binary is `main`: 34 //! 35 //! ```{.bash} 36 //! $ RUST_LOG=error ./main 37 //! [2017-11-09T02:12:24Z ERROR main] this is printed by default 38 //! ``` 39 //! 40 //! ```{.bash} 41 //! $ RUST_LOG=info ./main 42 //! [2017-11-09T02:12:24Z ERROR main] this is printed by default 43 //! [2017-11-09T02:12:24Z INFO main] the answer was: 12 44 //! ``` 45 //! 46 //! ```{.bash} 47 //! $ RUST_LOG=debug ./main 48 //! [2017-11-09T02:12:24Z DEBUG main] this is a debug message 49 //! [2017-11-09T02:12:24Z ERROR main] this is printed by default 50 //! [2017-11-09T02:12:24Z INFO main] the answer was: 12 51 //! ``` 52 //! 53 //! You can also set the log level on a per module basis: 54 //! 55 //! ```{.bash} 56 //! $ RUST_LOG=main=info ./main 57 //! [2017-11-09T02:12:24Z ERROR main] this is printed by default 58 //! [2017-11-09T02:12:24Z INFO main] the answer was: 12 59 //! ``` 60 //! 61 //! And enable all logging: 62 //! 63 //! ```{.bash} 64 //! $ RUST_LOG=main ./main 65 //! [2017-11-09T02:12:24Z DEBUG main] this is a debug message 66 //! [2017-11-09T02:12:24Z ERROR main] this is printed by default 67 //! [2017-11-09T02:12:24Z INFO main] the answer was: 12 68 //! ``` 69 //! 70 //! If the binary name contains hyphens, you will need to replace 71 //! them with underscores: 72 //! 73 //! ```{.bash} 74 //! $ RUST_LOG=my_app ./my-app 75 //! [2017-11-09T02:12:24Z DEBUG my_app] this is a debug message 76 //! [2017-11-09T02:12:24Z ERROR my_app] this is printed by default 77 //! [2017-11-09T02:12:24Z INFO my_app] the answer was: 12 78 //! ``` 79 //! 80 //! This is because Rust modules and crates cannot contain hyphens 81 //! in their name, although `cargo` continues to accept them. 82 //! 83 //! See the documentation for the [`log` crate][log-crate-url] for more 84 //! information about its API. 85 //! 86 //! ## Enabling logging 87 //! 88 //! **By default all logging is disabled except for the `error` level** 89 //! 90 //! The **`RUST_LOG`** environment variable controls logging with the syntax: 91 //! ```text 92 //! RUST_LOG=[target][=][level][,...] 93 //! ``` 94 //! Or in other words, its a comma-separated list of directives. 95 //! Directives can filter by **target**, by **level**, or both (using `=`). 96 //! 97 //! For example, 98 //! ```text 99 //! RUST_LOG=data=debug,hardware=debug 100 //! ``` 101 //! 102 //! **target** is typically the path of the module the message 103 //! in question originated from, though it can be overridden. 104 //! The path is rooted in the name of the crate it was compiled for, so if 105 //! your program is in a file called, for example, `hello.rs`, the path would 106 //! simply be `hello`. 107 //! 108 //! Furthermore, the log can be filtered using prefix-search based on the 109 //! specified log target. 110 //! 111 //! For example, `RUST_LOG=example` would match the following targets: 112 //! - `example` 113 //! - `example::test` 114 //! - `example::test::module::submodule` 115 //! - `examples::and_more_examples` 116 //! 117 //! When providing the crate name or a module path, explicitly specifying the 118 //! log level is optional. If omitted, all logging for the item will be 119 //! enabled. 120 //! 121 //! **level** is the maximum [`log::Level`][level-enum] to be shown and includes: 122 //! - `error` 123 //! - `warn` 124 //! - `info` 125 //! - `debug` 126 //! - `trace` 127 //! - `off` (pseudo level to disable all logging for the target) 128 //! 129 //! Logging level names are case-insensitive; e.g., 130 //! `debug`, `DEBUG`, and `dEbuG` all represent the same logging level. For 131 //! consistency, our convention is to use the lower case names. Where our docs 132 //! do use other forms, they do so in the context of specific examples, so you 133 //! won't be surprised if you see similar usage in the wild. 134 //! 135 //! Some examples of valid values of `RUST_LOG` are: 136 //! 137 //! - `RUST_LOG=hello` turns on all logging for the `hello` module 138 //! - `RUST_LOG=trace` turns on all logging for the application, regardless of its name 139 //! - `RUST_LOG=TRACE` turns on all logging for the application, regardless of its name (same as previous) 140 //! - `RUST_LOG=info` turns on all info logging 141 //! - `RUST_LOG=INFO` turns on all info logging (same as previous) 142 //! - `RUST_LOG=hello=debug` turns on debug logging for `hello` 143 //! - `RUST_LOG=hello=DEBUG` turns on debug logging for `hello` (same as previous) 144 //! - `RUST_LOG=hello,std::option` turns on `hello`, and std's option logging 145 //! - `RUST_LOG=error,hello=warn` turn on global error logging and also warn for `hello` 146 //! - `RUST_LOG=error,hello=off` turn on global error logging, but turn off logging for `hello` 147 //! - `RUST_LOG=off` turns off all logging for the application 148 //! - `RUST_LOG=OFF` turns off all logging for the application (same as previous) 149 //! 150 //! ## Filtering results 151 //! 152 //! A `RUST_LOG` directive may include a regex filter. The syntax is to append `/` 153 //! followed by a regex. Each message is checked against the regex, and is only 154 //! logged if it matches. Note that the matching is done after formatting the 155 //! log string but before adding any logging meta-data. There is a single filter 156 //! for all modules. 157 //! 158 //! Some examples: 159 //! 160 //! * `hello/foo` turns on all logging for the 'hello' module where the log 161 //! message includes 'foo'. 162 //! * `info/f.o` turns on all info logging where the log message includes 'foo', 163 //! 'f1o', 'fao', etc. 164 //! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the log 165 //! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc. 166 //! * `error,hello=warn/[0-9]scopes` turn on global error logging and also 167 //! warn for hello. In both cases the log message must include a single digit 168 //! number followed by 'scopes'. 169 //! 170 //! ## Capturing logs in tests 171 //! 172 //! Records logged during `cargo test` will not be captured by the test harness by default. 173 //! The [`Builder::is_test`] method can be used in unit tests to ensure logs will be captured: 174 //! 175 //! ``` 176 //! #[cfg(test)] 177 //! mod tests { 178 //! use log::info; 179 //! 180 //! fn init() { 181 //! let _ = env_logger::builder().is_test(true).try_init(); 182 //! } 183 //! 184 //! #[test] 185 //! fn it_works() { 186 //! init(); 187 //! 188 //! info!("This record will be captured by `cargo test`"); 189 //! 190 //! assert_eq!(2, 1 + 1); 191 //! } 192 //! } 193 //! ``` 194 //! 195 //! Enabling test capturing comes at the expense of color and other style support 196 //! and may have performance implications. 197 //! 198 //! ## Disabling colors 199 //! 200 //! Colors and other styles can be configured with the `RUST_LOG_STYLE` 201 //! environment variable. It accepts the following values: 202 //! 203 //! * `auto` (default) will attempt to print style characters, but don't force the issue. 204 //! If the console isn't available on Windows, or if TERM=dumb, for example, then don't print colors. 205 //! * `always` will always print style characters even if they aren't supported by the terminal. 206 //! This includes emitting ANSI colors on Windows if the console API is unavailable. 207 //! * `never` will never print style characters. 208 //! 209 //! ## Tweaking the default format 210 //! 211 //! Parts of the default format can be excluded from the log output using the [`Builder`]. 212 //! The following example excludes the timestamp from the log output: 213 //! 214 //! ``` 215 //! env_logger::builder() 216 //! .format_timestamp(None) 217 //! .init(); 218 //! ``` 219 //! 220 //! ### Stability of the default format 221 //! 222 //! The default format won't optimise for long-term stability, and explicitly makes no 223 //! guarantees about the stability of its output across major, minor or patch version 224 //! bumps during `0.x`. 225 //! 226 //! If you want to capture or interpret the output of `env_logger` programmatically 227 //! then you should use a custom format. 228 //! 229 //! ### Using a custom format 230 //! 231 //! Custom formats can be provided as closures to the [`Builder`]. 232 //! These closures take a [`Formatter`][crate::fmt::Formatter] and `log::Record` as arguments: 233 //! 234 //! ``` 235 //! use std::io::Write; 236 //! 237 //! env_logger::builder() 238 //! .format(|buf, record| { 239 //! writeln!(buf, "{}: {}", record.level(), record.args()) 240 //! }) 241 //! .init(); 242 //! ``` 243 //! 244 //! See the [`fmt`] module for more details about custom formats. 245 //! 246 //! ## Specifying defaults for environment variables 247 //! 248 //! `env_logger` can read configuration from environment variables. 249 //! If these variables aren't present, the default value to use can be tweaked with the [`Env`] type. 250 //! The following example defaults to log `warn` and above if the `RUST_LOG` environment variable 251 //! isn't set: 252 //! 253 //! ``` 254 //! use env_logger::Env; 255 //! 256 //! env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(); 257 //! ``` 258 //! 259 //! [gh-repo-examples]: https://github.com/rust-cli/env_logger/tree/main/examples 260 //! [level-enum]: https://docs.rs/log/latest/log/enum.Level.html 261 //! [log-crate-url]: https://docs.rs/log 262 //! [`Builder`]: struct.Builder.html 263 //! [`Builder::is_test`]: struct.Builder.html#method.is_test 264 //! [`Env`]: struct.Env.html 265 //! [`fmt`]: fmt/index.html 266 267 #![doc( 268 html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", 269 html_favicon_url = "https://www.rust-lang.org/static/images/favicon.ico" 270 )] 271 #![cfg_attr(docsrs, feature(doc_auto_cfg))] 272 // When compiled for the rustc compiler itself we want to make sure that this is 273 // an unstable crate 274 #![cfg_attr(rustbuild, feature(staged_api, rustc_private))] 275 #![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))] 276 #![deny(missing_debug_implementations, missing_docs)] 277 278 mod logger; 279 280 pub mod filter; 281 pub mod fmt; 282 283 pub use self::fmt::glob::*; 284 pub use self::logger::*; 285