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