/rust/registry/src/index.crates.io-6f17d22bba15001f/env_logger-0.9.0/src/lib.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT |
2 | | // file at the top-level directory of this distribution and at |
3 | | // http://rust-lang.org/COPYRIGHT. |
4 | | // |
5 | | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
6 | | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
7 | | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
8 | | // option. This file may not be copied, modified, or distributed |
9 | | // except according to those terms. |
10 | | |
11 | | //! A simple logger that can be configured via environment variables, for use |
12 | | //! with the logging facade exposed by the [`log` crate][log-crate-url]. |
13 | | //! |
14 | | //! Despite having "env" in its name, **`env_logger`** can also be configured by |
15 | | //! other means besides environment variables. See [the examples][gh-repo-examples] |
16 | | //! in the source repository for more approaches. |
17 | | //! |
18 | | //! By default, `env_logger` writes logs to `stderr`, but can be configured to |
19 | | //! instead write them to `stdout`. |
20 | | //! |
21 | | //! ## Example |
22 | | //! |
23 | | //! ``` |
24 | | //! use log::{debug, error, log_enabled, info, Level}; |
25 | | //! |
26 | | //! env_logger::init(); |
27 | | //! |
28 | | //! debug!("this is a debug {}", "message"); |
29 | | //! error!("this is printed by default"); |
30 | | //! |
31 | | //! if log_enabled!(Level::Info) { |
32 | | //! let x = 3 * 4; // expensive computation |
33 | | //! info!("the answer was: {}", x); |
34 | | //! } |
35 | | //! ``` |
36 | | //! |
37 | | //! Assumes the binary is `main`: |
38 | | //! |
39 | | //! ```{.bash} |
40 | | //! $ RUST_LOG=error ./main |
41 | | //! [2017-11-09T02:12:24Z ERROR main] this is printed by default |
42 | | //! ``` |
43 | | //! |
44 | | //! ```{.bash} |
45 | | //! $ RUST_LOG=info ./main |
46 | | //! [2017-11-09T02:12:24Z ERROR main] this is printed by default |
47 | | //! [2017-11-09T02:12:24Z INFO main] the answer was: 12 |
48 | | //! ``` |
49 | | //! |
50 | | //! ```{.bash} |
51 | | //! $ RUST_LOG=debug ./main |
52 | | //! [2017-11-09T02:12:24Z DEBUG main] this is a debug message |
53 | | //! [2017-11-09T02:12:24Z ERROR main] this is printed by default |
54 | | //! [2017-11-09T02:12:24Z INFO main] the answer was: 12 |
55 | | //! ``` |
56 | | //! |
57 | | //! You can also set the log level on a per module basis: |
58 | | //! |
59 | | //! ```{.bash} |
60 | | //! $ RUST_LOG=main=info ./main |
61 | | //! [2017-11-09T02:12:24Z ERROR main] this is printed by default |
62 | | //! [2017-11-09T02:12:24Z INFO main] the answer was: 12 |
63 | | //! ``` |
64 | | //! |
65 | | //! And enable all logging: |
66 | | //! |
67 | | //! ```{.bash} |
68 | | //! $ RUST_LOG=main ./main |
69 | | //! [2017-11-09T02:12:24Z DEBUG main] this is a debug message |
70 | | //! [2017-11-09T02:12:24Z ERROR main] this is printed by default |
71 | | //! [2017-11-09T02:12:24Z INFO main] the answer was: 12 |
72 | | //! ``` |
73 | | //! |
74 | | //! If the binary name contains hyphens, you will need to replace |
75 | | //! them with underscores: |
76 | | //! |
77 | | //! ```{.bash} |
78 | | //! $ RUST_LOG=my_app ./my-app |
79 | | //! [2017-11-09T02:12:24Z DEBUG my_app] this is a debug message |
80 | | //! [2017-11-09T02:12:24Z ERROR my_app] this is printed by default |
81 | | //! [2017-11-09T02:12:24Z INFO my_app] the answer was: 12 |
82 | | //! ``` |
83 | | //! |
84 | | //! This is because Rust modules and crates cannot contain hyphens |
85 | | //! in their name, although `cargo` continues to accept them. |
86 | | //! |
87 | | //! See the documentation for the [`log` crate][log-crate-url] for more |
88 | | //! information about its API. |
89 | | //! |
90 | | //! ## Enabling logging |
91 | | //! |
92 | | //! Log levels are controlled on a per-module basis, and **by default all |
93 | | //! logging is disabled except for the `error` level**. |
94 | | //! |
95 | | //! Logging is controlled via the **`RUST_LOG`** environment variable. The |
96 | | //! value of this environment variable is a comma-separated list of *logging |
97 | | //! directives*. A logging directive is of the form: |
98 | | //! |
99 | | //! ```text |
100 | | //! example::log::target=level |
101 | | //! ``` |
102 | | //! |
103 | | //! The log target is typically equal to the path of the module the message |
104 | | //! in question originated from, though it can be overriden. |
105 | | //! |
106 | | //! The path is rooted in the name of the crate it was compiled for, so if |
107 | | //! your program is in a file called, for example, `hello.rs`, the path would |
108 | | //! simply be be `hello`. |
109 | | //! |
110 | | //! Furthermore, the the log can be filtered using prefix-search based on the |
111 | | //! specified log target. A value of, for example, `RUST_LOG=example`, would |
112 | | //! match all of the messages with targets: |
113 | | //! |
114 | | //! * `example` |
115 | | //! * `example::test` |
116 | | //! * `example::test::module::submodule` |
117 | | //! * `examples::and_more_examples` |
118 | | //! |
119 | | //! When providing the crate name or a module path, explicitly specifying the |
120 | | //! log level is optional. If omitted, all logging for the item will be |
121 | | //! enabled. |
122 | | //! |
123 | | //! The names of the log levels that may be specified correspond to the |
124 | | //! variations of the [`log::Level`][level-enum] enum from the `log` |
125 | | //! crate. They are: |
126 | | //! |
127 | | //! * `error` |
128 | | //! * `warn` |
129 | | //! * `info` |
130 | | //! * `debug` |
131 | | //! * `trace` |
132 | | //! |
133 | | //! There is also a pseudo logging level, `off`, which may be specified to |
134 | | //! disable all logging for a given module or for the entire application. As |
135 | | //! with the logging levels, the letter case is not significant[^fn-off]. |
136 | | //! |
137 | | //! [^fn-off]: Similar to the universe of log level names, the `off` pseudo |
138 | | //! log level feature is also provided by the underlying `log` crate. |
139 | | //! |
140 | | //! The letter case is not significant for the logging level names; e.g., |
141 | | //! `debug`, `DEBUG`, and `dEbuG` all represent the same logging level. For |
142 | | //! consistency, our convention is to use the lower case names. Where our docs |
143 | | //! do use other forms, they do so in the context of specific examples, so you |
144 | | //! won't be surprised if you see similar usage in the wild. |
145 | | //! |
146 | | //! As the log level for a module is optional, the module to enable logging for |
147 | | //! is also optional. **If only a level is provided, then the global log |
148 | | //! level for all modules is set to this value.** |
149 | | //! |
150 | | //! Some examples of valid values of `RUST_LOG` are: |
151 | | //! |
152 | | //! * `hello` turns on all logging for the 'hello' module |
153 | | //! * `trace` turns on all logging for the application, regardless of its name |
154 | | //! * `TRACE` turns on all logging for the application, regardless of its name (same as previous) |
155 | | //! * `info` turns on all info logging |
156 | | //! * `INFO` turns on all info logging (same as previous) |
157 | | //! * `hello=debug` turns on debug logging for 'hello' |
158 | | //! * `hello=DEBUG` turns on debug logging for 'hello' (same as previous) |
159 | | //! * `hello,std::option` turns on hello, and std's option logging |
160 | | //! * `error,hello=warn` turn on global error logging and also warn for hello |
161 | | //! * `error,hello=off` turn on global error logging, but turn off logging for hello |
162 | | //! * `off` turns off all logging for the application |
163 | | //! * `OFF` turns off all logging for the application (same as previous) |
164 | | //! |
165 | | //! ## Filtering results |
166 | | //! |
167 | | //! A `RUST_LOG` directive may include a regex filter. The syntax is to append `/` |
168 | | //! followed by a regex. Each message is checked against the regex, and is only |
169 | | //! logged if it matches. Note that the matching is done after formatting the |
170 | | //! log string but before adding any logging meta-data. There is a single filter |
171 | | //! for all modules. |
172 | | //! |
173 | | //! Some examples: |
174 | | //! |
175 | | //! * `hello/foo` turns on all logging for the 'hello' module where the log |
176 | | //! message includes 'foo'. |
177 | | //! * `info/f.o` turns on all info logging where the log message includes 'foo', |
178 | | //! 'f1o', 'fao', etc. |
179 | | //! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the log |
180 | | //! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc. |
181 | | //! * `error,hello=warn/[0-9]scopes` turn on global error logging and also |
182 | | //! warn for hello. In both cases the log message must include a single digit |
183 | | //! number followed by 'scopes'. |
184 | | //! |
185 | | //! ## Capturing logs in tests |
186 | | //! |
187 | | //! Records logged during `cargo test` will not be captured by the test harness by default. |
188 | | //! The [`Builder::is_test`] method can be used in unit tests to ensure logs will be captured: |
189 | | //! |
190 | | //! ``` |
191 | | //! # #[macro_use] extern crate log; |
192 | | //! #[cfg(test)] |
193 | | //! mod tests { |
194 | | //! fn init() { |
195 | | //! let _ = env_logger::builder().is_test(true).try_init(); |
196 | | //! } |
197 | | //! |
198 | | //! #[test] |
199 | | //! fn it_works() { |
200 | | //! init(); |
201 | | //! |
202 | | //! info!("This record will be captured by `cargo test`"); |
203 | | //! |
204 | | //! assert_eq!(2, 1 + 1); |
205 | | //! } |
206 | | //! } |
207 | | //! ``` |
208 | | //! |
209 | | //! Enabling test capturing comes at the expense of color and other style support |
210 | | //! and may have performance implications. |
211 | | //! |
212 | | //! ## Disabling colors |
213 | | //! |
214 | | //! Colors and other styles can be configured with the `RUST_LOG_STYLE` |
215 | | //! environment variable. It accepts the following values: |
216 | | //! |
217 | | //! * `auto` (default) will attempt to print style characters, but don't force the issue. |
218 | | //! If the console isn't available on Windows, or if TERM=dumb, for example, then don't print colors. |
219 | | //! * `always` will always print style characters even if they aren't supported by the terminal. |
220 | | //! This includes emitting ANSI colors on Windows if the console API is unavailable. |
221 | | //! * `never` will never print style characters. |
222 | | //! |
223 | | //! ## Tweaking the default format |
224 | | //! |
225 | | //! Parts of the default format can be excluded from the log output using the [`Builder`]. |
226 | | //! The following example excludes the timestamp from the log output: |
227 | | //! |
228 | | //! ``` |
229 | | //! env_logger::builder() |
230 | | //! .format_timestamp(None) |
231 | | //! .init(); |
232 | | //! ``` |
233 | | //! |
234 | | //! ### Stability of the default format |
235 | | //! |
236 | | //! The default format won't optimise for long-term stability, and explicitly makes no |
237 | | //! guarantees about the stability of its output across major, minor or patch version |
238 | | //! bumps during `0.x`. |
239 | | //! |
240 | | //! If you want to capture or interpret the output of `env_logger` programmatically |
241 | | //! then you should use a custom format. |
242 | | //! |
243 | | //! ### Using a custom format |
244 | | //! |
245 | | //! Custom formats can be provided as closures to the [`Builder`]. |
246 | | //! These closures take a [`Formatter`] and `log::Record` as arguments: |
247 | | //! |
248 | | //! ``` |
249 | | //! use std::io::Write; |
250 | | //! |
251 | | //! env_logger::builder() |
252 | | //! .format(|buf, record| { |
253 | | //! writeln!(buf, "{}: {}", record.level(), record.args()) |
254 | | //! }) |
255 | | //! .init(); |
256 | | //! ``` |
257 | | //! |
258 | | //! See the [`fmt`] module for more details about custom formats. |
259 | | //! |
260 | | //! ## Specifying defaults for environment variables |
261 | | //! |
262 | | //! `env_logger` can read configuration from environment variables. |
263 | | //! If these variables aren't present, the default value to use can be tweaked with the [`Env`] type. |
264 | | //! The following example defaults to log `warn` and above if the `RUST_LOG` environment variable |
265 | | //! isn't set: |
266 | | //! |
267 | | //! ``` |
268 | | //! use env_logger::Env; |
269 | | //! |
270 | | //! env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(); |
271 | | //! ``` |
272 | | //! |
273 | | //! [gh-repo-examples]: https://github.com/env-logger-rs/env_logger/tree/main/examples |
274 | | //! [level-enum]: https://docs.rs/log/latest/log/enum.Level.html |
275 | | //! [log-crate-url]: https://docs.rs/log/ |
276 | | //! [`Builder`]: struct.Builder.html |
277 | | //! [`Builder::is_test`]: struct.Builder.html#method.is_test |
278 | | //! [`Env`]: struct.Env.html |
279 | | //! [`fmt`]: fmt/index.html |
280 | | |
281 | | #![doc( |
282 | | html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", |
283 | | html_favicon_url = "https://www.rust-lang.org/static/images/favicon.ico" |
284 | | )] |
285 | | // When compiled for the rustc compiler itself we want to make sure that this is |
286 | | // an unstable crate |
287 | | #![cfg_attr(rustbuild, feature(staged_api, rustc_private))] |
288 | | #![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))] |
289 | | #![deny(missing_debug_implementations, missing_docs)] |
290 | | |
291 | | use std::{borrow::Cow, cell::RefCell, env, io}; |
292 | | |
293 | | use log::{LevelFilter, Log, Metadata, Record, SetLoggerError}; |
294 | | |
295 | | pub mod filter; |
296 | | pub mod fmt; |
297 | | |
298 | | pub use self::fmt::glob::*; |
299 | | |
300 | | use self::filter::Filter; |
301 | | use self::fmt::writer::{self, Writer}; |
302 | | use self::fmt::{FormatFn, Formatter}; |
303 | | |
304 | | /// The default name for the environment variable to read filters from. |
305 | | pub const DEFAULT_FILTER_ENV: &str = "RUST_LOG"; |
306 | | |
307 | | /// The default name for the environment variable to read style preferences from. |
308 | | pub const DEFAULT_WRITE_STYLE_ENV: &str = "RUST_LOG_STYLE"; |
309 | | |
310 | | /// Set of environment variables to configure from. |
311 | | /// |
312 | | /// # Default environment variables |
313 | | /// |
314 | | /// By default, the `Env` will read the following environment variables: |
315 | | /// |
316 | | /// - `RUST_LOG`: the level filter |
317 | | /// - `RUST_LOG_STYLE`: whether or not to print styles with records. |
318 | | /// |
319 | | /// These sources can be configured using the builder methods on `Env`. |
320 | | #[derive(Debug)] |
321 | | pub struct Env<'a> { |
322 | | filter: Var<'a>, |
323 | | write_style: Var<'a>, |
324 | | } |
325 | | |
326 | | #[derive(Debug)] |
327 | | struct Var<'a> { |
328 | | name: Cow<'a, str>, |
329 | | default: Option<Cow<'a, str>>, |
330 | | } |
331 | | |
332 | | /// The env logger. |
333 | | /// |
334 | | /// This struct implements the `Log` trait from the [`log` crate][log-crate-url], |
335 | | /// which allows it to act as a logger. |
336 | | /// |
337 | | /// The [`init()`], [`try_init()`], [`Builder::init()`] and [`Builder::try_init()`] |
338 | | /// methods will each construct a `Logger` and immediately initialize it as the |
339 | | /// default global logger. |
340 | | /// |
341 | | /// If you'd instead need access to the constructed `Logger`, you can use |
342 | | /// the associated [`Builder`] and install it with the |
343 | | /// [`log` crate][log-crate-url] directly. |
344 | | /// |
345 | | /// [log-crate-url]: https://docs.rs/log/ |
346 | | /// [`init()`]: fn.init.html |
347 | | /// [`try_init()`]: fn.try_init.html |
348 | | /// [`Builder::init()`]: struct.Builder.html#method.init |
349 | | /// [`Builder::try_init()`]: struct.Builder.html#method.try_init |
350 | | /// [`Builder`]: struct.Builder.html |
351 | | pub struct Logger { |
352 | | writer: Writer, |
353 | | filter: Filter, |
354 | | format: FormatFn, |
355 | | } |
356 | | |
357 | | /// `Builder` acts as builder for initializing a `Logger`. |
358 | | /// |
359 | | /// It can be used to customize the log format, change the environment variable used |
360 | | /// to provide the logging directives and also set the default log level filter. |
361 | | /// |
362 | | /// # Examples |
363 | | /// |
364 | | /// ``` |
365 | | /// # #[macro_use] extern crate log; |
366 | | /// # use std::io::Write; |
367 | | /// use env_logger::Builder; |
368 | | /// use log::LevelFilter; |
369 | | /// |
370 | | /// let mut builder = Builder::from_default_env(); |
371 | | /// |
372 | | /// builder |
373 | | /// .format(|buf, record| writeln!(buf, "{} - {}", record.level(), record.args())) |
374 | | /// .filter(None, LevelFilter::Info) |
375 | | /// .init(); |
376 | | /// |
377 | | /// error!("error message"); |
378 | | /// info!("info message"); |
379 | | /// ``` |
380 | | #[derive(Default)] |
381 | | pub struct Builder { |
382 | | filter: filter::Builder, |
383 | | writer: writer::Builder, |
384 | | format: fmt::Builder, |
385 | | built: bool, |
386 | | } |
387 | | |
388 | | impl Builder { |
389 | | /// Initializes the log builder with defaults. |
390 | | /// |
391 | | /// **NOTE:** This method won't read from any environment variables. |
392 | | /// Use the [`filter`] and [`write_style`] methods to configure the builder |
393 | | /// or use [`from_env`] or [`from_default_env`] instead. |
394 | | /// |
395 | | /// # Examples |
396 | | /// |
397 | | /// Create a new builder and configure filters and style: |
398 | | /// |
399 | | /// ``` |
400 | | /// use log::LevelFilter; |
401 | | /// use env_logger::{Builder, WriteStyle}; |
402 | | /// |
403 | | /// let mut builder = Builder::new(); |
404 | | /// |
405 | | /// builder |
406 | | /// .filter(None, LevelFilter::Info) |
407 | | /// .write_style(WriteStyle::Always) |
408 | | /// .init(); |
409 | | /// ``` |
410 | | /// |
411 | | /// [`filter`]: #method.filter |
412 | | /// [`write_style`]: #method.write_style |
413 | | /// [`from_env`]: #method.from_env |
414 | | /// [`from_default_env`]: #method.from_default_env |
415 | 0 | pub fn new() -> Builder { |
416 | 0 | Default::default() |
417 | 0 | } |
418 | | |
419 | | /// Initializes the log builder from the environment. |
420 | | /// |
421 | | /// The variables used to read configuration from can be tweaked before |
422 | | /// passing in. |
423 | | /// |
424 | | /// # Examples |
425 | | /// |
426 | | /// Initialise a logger reading the log filter from an environment variable |
427 | | /// called `MY_LOG`: |
428 | | /// |
429 | | /// ``` |
430 | | /// use env_logger::Builder; |
431 | | /// |
432 | | /// let mut builder = Builder::from_env("MY_LOG"); |
433 | | /// builder.init(); |
434 | | /// ``` |
435 | | /// |
436 | | /// Initialise a logger using the `MY_LOG` variable for filtering and |
437 | | /// `MY_LOG_STYLE` for whether or not to write styles: |
438 | | /// |
439 | | /// ``` |
440 | | /// use env_logger::{Builder, Env}; |
441 | | /// |
442 | | /// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); |
443 | | /// |
444 | | /// let mut builder = Builder::from_env(env); |
445 | | /// builder.init(); |
446 | | /// ``` |
447 | 0 | pub fn from_env<'a, E>(env: E) -> Self |
448 | 0 | where |
449 | 0 | E: Into<Env<'a>>, |
450 | 0 | { |
451 | 0 | let mut builder = Builder::new(); |
452 | 0 | builder.parse_env(env); |
453 | 0 | builder |
454 | 0 | } |
455 | | |
456 | | /// Applies the configuration from the environment. |
457 | | /// |
458 | | /// This function allows a builder to be configured with default parameters, |
459 | | /// to be then overridden by the environment. |
460 | | /// |
461 | | /// # Examples |
462 | | /// |
463 | | /// Initialise a logger with filter level `Off`, then override the log |
464 | | /// filter from an environment variable called `MY_LOG`: |
465 | | /// |
466 | | /// ``` |
467 | | /// use log::LevelFilter; |
468 | | /// use env_logger::Builder; |
469 | | /// |
470 | | /// let mut builder = Builder::new(); |
471 | | /// |
472 | | /// builder.filter_level(LevelFilter::Off); |
473 | | /// builder.parse_env("MY_LOG"); |
474 | | /// builder.init(); |
475 | | /// ``` |
476 | | /// |
477 | | /// Initialise a logger with filter level `Off`, then use the `MY_LOG` |
478 | | /// variable to override filtering and `MY_LOG_STYLE` to override whether |
479 | | /// or not to write styles: |
480 | | /// |
481 | | /// ``` |
482 | | /// use log::LevelFilter; |
483 | | /// use env_logger::{Builder, Env}; |
484 | | /// |
485 | | /// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); |
486 | | /// |
487 | | /// let mut builder = Builder::new(); |
488 | | /// builder.filter_level(LevelFilter::Off); |
489 | | /// builder.parse_env(env); |
490 | | /// builder.init(); |
491 | | /// ``` |
492 | 0 | pub fn parse_env<'a, E>(&mut self, env: E) -> &mut Self |
493 | 0 | where |
494 | 0 | E: Into<Env<'a>>, |
495 | 0 | { |
496 | 0 | let env = env.into(); |
497 | | |
498 | 0 | if let Some(s) = env.get_filter() { |
499 | 0 | self.parse_filters(&s); |
500 | 0 | } |
501 | | |
502 | 0 | if let Some(s) = env.get_write_style() { |
503 | 0 | self.parse_write_style(&s); |
504 | 0 | } |
505 | | |
506 | 0 | self |
507 | 0 | } |
508 | | |
509 | | /// Initializes the log builder from the environment using default variable names. |
510 | | /// |
511 | | /// This method is a convenient way to call `from_env(Env::default())` without |
512 | | /// having to use the `Env` type explicitly. The builder will use the |
513 | | /// [default environment variables]. |
514 | | /// |
515 | | /// # Examples |
516 | | /// |
517 | | /// Initialise a logger using the default environment variables: |
518 | | /// |
519 | | /// ``` |
520 | | /// use env_logger::Builder; |
521 | | /// |
522 | | /// let mut builder = Builder::from_default_env(); |
523 | | /// builder.init(); |
524 | | /// ``` |
525 | | /// |
526 | | /// [default environment variables]: struct.Env.html#default-environment-variables |
527 | 0 | pub fn from_default_env() -> Self { |
528 | 0 | Self::from_env(Env::default()) |
529 | 0 | } |
530 | | |
531 | | /// Applies the configuration from the environment using default variable names. |
532 | | /// |
533 | | /// This method is a convenient way to call `parse_env(Env::default())` without |
534 | | /// having to use the `Env` type explicitly. The builder will use the |
535 | | /// [default environment variables]. |
536 | | /// |
537 | | /// # Examples |
538 | | /// |
539 | | /// Initialise a logger with filter level `Off`, then configure it using the |
540 | | /// default environment variables: |
541 | | /// |
542 | | /// ``` |
543 | | /// use log::LevelFilter; |
544 | | /// use env_logger::Builder; |
545 | | /// |
546 | | /// let mut builder = Builder::new(); |
547 | | /// builder.filter_level(LevelFilter::Off); |
548 | | /// builder.parse_default_env(); |
549 | | /// builder.init(); |
550 | | /// ``` |
551 | | /// |
552 | | /// [default environment variables]: struct.Env.html#default-environment-variables |
553 | 0 | pub fn parse_default_env(&mut self) -> &mut Self { |
554 | 0 | self.parse_env(Env::default()) |
555 | 0 | } |
556 | | |
557 | | /// Sets the format function for formatting the log output. |
558 | | /// |
559 | | /// This function is called on each record logged and should format the |
560 | | /// log record and output it to the given [`Formatter`]. |
561 | | /// |
562 | | /// The format function is expected to output the string directly to the |
563 | | /// `Formatter` so that implementations can use the [`std::fmt`] macros |
564 | | /// to format and output without intermediate heap allocations. The default |
565 | | /// `env_logger` formatter takes advantage of this. |
566 | | /// |
567 | | /// # Examples |
568 | | /// |
569 | | /// Use a custom format to write only the log message: |
570 | | /// |
571 | | /// ``` |
572 | | /// use std::io::Write; |
573 | | /// use env_logger::Builder; |
574 | | /// |
575 | | /// let mut builder = Builder::new(); |
576 | | /// |
577 | | /// builder.format(|buf, record| writeln!(buf, "{}", record.args())); |
578 | | /// ``` |
579 | | /// |
580 | | /// [`Formatter`]: fmt/struct.Formatter.html |
581 | | /// [`String`]: https://doc.rust-lang.org/stable/std/string/struct.String.html |
582 | | /// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html |
583 | 0 | pub fn format<F: 'static>(&mut self, format: F) -> &mut Self |
584 | 0 | where |
585 | 0 | F: Fn(&mut Formatter, &Record) -> io::Result<()> + Sync + Send, |
586 | 0 | { |
587 | 0 | self.format.custom_format = Some(Box::new(format)); |
588 | 0 | self |
589 | 0 | } Unexecuted instantiation: <env_logger::Builder>::format::<alloc::boxed::Box<dyn for<'a, 'b, 'c> core::ops::function::Fn<(&'a mut env_logger::fmt::Formatter, &'b log::Record<'c>), Output = core::result::Result<(), std::io::error::Error>> + core::marker::Sync + core::marker::Send>> Unexecuted instantiation: <env_logger::Builder>::format::<<base::syslog::State>::new::{closure#0}::{closure#0}> Unexecuted instantiation: <env_logger::Builder>::format::<<base::sys::linux::linux::syslog::PlatformSyslog as base::syslog::Syslog>::new::{closure#0}> Unexecuted instantiation: <env_logger::Builder>::format::<_> |
590 | | |
591 | | /// Use the default format. |
592 | | /// |
593 | | /// This method will clear any custom format set on the builder. |
594 | 0 | pub fn default_format(&mut self) -> &mut Self { |
595 | 0 | self.format = Default::default(); |
596 | 0 | self |
597 | 0 | } |
598 | | |
599 | | /// Whether or not to write the level in the default format. |
600 | 0 | pub fn format_level(&mut self, write: bool) -> &mut Self { |
601 | 0 | self.format.format_level = write; |
602 | 0 | self |
603 | 0 | } |
604 | | |
605 | | /// Whether or not to write the module path in the default format. |
606 | 0 | pub fn format_module_path(&mut self, write: bool) -> &mut Self { |
607 | 0 | self.format.format_module_path = write; |
608 | 0 | self |
609 | 0 | } |
610 | | |
611 | | /// Whether or not to write the target in the default format. |
612 | 0 | pub fn format_target(&mut self, write: bool) -> &mut Self { |
613 | 0 | self.format.format_target = write; |
614 | 0 | self |
615 | 0 | } |
616 | | |
617 | | /// Configures the amount of spaces to use to indent multiline log records. |
618 | | /// A value of `None` disables any kind of indentation. |
619 | 0 | pub fn format_indent(&mut self, indent: Option<usize>) -> &mut Self { |
620 | 0 | self.format.format_indent = indent; |
621 | 0 | self |
622 | 0 | } |
623 | | |
624 | | /// Configures if timestamp should be included and in what precision. |
625 | 0 | pub fn format_timestamp(&mut self, timestamp: Option<fmt::TimestampPrecision>) -> &mut Self { |
626 | 0 | self.format.format_timestamp = timestamp; |
627 | 0 | self |
628 | 0 | } |
629 | | |
630 | | /// Configures the timestamp to use second precision. |
631 | 0 | pub fn format_timestamp_secs(&mut self) -> &mut Self { |
632 | 0 | self.format_timestamp(Some(fmt::TimestampPrecision::Seconds)) |
633 | 0 | } |
634 | | |
635 | | /// Configures the timestamp to use millisecond precision. |
636 | 0 | pub fn format_timestamp_millis(&mut self) -> &mut Self { |
637 | 0 | self.format_timestamp(Some(fmt::TimestampPrecision::Millis)) |
638 | 0 | } |
639 | | |
640 | | /// Configures the timestamp to use microsecond precision. |
641 | 0 | pub fn format_timestamp_micros(&mut self) -> &mut Self { |
642 | 0 | self.format_timestamp(Some(fmt::TimestampPrecision::Micros)) |
643 | 0 | } |
644 | | |
645 | | /// Configures the timestamp to use nanosecond precision. |
646 | 0 | pub fn format_timestamp_nanos(&mut self) -> &mut Self { |
647 | 0 | self.format_timestamp(Some(fmt::TimestampPrecision::Nanos)) |
648 | 0 | } |
649 | | |
650 | | /// Configures the end of line suffix. |
651 | 0 | pub fn format_suffix(&mut self, suffix: &'static str) -> &mut Self { |
652 | 0 | self.format.format_suffix = suffix; |
653 | 0 | self |
654 | 0 | } |
655 | | |
656 | | /// Adds a directive to the filter for a specific module. |
657 | | /// |
658 | | /// # Examples |
659 | | /// |
660 | | /// Only include messages for info and above for logs in `path::to::module`: |
661 | | /// |
662 | | /// ``` |
663 | | /// use env_logger::Builder; |
664 | | /// use log::LevelFilter; |
665 | | /// |
666 | | /// let mut builder = Builder::new(); |
667 | | /// |
668 | | /// builder.filter_module("path::to::module", LevelFilter::Info); |
669 | | /// ``` |
670 | 0 | pub fn filter_module(&mut self, module: &str, level: LevelFilter) -> &mut Self { |
671 | 0 | self.filter.filter_module(module, level); |
672 | 0 | self |
673 | 0 | } |
674 | | |
675 | | /// Adds a directive to the filter for all modules. |
676 | | /// |
677 | | /// # Examples |
678 | | /// |
679 | | /// Only include messages for info and above for logs in `path::to::module`: |
680 | | /// |
681 | | /// ``` |
682 | | /// use env_logger::Builder; |
683 | | /// use log::LevelFilter; |
684 | | /// |
685 | | /// let mut builder = Builder::new(); |
686 | | /// |
687 | | /// builder.filter_level(LevelFilter::Info); |
688 | | /// ``` |
689 | 0 | pub fn filter_level(&mut self, level: LevelFilter) -> &mut Self { |
690 | 0 | self.filter.filter_level(level); |
691 | 0 | self |
692 | 0 | } |
693 | | |
694 | | /// Adds filters to the logger. |
695 | | /// |
696 | | /// The given module (if any) will log at most the specified level provided. |
697 | | /// If no module is provided then the filter will apply to all log messages. |
698 | | /// |
699 | | /// # Examples |
700 | | /// |
701 | | /// Only include messages for info and above for logs in `path::to::module`: |
702 | | /// |
703 | | /// ``` |
704 | | /// use env_logger::Builder; |
705 | | /// use log::LevelFilter; |
706 | | /// |
707 | | /// let mut builder = Builder::new(); |
708 | | /// |
709 | | /// builder.filter(Some("path::to::module"), LevelFilter::Info); |
710 | | /// ``` |
711 | 0 | pub fn filter(&mut self, module: Option<&str>, level: LevelFilter) -> &mut Self { |
712 | 0 | self.filter.filter(module, level); |
713 | 0 | self |
714 | 0 | } |
715 | | |
716 | | /// Parses the directives string in the same form as the `RUST_LOG` |
717 | | /// environment variable. |
718 | | /// |
719 | | /// See the module documentation for more details. |
720 | 0 | pub fn parse_filters(&mut self, filters: &str) -> &mut Self { |
721 | 0 | self.filter.parse(filters); |
722 | 0 | self |
723 | 0 | } |
724 | | |
725 | | /// Sets the target for the log output. |
726 | | /// |
727 | | /// Env logger can log to either stdout, stderr or a custom pipe. The default is stderr. |
728 | | /// |
729 | | /// The custom pipe can be used to send the log messages to a custom sink (for example a file). |
730 | | /// Do note that direct writes to a file can become a bottleneck due to IO operation times. |
731 | | /// |
732 | | /// # Examples |
733 | | /// |
734 | | /// Write log message to `stdout`: |
735 | | /// |
736 | | /// ``` |
737 | | /// use env_logger::{Builder, Target}; |
738 | | /// |
739 | | /// let mut builder = Builder::new(); |
740 | | /// |
741 | | /// builder.target(Target::Stdout); |
742 | | /// ``` |
743 | 0 | pub fn target(&mut self, target: fmt::Target) -> &mut Self { |
744 | 0 | self.writer.target(target); |
745 | 0 | self |
746 | 0 | } |
747 | | |
748 | | /// Sets whether or not styles will be written. |
749 | | /// |
750 | | /// This can be useful in environments that don't support control characters |
751 | | /// for setting colors. |
752 | | /// |
753 | | /// # Examples |
754 | | /// |
755 | | /// Never attempt to write styles: |
756 | | /// |
757 | | /// ``` |
758 | | /// use env_logger::{Builder, WriteStyle}; |
759 | | /// |
760 | | /// let mut builder = Builder::new(); |
761 | | /// |
762 | | /// builder.write_style(WriteStyle::Never); |
763 | | /// ``` |
764 | 0 | pub fn write_style(&mut self, write_style: fmt::WriteStyle) -> &mut Self { |
765 | 0 | self.writer.write_style(write_style); |
766 | 0 | self |
767 | 0 | } |
768 | | |
769 | | /// Parses whether or not to write styles in the same form as the `RUST_LOG_STYLE` |
770 | | /// environment variable. |
771 | | /// |
772 | | /// See the module documentation for more details. |
773 | 0 | pub fn parse_write_style(&mut self, write_style: &str) -> &mut Self { |
774 | 0 | self.writer.parse_write_style(write_style); |
775 | 0 | self |
776 | 0 | } |
777 | | |
778 | | /// Sets whether or not the logger will be used in unit tests. |
779 | | /// |
780 | | /// If `is_test` is `true` then the logger will allow the testing framework to |
781 | | /// capture log records rather than printing them to the terminal directly. |
782 | 0 | pub fn is_test(&mut self, is_test: bool) -> &mut Self { |
783 | 0 | self.writer.is_test(is_test); |
784 | 0 | self |
785 | 0 | } |
786 | | |
787 | | /// Initializes the global logger with the built env logger. |
788 | | /// |
789 | | /// This should be called early in the execution of a Rust program. Any log |
790 | | /// events that occur before initialization will be ignored. |
791 | | /// |
792 | | /// # Errors |
793 | | /// |
794 | | /// This function will fail if it is called more than once, or if another |
795 | | /// library has already initialized a global logger. |
796 | 0 | pub fn try_init(&mut self) -> Result<(), SetLoggerError> { |
797 | 0 | let logger = self.build(); |
798 | 0 |
|
799 | 0 | let max_level = logger.filter(); |
800 | 0 | let r = log::set_boxed_logger(Box::new(logger)); |
801 | 0 |
|
802 | 0 | if r.is_ok() { |
803 | 0 | log::set_max_level(max_level); |
804 | 0 | } |
805 | | |
806 | 0 | r |
807 | 0 | } |
808 | | |
809 | | /// Initializes the global logger with the built env logger. |
810 | | /// |
811 | | /// This should be called early in the execution of a Rust program. Any log |
812 | | /// events that occur before initialization will be ignored. |
813 | | /// |
814 | | /// # Panics |
815 | | /// |
816 | | /// This function will panic if it is called more than once, or if another |
817 | | /// library has already initialized a global logger. |
818 | 0 | pub fn init(&mut self) { |
819 | 0 | self.try_init() |
820 | 0 | .expect("Builder::init should not be called after logger initialized"); |
821 | 0 | } |
822 | | |
823 | | /// Build an env logger. |
824 | | /// |
825 | | /// The returned logger implements the `Log` trait and can be installed manually |
826 | | /// or nested within another logger. |
827 | 0 | pub fn build(&mut self) -> Logger { |
828 | 0 | assert!(!self.built, "attempt to re-use consumed builder"); |
829 | 0 | self.built = true; |
830 | 0 |
|
831 | 0 | Logger { |
832 | 0 | writer: self.writer.build(), |
833 | 0 | filter: self.filter.build(), |
834 | 0 | format: self.format.build(), |
835 | 0 | } |
836 | 0 | } |
837 | | } |
838 | | |
839 | | impl Logger { |
840 | | /// Creates the logger from the environment. |
841 | | /// |
842 | | /// The variables used to read configuration from can be tweaked before |
843 | | /// passing in. |
844 | | /// |
845 | | /// # Examples |
846 | | /// |
847 | | /// Create a logger reading the log filter from an environment variable |
848 | | /// called `MY_LOG`: |
849 | | /// |
850 | | /// ``` |
851 | | /// use env_logger::Logger; |
852 | | /// |
853 | | /// let logger = Logger::from_env("MY_LOG"); |
854 | | /// ``` |
855 | | /// |
856 | | /// Create a logger using the `MY_LOG` variable for filtering and |
857 | | /// `MY_LOG_STYLE` for whether or not to write styles: |
858 | | /// |
859 | | /// ``` |
860 | | /// use env_logger::{Logger, Env}; |
861 | | /// |
862 | | /// let env = Env::new().filter_or("MY_LOG", "info").write_style_or("MY_LOG_STYLE", "always"); |
863 | | /// |
864 | | /// let logger = Logger::from_env(env); |
865 | | /// ``` |
866 | 0 | pub fn from_env<'a, E>(env: E) -> Self |
867 | 0 | where |
868 | 0 | E: Into<Env<'a>>, |
869 | 0 | { |
870 | 0 | Builder::from_env(env).build() |
871 | 0 | } |
872 | | |
873 | | /// Creates the logger from the environment using default variable names. |
874 | | /// |
875 | | /// This method is a convenient way to call `from_env(Env::default())` without |
876 | | /// having to use the `Env` type explicitly. The logger will use the |
877 | | /// [default environment variables]. |
878 | | /// |
879 | | /// # Examples |
880 | | /// |
881 | | /// Creates a logger using the default environment variables: |
882 | | /// |
883 | | /// ``` |
884 | | /// use env_logger::Logger; |
885 | | /// |
886 | | /// let logger = Logger::from_default_env(); |
887 | | /// ``` |
888 | | /// |
889 | | /// [default environment variables]: struct.Env.html#default-environment-variables |
890 | 0 | pub fn from_default_env() -> Self { |
891 | 0 | Builder::from_default_env().build() |
892 | 0 | } |
893 | | |
894 | | /// Returns the maximum `LevelFilter` that this env logger instance is |
895 | | /// configured to output. |
896 | 0 | pub fn filter(&self) -> LevelFilter { |
897 | 0 | self.filter.filter() |
898 | 0 | } |
899 | | |
900 | | /// Checks if this record matches the configured filter. |
901 | 0 | pub fn matches(&self, record: &Record) -> bool { |
902 | 0 | self.filter.matches(record) |
903 | 0 | } |
904 | | } |
905 | | |
906 | | impl Log for Logger { |
907 | 0 | fn enabled(&self, metadata: &Metadata) -> bool { |
908 | 0 | self.filter.enabled(metadata) |
909 | 0 | } |
910 | | |
911 | 0 | fn log(&self, record: &Record) { |
912 | 0 | if self.matches(record) { |
913 | | // Log records are written to a thread-local buffer before being printed |
914 | | // to the terminal. We clear these buffers afterwards, but they aren't shrinked |
915 | | // so will always at least have capacity for the largest log record formatted |
916 | | // on that thread. |
917 | | // |
918 | | // If multiple `Logger`s are used by the same threads then the thread-local |
919 | | // formatter might have different color support. If this is the case the |
920 | | // formatter and its buffer are discarded and recreated. |
921 | | |
922 | | thread_local! { |
923 | | static FORMATTER: RefCell<Option<Formatter>> = RefCell::new(None); |
924 | | } |
925 | | |
926 | 0 | let print = |formatter: &mut Formatter, record: &Record| { |
927 | 0 | let _ = |
928 | 0 | (self.format)(formatter, record).and_then(|_| formatter.print(&self.writer)); |
929 | 0 |
|
930 | 0 | // Always clear the buffer afterwards |
931 | 0 | formatter.clear(); |
932 | 0 | }; |
933 | | |
934 | 0 | let printed = FORMATTER |
935 | 0 | .try_with(|tl_buf| { |
936 | 0 | match tl_buf.try_borrow_mut() { |
937 | | // There are no active borrows of the buffer |
938 | 0 | Ok(mut tl_buf) => match *tl_buf { |
939 | | // We have a previously set formatter |
940 | 0 | Some(ref mut formatter) => { |
941 | 0 | // Check the buffer style. If it's different from the logger's |
942 | 0 | // style then drop the buffer and recreate it. |
943 | 0 | if formatter.write_style() != self.writer.write_style() { |
944 | 0 | *formatter = Formatter::new(&self.writer); |
945 | 0 | } |
946 | | |
947 | 0 | print(formatter, record); |
948 | | } |
949 | | // We don't have a previously set formatter |
950 | 0 | None => { |
951 | 0 | let mut formatter = Formatter::new(&self.writer); |
952 | 0 | print(&mut formatter, record); |
953 | 0 |
|
954 | 0 | *tl_buf = Some(formatter); |
955 | 0 | } |
956 | | }, |
957 | | // There's already an active borrow of the buffer (due to re-entrancy) |
958 | 0 | Err(_) => { |
959 | 0 | print(&mut Formatter::new(&self.writer), record); |
960 | 0 | } |
961 | | } |
962 | 0 | }) |
963 | 0 | .is_ok(); |
964 | 0 |
|
965 | 0 | if !printed { |
966 | 0 | // The thread-local storage was not available (because its |
967 | 0 | // destructor has already run). Create a new single-use |
968 | 0 | // Formatter on the stack for this call. |
969 | 0 | print(&mut Formatter::new(&self.writer), record); |
970 | 0 | } |
971 | 0 | } |
972 | 0 | } |
973 | | |
974 | 0 | fn flush(&self) {} |
975 | | } |
976 | | |
977 | | impl<'a> Env<'a> { |
978 | | /// Get a default set of environment variables. |
979 | 0 | pub fn new() -> Self { |
980 | 0 | Self::default() |
981 | 0 | } |
982 | | |
983 | | /// Specify an environment variable to read the filter from. |
984 | 0 | pub fn filter<E>(mut self, filter_env: E) -> Self |
985 | 0 | where |
986 | 0 | E: Into<Cow<'a, str>>, |
987 | 0 | { |
988 | 0 | self.filter = Var::new(filter_env); |
989 | 0 |
|
990 | 0 | self |
991 | 0 | } |
992 | | |
993 | | /// Specify an environment variable to read the filter from. |
994 | | /// |
995 | | /// If the variable is not set, the default value will be used. |
996 | 0 | pub fn filter_or<E, V>(mut self, filter_env: E, default: V) -> Self |
997 | 0 | where |
998 | 0 | E: Into<Cow<'a, str>>, |
999 | 0 | V: Into<Cow<'a, str>>, |
1000 | 0 | { |
1001 | 0 | self.filter = Var::new_with_default(filter_env, default); |
1002 | 0 |
|
1003 | 0 | self |
1004 | 0 | } |
1005 | | |
1006 | | /// Use the default environment variable to read the filter from. |
1007 | | /// |
1008 | | /// If the variable is not set, the default value will be used. |
1009 | 0 | pub fn default_filter_or<V>(mut self, default: V) -> Self |
1010 | 0 | where |
1011 | 0 | V: Into<Cow<'a, str>>, |
1012 | 0 | { |
1013 | 0 | self.filter = Var::new_with_default(DEFAULT_FILTER_ENV, default); |
1014 | 0 |
|
1015 | 0 | self |
1016 | 0 | } |
1017 | | |
1018 | 0 | fn get_filter(&self) -> Option<String> { |
1019 | 0 | self.filter.get() |
1020 | 0 | } |
1021 | | |
1022 | | /// Specify an environment variable to read the style from. |
1023 | 0 | pub fn write_style<E>(mut self, write_style_env: E) -> Self |
1024 | 0 | where |
1025 | 0 | E: Into<Cow<'a, str>>, |
1026 | 0 | { |
1027 | 0 | self.write_style = Var::new(write_style_env); |
1028 | 0 |
|
1029 | 0 | self |
1030 | 0 | } |
1031 | | |
1032 | | /// Specify an environment variable to read the style from. |
1033 | | /// |
1034 | | /// If the variable is not set, the default value will be used. |
1035 | 0 | pub fn write_style_or<E, V>(mut self, write_style_env: E, default: V) -> Self |
1036 | 0 | where |
1037 | 0 | E: Into<Cow<'a, str>>, |
1038 | 0 | V: Into<Cow<'a, str>>, |
1039 | 0 | { |
1040 | 0 | self.write_style = Var::new_with_default(write_style_env, default); |
1041 | 0 |
|
1042 | 0 | self |
1043 | 0 | } |
1044 | | |
1045 | | /// Use the default environment variable to read the style from. |
1046 | | /// |
1047 | | /// If the variable is not set, the default value will be used. |
1048 | 0 | pub fn default_write_style_or<V>(mut self, default: V) -> Self |
1049 | 0 | where |
1050 | 0 | V: Into<Cow<'a, str>>, |
1051 | 0 | { |
1052 | 0 | self.write_style = Var::new_with_default(DEFAULT_WRITE_STYLE_ENV, default); |
1053 | 0 |
|
1054 | 0 | self |
1055 | 0 | } |
1056 | | |
1057 | 0 | fn get_write_style(&self) -> Option<String> { |
1058 | 0 | self.write_style.get() |
1059 | 0 | } |
1060 | | } |
1061 | | |
1062 | | impl<'a> Var<'a> { |
1063 | 0 | fn new<E>(name: E) -> Self |
1064 | 0 | where |
1065 | 0 | E: Into<Cow<'a, str>>, |
1066 | 0 | { |
1067 | 0 | Var { |
1068 | 0 | name: name.into(), |
1069 | 0 | default: None, |
1070 | 0 | } |
1071 | 0 | } |
1072 | | |
1073 | 0 | fn new_with_default<E, V>(name: E, default: V) -> Self |
1074 | 0 | where |
1075 | 0 | E: Into<Cow<'a, str>>, |
1076 | 0 | V: Into<Cow<'a, str>>, |
1077 | 0 | { |
1078 | 0 | Var { |
1079 | 0 | name: name.into(), |
1080 | 0 | default: Some(default.into()), |
1081 | 0 | } |
1082 | 0 | } |
1083 | | |
1084 | 0 | fn get(&self) -> Option<String> { |
1085 | 0 | env::var(&*self.name) |
1086 | 0 | .ok() |
1087 | 0 | .or_else(|| self.default.to_owned().map(|v| v.into_owned())) |
1088 | 0 | } |
1089 | | } |
1090 | | |
1091 | | impl<'a, T> From<T> for Env<'a> |
1092 | | where |
1093 | | T: Into<Cow<'a, str>>, |
1094 | | { |
1095 | 0 | fn from(filter_env: T) -> Self { |
1096 | 0 | Env::default().filter(filter_env.into()) |
1097 | 0 | } |
1098 | | } |
1099 | | |
1100 | | impl<'a> Default for Env<'a> { |
1101 | 0 | fn default() -> Self { |
1102 | 0 | Env { |
1103 | 0 | filter: Var::new(DEFAULT_FILTER_ENV), |
1104 | 0 | write_style: Var::new(DEFAULT_WRITE_STYLE_ENV), |
1105 | 0 | } |
1106 | 0 | } |
1107 | | } |
1108 | | |
1109 | | mod std_fmt_impls { |
1110 | | use super::*; |
1111 | | use std::fmt; |
1112 | | |
1113 | | impl fmt::Debug for Logger { |
1114 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1115 | 0 | f.debug_struct("Logger") |
1116 | 0 | .field("filter", &self.filter) |
1117 | 0 | .finish() |
1118 | 0 | } |
1119 | | } |
1120 | | |
1121 | | impl fmt::Debug for Builder { |
1122 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1123 | 0 | if self.built { |
1124 | 0 | f.debug_struct("Logger").field("built", &true).finish() |
1125 | | } else { |
1126 | 0 | f.debug_struct("Logger") |
1127 | 0 | .field("filter", &self.filter) |
1128 | 0 | .field("writer", &self.writer) |
1129 | 0 | .finish() |
1130 | | } |
1131 | 0 | } |
1132 | | } |
1133 | | } |
1134 | | |
1135 | | /// Attempts to initialize the global logger with an env logger. |
1136 | | /// |
1137 | | /// This should be called early in the execution of a Rust program. Any log |
1138 | | /// events that occur before initialization will be ignored. |
1139 | | /// |
1140 | | /// # Errors |
1141 | | /// |
1142 | | /// This function will fail if it is called more than once, or if another |
1143 | | /// library has already initialized a global logger. |
1144 | 0 | pub fn try_init() -> Result<(), SetLoggerError> { |
1145 | 0 | try_init_from_env(Env::default()) |
1146 | 0 | } |
1147 | | |
1148 | | /// Initializes the global logger with an env logger. |
1149 | | /// |
1150 | | /// This should be called early in the execution of a Rust program. Any log |
1151 | | /// events that occur before initialization will be ignored. |
1152 | | /// |
1153 | | /// # Panics |
1154 | | /// |
1155 | | /// This function will panic if it is called more than once, or if another |
1156 | | /// library has already initialized a global logger. |
1157 | 0 | pub fn init() { |
1158 | 0 | try_init().expect("env_logger::init should not be called after logger initialized"); |
1159 | 0 | } |
1160 | | |
1161 | | /// Attempts to initialize the global logger with an env logger from the given |
1162 | | /// environment variables. |
1163 | | /// |
1164 | | /// This should be called early in the execution of a Rust program. Any log |
1165 | | /// events that occur before initialization will be ignored. |
1166 | | /// |
1167 | | /// # Examples |
1168 | | /// |
1169 | | /// Initialise a logger using the `MY_LOG` environment variable for filters |
1170 | | /// and `MY_LOG_STYLE` for writing colors: |
1171 | | /// |
1172 | | /// ``` |
1173 | | /// use env_logger::{Builder, Env}; |
1174 | | /// |
1175 | | /// # fn run() -> Result<(), Box<::std::error::Error>> { |
1176 | | /// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); |
1177 | | /// |
1178 | | /// env_logger::try_init_from_env(env)?; |
1179 | | /// |
1180 | | /// Ok(()) |
1181 | | /// # } |
1182 | | /// # run().unwrap(); |
1183 | | /// ``` |
1184 | | /// |
1185 | | /// # Errors |
1186 | | /// |
1187 | | /// This function will fail if it is called more than once, or if another |
1188 | | /// library has already initialized a global logger. |
1189 | 0 | pub fn try_init_from_env<'a, E>(env: E) -> Result<(), SetLoggerError> |
1190 | 0 | where |
1191 | 0 | E: Into<Env<'a>>, |
1192 | 0 | { |
1193 | 0 | let mut builder = Builder::from_env(env); |
1194 | 0 |
|
1195 | 0 | builder.try_init() |
1196 | 0 | } |
1197 | | |
1198 | | /// Initializes the global logger with an env logger from the given environment |
1199 | | /// variables. |
1200 | | /// |
1201 | | /// This should be called early in the execution of a Rust program. Any log |
1202 | | /// events that occur before initialization will be ignored. |
1203 | | /// |
1204 | | /// # Examples |
1205 | | /// |
1206 | | /// Initialise a logger using the `MY_LOG` environment variable for filters |
1207 | | /// and `MY_LOG_STYLE` for writing colors: |
1208 | | /// |
1209 | | /// ``` |
1210 | | /// use env_logger::{Builder, Env}; |
1211 | | /// |
1212 | | /// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); |
1213 | | /// |
1214 | | /// env_logger::init_from_env(env); |
1215 | | /// ``` |
1216 | | /// |
1217 | | /// # Panics |
1218 | | /// |
1219 | | /// This function will panic if it is called more than once, or if another |
1220 | | /// library has already initialized a global logger. |
1221 | 0 | pub fn init_from_env<'a, E>(env: E) |
1222 | 0 | where |
1223 | 0 | E: Into<Env<'a>>, |
1224 | 0 | { |
1225 | 0 | try_init_from_env(env) |
1226 | 0 | .expect("env_logger::init_from_env should not be called after logger initialized"); |
1227 | 0 | } |
1228 | | |
1229 | | /// Create a new builder with the default environment variables. |
1230 | | /// |
1231 | | /// The builder can be configured before being initialized. |
1232 | | /// This is a convenient way of calling [`Builder::from_default_env`]. |
1233 | | /// |
1234 | | /// [`Builder::from_default_env`]: struct.Builder.html#method.from_default_env |
1235 | 0 | pub fn builder() -> Builder { |
1236 | 0 | Builder::from_default_env() |
1237 | 0 | } |
1238 | | |
1239 | | /// Create a builder from the given environment variables. |
1240 | | /// |
1241 | | /// The builder can be configured before being initialized. |
1242 | | #[deprecated( |
1243 | | since = "0.8.0", |
1244 | | note = "Prefer `env_logger::Builder::from_env()` instead." |
1245 | | )] |
1246 | 0 | pub fn from_env<'a, E>(env: E) -> Builder |
1247 | 0 | where |
1248 | 0 | E: Into<Env<'a>>, |
1249 | 0 | { |
1250 | 0 | Builder::from_env(env) |
1251 | 0 | } |
1252 | | |
1253 | | #[cfg(test)] |
1254 | | mod tests { |
1255 | | use super::*; |
1256 | | |
1257 | | #[test] |
1258 | | fn env_get_filter_reads_from_var_if_set() { |
1259 | | env::set_var("env_get_filter_reads_from_var_if_set", "from var"); |
1260 | | |
1261 | | let env = Env::new().filter_or("env_get_filter_reads_from_var_if_set", "from default"); |
1262 | | |
1263 | | assert_eq!(Some("from var".to_owned()), env.get_filter()); |
1264 | | } |
1265 | | |
1266 | | #[test] |
1267 | | fn env_get_filter_reads_from_default_if_var_not_set() { |
1268 | | env::remove_var("env_get_filter_reads_from_default_if_var_not_set"); |
1269 | | |
1270 | | let env = Env::new().filter_or( |
1271 | | "env_get_filter_reads_from_default_if_var_not_set", |
1272 | | "from default", |
1273 | | ); |
1274 | | |
1275 | | assert_eq!(Some("from default".to_owned()), env.get_filter()); |
1276 | | } |
1277 | | |
1278 | | #[test] |
1279 | | fn env_get_write_style_reads_from_var_if_set() { |
1280 | | env::set_var("env_get_write_style_reads_from_var_if_set", "from var"); |
1281 | | |
1282 | | let env = |
1283 | | Env::new().write_style_or("env_get_write_style_reads_from_var_if_set", "from default"); |
1284 | | |
1285 | | assert_eq!(Some("from var".to_owned()), env.get_write_style()); |
1286 | | } |
1287 | | |
1288 | | #[test] |
1289 | | fn env_get_write_style_reads_from_default_if_var_not_set() { |
1290 | | env::remove_var("env_get_write_style_reads_from_default_if_var_not_set"); |
1291 | | |
1292 | | let env = Env::new().write_style_or( |
1293 | | "env_get_write_style_reads_from_default_if_var_not_set", |
1294 | | "from default", |
1295 | | ); |
1296 | | |
1297 | | assert_eq!(Some("from default".to_owned()), env.get_write_style()); |
1298 | | } |
1299 | | |
1300 | | #[test] |
1301 | | fn builder_parse_env_overrides_existing_filters() { |
1302 | | env::set_var( |
1303 | | "builder_parse_default_env_overrides_existing_filters", |
1304 | | "debug", |
1305 | | ); |
1306 | | let env = Env::new().filter("builder_parse_default_env_overrides_existing_filters"); |
1307 | | |
1308 | | let mut builder = Builder::new(); |
1309 | | builder.filter_level(LevelFilter::Trace); |
1310 | | // Overrides global level to debug |
1311 | | builder.parse_env(env); |
1312 | | |
1313 | | assert_eq!(builder.filter.build().filter(), LevelFilter::Debug); |
1314 | | } |
1315 | | } |