1336d762aSopenharmony_ci// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 2336d762aSopenharmony_ci// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license 3336d762aSopenharmony_ci// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your 4336d762aSopenharmony_ci// option. This file may not be copied, modified, or distributed 5336d762aSopenharmony_ci// except according to those terms. 6336d762aSopenharmony_ci 7336d762aSopenharmony_ci//! A simple logger that can be configured via environment variables, for use 8336d762aSopenharmony_ci//! with the logging facade exposed by the [`log` crate][log-crate-url]. 9336d762aSopenharmony_ci//! 10336d762aSopenharmony_ci//! Despite having "env" in its name, **`env_logger`** can also be configured by 11336d762aSopenharmony_ci//! other means besides environment variables. See [the examples][gh-repo-examples] 12336d762aSopenharmony_ci//! in the source repository for more approaches. 13336d762aSopenharmony_ci//! 14336d762aSopenharmony_ci//! By default, `env_logger` writes logs to `stderr`, but can be configured to 15336d762aSopenharmony_ci//! instead write them to `stdout`. 16336d762aSopenharmony_ci//! 17336d762aSopenharmony_ci//! ## Example 18336d762aSopenharmony_ci//! 19336d762aSopenharmony_ci//! ``` 20336d762aSopenharmony_ci//! use log::{debug, error, log_enabled, info, Level}; 21336d762aSopenharmony_ci//! 22336d762aSopenharmony_ci//! env_logger::init(); 23336d762aSopenharmony_ci//! 24336d762aSopenharmony_ci//! debug!("this is a debug {}", "message"); 25336d762aSopenharmony_ci//! error!("this is printed by default"); 26336d762aSopenharmony_ci//! 27336d762aSopenharmony_ci//! if log_enabled!(Level::Info) { 28336d762aSopenharmony_ci//! let x = 3 * 4; // expensive computation 29336d762aSopenharmony_ci//! info!("the answer was: {}", x); 30336d762aSopenharmony_ci//! } 31336d762aSopenharmony_ci//! ``` 32336d762aSopenharmony_ci//! 33336d762aSopenharmony_ci//! Assumes the binary is `main`: 34336d762aSopenharmony_ci//! 35336d762aSopenharmony_ci//! ```{.bash} 36336d762aSopenharmony_ci//! $ RUST_LOG=error ./main 37336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z ERROR main] this is printed by default 38336d762aSopenharmony_ci//! ``` 39336d762aSopenharmony_ci//! 40336d762aSopenharmony_ci//! ```{.bash} 41336d762aSopenharmony_ci//! $ RUST_LOG=info ./main 42336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z ERROR main] this is printed by default 43336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z INFO main] the answer was: 12 44336d762aSopenharmony_ci//! ``` 45336d762aSopenharmony_ci//! 46336d762aSopenharmony_ci//! ```{.bash} 47336d762aSopenharmony_ci//! $ RUST_LOG=debug ./main 48336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z DEBUG main] this is a debug message 49336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z ERROR main] this is printed by default 50336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z INFO main] the answer was: 12 51336d762aSopenharmony_ci//! ``` 52336d762aSopenharmony_ci//! 53336d762aSopenharmony_ci//! You can also set the log level on a per module basis: 54336d762aSopenharmony_ci//! 55336d762aSopenharmony_ci//! ```{.bash} 56336d762aSopenharmony_ci//! $ RUST_LOG=main=info ./main 57336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z ERROR main] this is printed by default 58336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z INFO main] the answer was: 12 59336d762aSopenharmony_ci//! ``` 60336d762aSopenharmony_ci//! 61336d762aSopenharmony_ci//! And enable all logging: 62336d762aSopenharmony_ci//! 63336d762aSopenharmony_ci//! ```{.bash} 64336d762aSopenharmony_ci//! $ RUST_LOG=main ./main 65336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z DEBUG main] this is a debug message 66336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z ERROR main] this is printed by default 67336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z INFO main] the answer was: 12 68336d762aSopenharmony_ci//! ``` 69336d762aSopenharmony_ci//! 70336d762aSopenharmony_ci//! If the binary name contains hyphens, you will need to replace 71336d762aSopenharmony_ci//! them with underscores: 72336d762aSopenharmony_ci//! 73336d762aSopenharmony_ci//! ```{.bash} 74336d762aSopenharmony_ci//! $ RUST_LOG=my_app ./my-app 75336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z DEBUG my_app] this is a debug message 76336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z ERROR my_app] this is printed by default 77336d762aSopenharmony_ci//! [2017-11-09T02:12:24Z INFO my_app] the answer was: 12 78336d762aSopenharmony_ci//! ``` 79336d762aSopenharmony_ci//! 80336d762aSopenharmony_ci//! This is because Rust modules and crates cannot contain hyphens 81336d762aSopenharmony_ci//! in their name, although `cargo` continues to accept them. 82336d762aSopenharmony_ci//! 83336d762aSopenharmony_ci//! See the documentation for the [`log` crate][log-crate-url] for more 84336d762aSopenharmony_ci//! information about its API. 85336d762aSopenharmony_ci//! 86336d762aSopenharmony_ci//! ## Enabling logging 87336d762aSopenharmony_ci//! 88336d762aSopenharmony_ci//! Log levels are controlled on a per-module basis, and **by default all 89336d762aSopenharmony_ci//! logging is disabled except for the `error` level**. 90336d762aSopenharmony_ci//! 91336d762aSopenharmony_ci//! Logging is controlled via the **`RUST_LOG`** environment variable. The 92336d762aSopenharmony_ci//! value of this environment variable is a comma-separated list of *logging 93336d762aSopenharmony_ci//! directives*. A logging directive is of the form: 94336d762aSopenharmony_ci//! 95336d762aSopenharmony_ci//! ```text 96336d762aSopenharmony_ci//! example::log::target=level 97336d762aSopenharmony_ci//! ``` 98336d762aSopenharmony_ci//! 99336d762aSopenharmony_ci//! The log target is typically equal to the path of the module the message 100336d762aSopenharmony_ci//! in question originated from, though it can be overriden. 101336d762aSopenharmony_ci//! 102336d762aSopenharmony_ci//! The path is rooted in the name of the crate it was compiled for, so if 103336d762aSopenharmony_ci//! your program is in a file called, for example, `hello.rs`, the path would 104336d762aSopenharmony_ci//! simply be be `hello`. 105336d762aSopenharmony_ci//! 106336d762aSopenharmony_ci//! Furthermore, the log can be filtered using prefix-search based on the 107336d762aSopenharmony_ci//! specified log target. A value of, for example, `RUST_LOG=example`, would 108336d762aSopenharmony_ci//! match all of the messages with targets: 109336d762aSopenharmony_ci//! 110336d762aSopenharmony_ci//! * `example` 111336d762aSopenharmony_ci//! * `example::test` 112336d762aSopenharmony_ci//! * `example::test::module::submodule` 113336d762aSopenharmony_ci//! * `examples::and_more_examples` 114336d762aSopenharmony_ci//! 115336d762aSopenharmony_ci//! When providing the crate name or a module path, explicitly specifying the 116336d762aSopenharmony_ci//! log level is optional. If omitted, all logging for the item will be 117336d762aSopenharmony_ci//! enabled. 118336d762aSopenharmony_ci//! 119336d762aSopenharmony_ci//! The names of the log levels that may be specified correspond to the 120336d762aSopenharmony_ci//! variations of the [`log::Level`][level-enum] enum from the `log` 121336d762aSopenharmony_ci//! crate. They are: 122336d762aSopenharmony_ci//! 123336d762aSopenharmony_ci//! * `error` 124336d762aSopenharmony_ci//! * `warn` 125336d762aSopenharmony_ci//! * `info` 126336d762aSopenharmony_ci//! * `debug` 127336d762aSopenharmony_ci//! * `trace` 128336d762aSopenharmony_ci//! 129336d762aSopenharmony_ci//! There is also a pseudo logging level, `off`, which may be specified to 130336d762aSopenharmony_ci//! disable all logging for a given module or for the entire application. As 131336d762aSopenharmony_ci//! with the logging levels, the letter case is not significant[^fn-off]. 132336d762aSopenharmony_ci//! 133336d762aSopenharmony_ci//! [^fn-off]: Similar to the universe of log level names, the `off` pseudo 134336d762aSopenharmony_ci//! log level feature is also provided by the underlying `log` crate. 135336d762aSopenharmony_ci//! 136336d762aSopenharmony_ci//! The letter case is not significant for the logging level names; e.g., 137336d762aSopenharmony_ci//! `debug`, `DEBUG`, and `dEbuG` all represent the same logging level. For 138336d762aSopenharmony_ci//! consistency, our convention is to use the lower case names. Where our docs 139336d762aSopenharmony_ci//! do use other forms, they do so in the context of specific examples, so you 140336d762aSopenharmony_ci//! won't be surprised if you see similar usage in the wild. 141336d762aSopenharmony_ci//! 142336d762aSopenharmony_ci//! As the log level for a module is optional, the module to enable logging for 143336d762aSopenharmony_ci//! is also optional. **If only a level is provided, then the global log 144336d762aSopenharmony_ci//! level for all modules is set to this value.** 145336d762aSopenharmony_ci//! 146336d762aSopenharmony_ci//! Some examples of valid values of `RUST_LOG` are: 147336d762aSopenharmony_ci//! 148336d762aSopenharmony_ci//! * `hello` turns on all logging for the 'hello' module 149336d762aSopenharmony_ci//! * `trace` turns on all logging for the application, regardless of its name 150336d762aSopenharmony_ci//! * `TRACE` turns on all logging for the application, regardless of its name (same as previous) 151336d762aSopenharmony_ci//! * `info` turns on all info logging 152336d762aSopenharmony_ci//! * `INFO` turns on all info logging (same as previous) 153336d762aSopenharmony_ci//! * `hello=debug` turns on debug logging for 'hello' 154336d762aSopenharmony_ci//! * `hello=DEBUG` turns on debug logging for 'hello' (same as previous) 155336d762aSopenharmony_ci//! * `hello,std::option` turns on hello, and std's option logging 156336d762aSopenharmony_ci//! * `error,hello=warn` turn on global error logging and also warn for hello 157336d762aSopenharmony_ci//! * `error,hello=off` turn on global error logging, but turn off logging for hello 158336d762aSopenharmony_ci//! * `off` turns off all logging for the application 159336d762aSopenharmony_ci//! * `OFF` turns off all logging for the application (same as previous) 160336d762aSopenharmony_ci//! 161336d762aSopenharmony_ci//! ## Filtering results 162336d762aSopenharmony_ci//! 163336d762aSopenharmony_ci//! A `RUST_LOG` directive may include a regex filter. The syntax is to append `/` 164336d762aSopenharmony_ci//! followed by a regex. Each message is checked against the regex, and is only 165336d762aSopenharmony_ci//! logged if it matches. Note that the matching is done after formatting the 166336d762aSopenharmony_ci//! log string but before adding any logging meta-data. There is a single filter 167336d762aSopenharmony_ci//! for all modules. 168336d762aSopenharmony_ci//! 169336d762aSopenharmony_ci//! Some examples: 170336d762aSopenharmony_ci//! 171336d762aSopenharmony_ci//! * `hello/foo` turns on all logging for the 'hello' module where the log 172336d762aSopenharmony_ci//! message includes 'foo'. 173336d762aSopenharmony_ci//! * `info/f.o` turns on all info logging where the log message includes 'foo', 174336d762aSopenharmony_ci//! 'f1o', 'fao', etc. 175336d762aSopenharmony_ci//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the log 176336d762aSopenharmony_ci//! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc. 177336d762aSopenharmony_ci//! * `error,hello=warn/[0-9]scopes` turn on global error logging and also 178336d762aSopenharmony_ci//! warn for hello. In both cases the log message must include a single digit 179336d762aSopenharmony_ci//! number followed by 'scopes'. 180336d762aSopenharmony_ci//! 181336d762aSopenharmony_ci//! ## Capturing logs in tests 182336d762aSopenharmony_ci//! 183336d762aSopenharmony_ci//! Records logged during `cargo test` will not be captured by the test harness by default. 184336d762aSopenharmony_ci//! The [`Builder::is_test`] method can be used in unit tests to ensure logs will be captured: 185336d762aSopenharmony_ci//! 186336d762aSopenharmony_ci//! ``` 187336d762aSopenharmony_ci//! # #[macro_use] extern crate log; 188336d762aSopenharmony_ci//! #[cfg(test)] 189336d762aSopenharmony_ci//! mod tests { 190336d762aSopenharmony_ci//! fn init() { 191336d762aSopenharmony_ci//! let _ = env_logger::builder().is_test(true).try_init(); 192336d762aSopenharmony_ci//! } 193336d762aSopenharmony_ci//! 194336d762aSopenharmony_ci//! #[test] 195336d762aSopenharmony_ci//! fn it_works() { 196336d762aSopenharmony_ci//! init(); 197336d762aSopenharmony_ci//! 198336d762aSopenharmony_ci//! info!("This record will be captured by `cargo test`"); 199336d762aSopenharmony_ci//! 200336d762aSopenharmony_ci//! assert_eq!(2, 1 + 1); 201336d762aSopenharmony_ci//! } 202336d762aSopenharmony_ci//! } 203336d762aSopenharmony_ci//! ``` 204336d762aSopenharmony_ci//! 205336d762aSopenharmony_ci//! Enabling test capturing comes at the expense of color and other style support 206336d762aSopenharmony_ci//! and may have performance implications. 207336d762aSopenharmony_ci//! 208336d762aSopenharmony_ci//! ## Disabling colors 209336d762aSopenharmony_ci//! 210336d762aSopenharmony_ci//! Colors and other styles can be configured with the `RUST_LOG_STYLE` 211336d762aSopenharmony_ci//! environment variable. It accepts the following values: 212336d762aSopenharmony_ci//! 213336d762aSopenharmony_ci//! * `auto` (default) will attempt to print style characters, but don't force the issue. 214336d762aSopenharmony_ci//! If the console isn't available on Windows, or if TERM=dumb, for example, then don't print colors. 215336d762aSopenharmony_ci//! * `always` will always print style characters even if they aren't supported by the terminal. 216336d762aSopenharmony_ci//! This includes emitting ANSI colors on Windows if the console API is unavailable. 217336d762aSopenharmony_ci//! * `never` will never print style characters. 218336d762aSopenharmony_ci//! 219336d762aSopenharmony_ci//! ## Tweaking the default format 220336d762aSopenharmony_ci//! 221336d762aSopenharmony_ci//! Parts of the default format can be excluded from the log output using the [`Builder`]. 222336d762aSopenharmony_ci//! The following example excludes the timestamp from the log output: 223336d762aSopenharmony_ci//! 224336d762aSopenharmony_ci//! ``` 225336d762aSopenharmony_ci//! env_logger::builder() 226336d762aSopenharmony_ci//! .format_timestamp(None) 227336d762aSopenharmony_ci//! .init(); 228336d762aSopenharmony_ci//! ``` 229336d762aSopenharmony_ci//! 230336d762aSopenharmony_ci//! ### Stability of the default format 231336d762aSopenharmony_ci//! 232336d762aSopenharmony_ci//! The default format won't optimise for long-term stability, and explicitly makes no 233336d762aSopenharmony_ci//! guarantees about the stability of its output across major, minor or patch version 234336d762aSopenharmony_ci//! bumps during `0.x`. 235336d762aSopenharmony_ci//! 236336d762aSopenharmony_ci//! If you want to capture or interpret the output of `env_logger` programmatically 237336d762aSopenharmony_ci//! then you should use a custom format. 238336d762aSopenharmony_ci//! 239336d762aSopenharmony_ci//! ### Using a custom format 240336d762aSopenharmony_ci//! 241336d762aSopenharmony_ci//! Custom formats can be provided as closures to the [`Builder`]. 242336d762aSopenharmony_ci//! These closures take a [`Formatter`] and `log::Record` as arguments: 243336d762aSopenharmony_ci//! 244336d762aSopenharmony_ci//! ``` 245336d762aSopenharmony_ci//! use std::io::Write; 246336d762aSopenharmony_ci//! 247336d762aSopenharmony_ci//! env_logger::builder() 248336d762aSopenharmony_ci//! .format(|buf, record| { 249336d762aSopenharmony_ci//! writeln!(buf, "{}: {}", record.level(), record.args()) 250336d762aSopenharmony_ci//! }) 251336d762aSopenharmony_ci//! .init(); 252336d762aSopenharmony_ci//! ``` 253336d762aSopenharmony_ci//! 254336d762aSopenharmony_ci//! See the [`fmt`] module for more details about custom formats. 255336d762aSopenharmony_ci//! 256336d762aSopenharmony_ci//! ## Specifying defaults for environment variables 257336d762aSopenharmony_ci//! 258336d762aSopenharmony_ci//! `env_logger` can read configuration from environment variables. 259336d762aSopenharmony_ci//! If these variables aren't present, the default value to use can be tweaked with the [`Env`] type. 260336d762aSopenharmony_ci//! The following example defaults to log `warn` and above if the `RUST_LOG` environment variable 261336d762aSopenharmony_ci//! isn't set: 262336d762aSopenharmony_ci//! 263336d762aSopenharmony_ci//! ``` 264336d762aSopenharmony_ci//! use env_logger::Env; 265336d762aSopenharmony_ci//! 266336d762aSopenharmony_ci//! env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(); 267336d762aSopenharmony_ci//! ``` 268336d762aSopenharmony_ci//! 269336d762aSopenharmony_ci//! [gh-repo-examples]: https://github.com/env-logger-rs/env_logger/tree/main/examples 270336d762aSopenharmony_ci//! [level-enum]: https://docs.rs/log/latest/log/enum.Level.html 271336d762aSopenharmony_ci//! [log-crate-url]: https://docs.rs/log/ 272336d762aSopenharmony_ci//! [`Builder`]: struct.Builder.html 273336d762aSopenharmony_ci//! [`Builder::is_test`]: struct.Builder.html#method.is_test 274336d762aSopenharmony_ci//! [`Env`]: struct.Env.html 275336d762aSopenharmony_ci//! [`fmt`]: fmt/index.html 276336d762aSopenharmony_ci 277336d762aSopenharmony_ci#![doc( 278336d762aSopenharmony_ci html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", 279336d762aSopenharmony_ci html_favicon_url = "https://www.rust-lang.org/static/images/favicon.ico" 280336d762aSopenharmony_ci)] 281336d762aSopenharmony_ci// When compiled for the rustc compiler itself we want to make sure that this is 282336d762aSopenharmony_ci// an unstable crate 283336d762aSopenharmony_ci#![cfg_attr(rustbuild, feature(staged_api, rustc_private))] 284336d762aSopenharmony_ci#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))] 285336d762aSopenharmony_ci#![deny(missing_debug_implementations, missing_docs)] 286336d762aSopenharmony_ci 287336d762aSopenharmony_ciuse std::{borrow::Cow, cell::RefCell, env, io}; 288336d762aSopenharmony_ci 289336d762aSopenharmony_ciuse log::{LevelFilter, Log, Metadata, Record, SetLoggerError}; 290336d762aSopenharmony_ci 291336d762aSopenharmony_cipub mod filter; 292336d762aSopenharmony_cipub mod fmt; 293336d762aSopenharmony_ci 294336d762aSopenharmony_cipub use self::fmt::glob::*; 295336d762aSopenharmony_ci 296336d762aSopenharmony_ciuse self::filter::Filter; 297336d762aSopenharmony_ciuse self::fmt::writer::{self, Writer}; 298336d762aSopenharmony_ciuse self::fmt::{FormatFn, Formatter}; 299336d762aSopenharmony_ci 300336d762aSopenharmony_ci/// The default name for the environment variable to read filters from. 301336d762aSopenharmony_cipub const DEFAULT_FILTER_ENV: &str = "RUST_LOG"; 302336d762aSopenharmony_ci 303336d762aSopenharmony_ci/// The default name for the environment variable to read style preferences from. 304336d762aSopenharmony_cipub const DEFAULT_WRITE_STYLE_ENV: &str = "RUST_LOG_STYLE"; 305336d762aSopenharmony_ci 306336d762aSopenharmony_ci/// Set of environment variables to configure from. 307336d762aSopenharmony_ci/// 308336d762aSopenharmony_ci/// # Default environment variables 309336d762aSopenharmony_ci/// 310336d762aSopenharmony_ci/// By default, the `Env` will read the following environment variables: 311336d762aSopenharmony_ci/// 312336d762aSopenharmony_ci/// - `RUST_LOG`: the level filter 313336d762aSopenharmony_ci/// - `RUST_LOG_STYLE`: whether or not to print styles with records. 314336d762aSopenharmony_ci/// 315336d762aSopenharmony_ci/// These sources can be configured using the builder methods on `Env`. 316336d762aSopenharmony_ci#[derive(Debug)] 317336d762aSopenharmony_cipub struct Env<'a> { 318336d762aSopenharmony_ci filter: Var<'a>, 319336d762aSopenharmony_ci write_style: Var<'a>, 320336d762aSopenharmony_ci} 321336d762aSopenharmony_ci 322336d762aSopenharmony_ci#[derive(Debug)] 323336d762aSopenharmony_cistruct Var<'a> { 324336d762aSopenharmony_ci name: Cow<'a, str>, 325336d762aSopenharmony_ci default: Option<Cow<'a, str>>, 326336d762aSopenharmony_ci} 327336d762aSopenharmony_ci 328336d762aSopenharmony_ci/// The env logger. 329336d762aSopenharmony_ci/// 330336d762aSopenharmony_ci/// This struct implements the `Log` trait from the [`log` crate][log-crate-url], 331336d762aSopenharmony_ci/// which allows it to act as a logger. 332336d762aSopenharmony_ci/// 333336d762aSopenharmony_ci/// The [`init()`], [`try_init()`], [`Builder::init()`] and [`Builder::try_init()`] 334336d762aSopenharmony_ci/// methods will each construct a `Logger` and immediately initialize it as the 335336d762aSopenharmony_ci/// default global logger. 336336d762aSopenharmony_ci/// 337336d762aSopenharmony_ci/// If you'd instead need access to the constructed `Logger`, you can use 338336d762aSopenharmony_ci/// the associated [`Builder`] and install it with the 339336d762aSopenharmony_ci/// [`log` crate][log-crate-url] directly. 340336d762aSopenharmony_ci/// 341336d762aSopenharmony_ci/// [log-crate-url]: https://docs.rs/log/ 342336d762aSopenharmony_ci/// [`init()`]: fn.init.html 343336d762aSopenharmony_ci/// [`try_init()`]: fn.try_init.html 344336d762aSopenharmony_ci/// [`Builder::init()`]: struct.Builder.html#method.init 345336d762aSopenharmony_ci/// [`Builder::try_init()`]: struct.Builder.html#method.try_init 346336d762aSopenharmony_ci/// [`Builder`]: struct.Builder.html 347336d762aSopenharmony_cipub struct Logger { 348336d762aSopenharmony_ci writer: Writer, 349336d762aSopenharmony_ci filter: Filter, 350336d762aSopenharmony_ci format: FormatFn, 351336d762aSopenharmony_ci} 352336d762aSopenharmony_ci 353336d762aSopenharmony_ci/// `Builder` acts as builder for initializing a `Logger`. 354336d762aSopenharmony_ci/// 355336d762aSopenharmony_ci/// It can be used to customize the log format, change the environment variable used 356336d762aSopenharmony_ci/// to provide the logging directives and also set the default log level filter. 357336d762aSopenharmony_ci/// 358336d762aSopenharmony_ci/// # Examples 359336d762aSopenharmony_ci/// 360336d762aSopenharmony_ci/// ``` 361336d762aSopenharmony_ci/// # #[macro_use] extern crate log; 362336d762aSopenharmony_ci/// # use std::io::Write; 363336d762aSopenharmony_ci/// use env_logger::Builder; 364336d762aSopenharmony_ci/// use log::LevelFilter; 365336d762aSopenharmony_ci/// 366336d762aSopenharmony_ci/// let mut builder = Builder::from_default_env(); 367336d762aSopenharmony_ci/// 368336d762aSopenharmony_ci/// builder 369336d762aSopenharmony_ci/// .format(|buf, record| writeln!(buf, "{} - {}", record.level(), record.args())) 370336d762aSopenharmony_ci/// .filter(None, LevelFilter::Info) 371336d762aSopenharmony_ci/// .init(); 372336d762aSopenharmony_ci/// 373336d762aSopenharmony_ci/// error!("error message"); 374336d762aSopenharmony_ci/// info!("info message"); 375336d762aSopenharmony_ci/// ``` 376336d762aSopenharmony_ci#[derive(Default)] 377336d762aSopenharmony_cipub struct Builder { 378336d762aSopenharmony_ci filter: filter::Builder, 379336d762aSopenharmony_ci writer: writer::Builder, 380336d762aSopenharmony_ci format: fmt::Builder, 381336d762aSopenharmony_ci built: bool, 382336d762aSopenharmony_ci} 383336d762aSopenharmony_ci 384336d762aSopenharmony_ciimpl Builder { 385336d762aSopenharmony_ci /// Initializes the log builder with defaults. 386336d762aSopenharmony_ci /// 387336d762aSopenharmony_ci /// **NOTE:** This method won't read from any environment variables. 388336d762aSopenharmony_ci /// Use the [`filter`] and [`write_style`] methods to configure the builder 389336d762aSopenharmony_ci /// or use [`from_env`] or [`from_default_env`] instead. 390336d762aSopenharmony_ci /// 391336d762aSopenharmony_ci /// # Examples 392336d762aSopenharmony_ci /// 393336d762aSopenharmony_ci /// Create a new builder and configure filters and style: 394336d762aSopenharmony_ci /// 395336d762aSopenharmony_ci /// ``` 396336d762aSopenharmony_ci /// use log::LevelFilter; 397336d762aSopenharmony_ci /// use env_logger::{Builder, WriteStyle}; 398336d762aSopenharmony_ci /// 399336d762aSopenharmony_ci /// let mut builder = Builder::new(); 400336d762aSopenharmony_ci /// 401336d762aSopenharmony_ci /// builder 402336d762aSopenharmony_ci /// .filter(None, LevelFilter::Info) 403336d762aSopenharmony_ci /// .write_style(WriteStyle::Always) 404336d762aSopenharmony_ci /// .init(); 405336d762aSopenharmony_ci /// ``` 406336d762aSopenharmony_ci /// 407336d762aSopenharmony_ci /// [`filter`]: #method.filter 408336d762aSopenharmony_ci /// [`write_style`]: #method.write_style 409336d762aSopenharmony_ci /// [`from_env`]: #method.from_env 410336d762aSopenharmony_ci /// [`from_default_env`]: #method.from_default_env 411336d762aSopenharmony_ci pub fn new() -> Builder { 412336d762aSopenharmony_ci Default::default() 413336d762aSopenharmony_ci } 414336d762aSopenharmony_ci 415336d762aSopenharmony_ci /// Initializes the log builder from the environment. 416336d762aSopenharmony_ci /// 417336d762aSopenharmony_ci /// The variables used to read configuration from can be tweaked before 418336d762aSopenharmony_ci /// passing in. 419336d762aSopenharmony_ci /// 420336d762aSopenharmony_ci /// # Examples 421336d762aSopenharmony_ci /// 422336d762aSopenharmony_ci /// Initialise a logger reading the log filter from an environment variable 423336d762aSopenharmony_ci /// called `MY_LOG`: 424336d762aSopenharmony_ci /// 425336d762aSopenharmony_ci /// ``` 426336d762aSopenharmony_ci /// use env_logger::Builder; 427336d762aSopenharmony_ci /// 428336d762aSopenharmony_ci /// let mut builder = Builder::from_env("MY_LOG"); 429336d762aSopenharmony_ci /// builder.init(); 430336d762aSopenharmony_ci /// ``` 431336d762aSopenharmony_ci /// 432336d762aSopenharmony_ci /// Initialise a logger using the `MY_LOG` variable for filtering and 433336d762aSopenharmony_ci /// `MY_LOG_STYLE` for whether or not to write styles: 434336d762aSopenharmony_ci /// 435336d762aSopenharmony_ci /// ``` 436336d762aSopenharmony_ci /// use env_logger::{Builder, Env}; 437336d762aSopenharmony_ci /// 438336d762aSopenharmony_ci /// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); 439336d762aSopenharmony_ci /// 440336d762aSopenharmony_ci /// let mut builder = Builder::from_env(env); 441336d762aSopenharmony_ci /// builder.init(); 442336d762aSopenharmony_ci /// ``` 443336d762aSopenharmony_ci pub fn from_env<'a, E>(env: E) -> Self 444336d762aSopenharmony_ci where 445336d762aSopenharmony_ci E: Into<Env<'a>>, 446336d762aSopenharmony_ci { 447336d762aSopenharmony_ci let mut builder = Builder::new(); 448336d762aSopenharmony_ci builder.parse_env(env); 449336d762aSopenharmony_ci builder 450336d762aSopenharmony_ci } 451336d762aSopenharmony_ci 452336d762aSopenharmony_ci /// Applies the configuration from the environment. 453336d762aSopenharmony_ci /// 454336d762aSopenharmony_ci /// This function allows a builder to be configured with default parameters, 455336d762aSopenharmony_ci /// to be then overridden by the environment. 456336d762aSopenharmony_ci /// 457336d762aSopenharmony_ci /// # Examples 458336d762aSopenharmony_ci /// 459336d762aSopenharmony_ci /// Initialise a logger with filter level `Off`, then override the log 460336d762aSopenharmony_ci /// filter from an environment variable called `MY_LOG`: 461336d762aSopenharmony_ci /// 462336d762aSopenharmony_ci /// ``` 463336d762aSopenharmony_ci /// use log::LevelFilter; 464336d762aSopenharmony_ci /// use env_logger::Builder; 465336d762aSopenharmony_ci /// 466336d762aSopenharmony_ci /// let mut builder = Builder::new(); 467336d762aSopenharmony_ci /// 468336d762aSopenharmony_ci /// builder.filter_level(LevelFilter::Off); 469336d762aSopenharmony_ci /// builder.parse_env("MY_LOG"); 470336d762aSopenharmony_ci /// builder.init(); 471336d762aSopenharmony_ci /// ``` 472336d762aSopenharmony_ci /// 473336d762aSopenharmony_ci /// Initialise a logger with filter level `Off`, then use the `MY_LOG` 474336d762aSopenharmony_ci /// variable to override filtering and `MY_LOG_STYLE` to override whether 475336d762aSopenharmony_ci /// or not to write styles: 476336d762aSopenharmony_ci /// 477336d762aSopenharmony_ci /// ``` 478336d762aSopenharmony_ci /// use log::LevelFilter; 479336d762aSopenharmony_ci /// use env_logger::{Builder, Env}; 480336d762aSopenharmony_ci /// 481336d762aSopenharmony_ci /// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); 482336d762aSopenharmony_ci /// 483336d762aSopenharmony_ci /// let mut builder = Builder::new(); 484336d762aSopenharmony_ci /// builder.filter_level(LevelFilter::Off); 485336d762aSopenharmony_ci /// builder.parse_env(env); 486336d762aSopenharmony_ci /// builder.init(); 487336d762aSopenharmony_ci /// ``` 488336d762aSopenharmony_ci pub fn parse_env<'a, E>(&mut self, env: E) -> &mut Self 489336d762aSopenharmony_ci where 490336d762aSopenharmony_ci E: Into<Env<'a>>, 491336d762aSopenharmony_ci { 492336d762aSopenharmony_ci let env = env.into(); 493336d762aSopenharmony_ci 494336d762aSopenharmony_ci if let Some(s) = env.get_filter() { 495336d762aSopenharmony_ci self.parse_filters(&s); 496336d762aSopenharmony_ci } 497336d762aSopenharmony_ci 498336d762aSopenharmony_ci if let Some(s) = env.get_write_style() { 499336d762aSopenharmony_ci self.parse_write_style(&s); 500336d762aSopenharmony_ci } 501336d762aSopenharmony_ci 502336d762aSopenharmony_ci self 503336d762aSopenharmony_ci } 504336d762aSopenharmony_ci 505336d762aSopenharmony_ci /// Initializes the log builder from the environment using default variable names. 506336d762aSopenharmony_ci /// 507336d762aSopenharmony_ci /// This method is a convenient way to call `from_env(Env::default())` without 508336d762aSopenharmony_ci /// having to use the `Env` type explicitly. The builder will use the 509336d762aSopenharmony_ci /// [default environment variables]. 510336d762aSopenharmony_ci /// 511336d762aSopenharmony_ci /// # Examples 512336d762aSopenharmony_ci /// 513336d762aSopenharmony_ci /// Initialise a logger using the default environment variables: 514336d762aSopenharmony_ci /// 515336d762aSopenharmony_ci /// ``` 516336d762aSopenharmony_ci /// use env_logger::Builder; 517336d762aSopenharmony_ci /// 518336d762aSopenharmony_ci /// let mut builder = Builder::from_default_env(); 519336d762aSopenharmony_ci /// builder.init(); 520336d762aSopenharmony_ci /// ``` 521336d762aSopenharmony_ci /// 522336d762aSopenharmony_ci /// [default environment variables]: struct.Env.html#default-environment-variables 523336d762aSopenharmony_ci pub fn from_default_env() -> Self { 524336d762aSopenharmony_ci Self::from_env(Env::default()) 525336d762aSopenharmony_ci } 526336d762aSopenharmony_ci 527336d762aSopenharmony_ci /// Applies the configuration from the environment using default variable names. 528336d762aSopenharmony_ci /// 529336d762aSopenharmony_ci /// This method is a convenient way to call `parse_env(Env::default())` without 530336d762aSopenharmony_ci /// having to use the `Env` type explicitly. The builder will use the 531336d762aSopenharmony_ci /// [default environment variables]. 532336d762aSopenharmony_ci /// 533336d762aSopenharmony_ci /// # Examples 534336d762aSopenharmony_ci /// 535336d762aSopenharmony_ci /// Initialise a logger with filter level `Off`, then configure it using the 536336d762aSopenharmony_ci /// default environment variables: 537336d762aSopenharmony_ci /// 538336d762aSopenharmony_ci /// ``` 539336d762aSopenharmony_ci /// use log::LevelFilter; 540336d762aSopenharmony_ci /// use env_logger::Builder; 541336d762aSopenharmony_ci /// 542336d762aSopenharmony_ci /// let mut builder = Builder::new(); 543336d762aSopenharmony_ci /// builder.filter_level(LevelFilter::Off); 544336d762aSopenharmony_ci /// builder.parse_default_env(); 545336d762aSopenharmony_ci /// builder.init(); 546336d762aSopenharmony_ci /// ``` 547336d762aSopenharmony_ci /// 548336d762aSopenharmony_ci /// [default environment variables]: struct.Env.html#default-environment-variables 549336d762aSopenharmony_ci pub fn parse_default_env(&mut self) -> &mut Self { 550336d762aSopenharmony_ci self.parse_env(Env::default()) 551336d762aSopenharmony_ci } 552336d762aSopenharmony_ci 553336d762aSopenharmony_ci /// Sets the format function for formatting the log output. 554336d762aSopenharmony_ci /// 555336d762aSopenharmony_ci /// This function is called on each record logged and should format the 556336d762aSopenharmony_ci /// log record and output it to the given [`Formatter`]. 557336d762aSopenharmony_ci /// 558336d762aSopenharmony_ci /// The format function is expected to output the string directly to the 559336d762aSopenharmony_ci /// `Formatter` so that implementations can use the [`std::fmt`] macros 560336d762aSopenharmony_ci /// to format and output without intermediate heap allocations. The default 561336d762aSopenharmony_ci /// `env_logger` formatter takes advantage of this. 562336d762aSopenharmony_ci /// 563336d762aSopenharmony_ci /// # Examples 564336d762aSopenharmony_ci /// 565336d762aSopenharmony_ci /// Use a custom format to write only the log message: 566336d762aSopenharmony_ci /// 567336d762aSopenharmony_ci /// ``` 568336d762aSopenharmony_ci /// use std::io::Write; 569336d762aSopenharmony_ci /// use env_logger::Builder; 570336d762aSopenharmony_ci /// 571336d762aSopenharmony_ci /// let mut builder = Builder::new(); 572336d762aSopenharmony_ci /// 573336d762aSopenharmony_ci /// builder.format(|buf, record| writeln!(buf, "{}", record.args())); 574336d762aSopenharmony_ci /// ``` 575336d762aSopenharmony_ci /// 576336d762aSopenharmony_ci /// [`Formatter`]: fmt/struct.Formatter.html 577336d762aSopenharmony_ci /// [`String`]: https://doc.rust-lang.org/stable/std/string/struct.String.html 578336d762aSopenharmony_ci /// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html 579336d762aSopenharmony_ci pub fn format<F: 'static>(&mut self, format: F) -> &mut Self 580336d762aSopenharmony_ci where 581336d762aSopenharmony_ci F: Fn(&mut Formatter, &Record) -> io::Result<()> + Sync + Send, 582336d762aSopenharmony_ci { 583336d762aSopenharmony_ci self.format.custom_format = Some(Box::new(format)); 584336d762aSopenharmony_ci self 585336d762aSopenharmony_ci } 586336d762aSopenharmony_ci 587336d762aSopenharmony_ci /// Use the default format. 588336d762aSopenharmony_ci /// 589336d762aSopenharmony_ci /// This method will clear any custom format set on the builder. 590336d762aSopenharmony_ci pub fn default_format(&mut self) -> &mut Self { 591336d762aSopenharmony_ci self.format = Default::default(); 592336d762aSopenharmony_ci self 593336d762aSopenharmony_ci } 594336d762aSopenharmony_ci 595336d762aSopenharmony_ci /// Whether or not to write the level in the default format. 596336d762aSopenharmony_ci pub fn format_level(&mut self, write: bool) -> &mut Self { 597336d762aSopenharmony_ci self.format.format_level = write; 598336d762aSopenharmony_ci self 599336d762aSopenharmony_ci } 600336d762aSopenharmony_ci 601336d762aSopenharmony_ci /// Whether or not to write the module path in the default format. 602336d762aSopenharmony_ci pub fn format_module_path(&mut self, write: bool) -> &mut Self { 603336d762aSopenharmony_ci self.format.format_module_path = write; 604336d762aSopenharmony_ci self 605336d762aSopenharmony_ci } 606336d762aSopenharmony_ci 607336d762aSopenharmony_ci /// Whether or not to write the target in the default format. 608336d762aSopenharmony_ci pub fn format_target(&mut self, write: bool) -> &mut Self { 609336d762aSopenharmony_ci self.format.format_target = write; 610336d762aSopenharmony_ci self 611336d762aSopenharmony_ci } 612336d762aSopenharmony_ci 613336d762aSopenharmony_ci /// Configures the amount of spaces to use to indent multiline log records. 614336d762aSopenharmony_ci /// A value of `None` disables any kind of indentation. 615336d762aSopenharmony_ci pub fn format_indent(&mut self, indent: Option<usize>) -> &mut Self { 616336d762aSopenharmony_ci self.format.format_indent = indent; 617336d762aSopenharmony_ci self 618336d762aSopenharmony_ci } 619336d762aSopenharmony_ci 620336d762aSopenharmony_ci /// Configures if timestamp should be included and in what precision. 621336d762aSopenharmony_ci pub fn format_timestamp(&mut self, timestamp: Option<fmt::TimestampPrecision>) -> &mut Self { 622336d762aSopenharmony_ci self.format.format_timestamp = timestamp; 623336d762aSopenharmony_ci self 624336d762aSopenharmony_ci } 625336d762aSopenharmony_ci 626336d762aSopenharmony_ci /// Configures the timestamp to use second precision. 627336d762aSopenharmony_ci pub fn format_timestamp_secs(&mut self) -> &mut Self { 628336d762aSopenharmony_ci self.format_timestamp(Some(fmt::TimestampPrecision::Seconds)) 629336d762aSopenharmony_ci } 630336d762aSopenharmony_ci 631336d762aSopenharmony_ci /// Configures the timestamp to use millisecond precision. 632336d762aSopenharmony_ci pub fn format_timestamp_millis(&mut self) -> &mut Self { 633336d762aSopenharmony_ci self.format_timestamp(Some(fmt::TimestampPrecision::Millis)) 634336d762aSopenharmony_ci } 635336d762aSopenharmony_ci 636336d762aSopenharmony_ci /// Configures the timestamp to use microsecond precision. 637336d762aSopenharmony_ci pub fn format_timestamp_micros(&mut self) -> &mut Self { 638336d762aSopenharmony_ci self.format_timestamp(Some(fmt::TimestampPrecision::Micros)) 639336d762aSopenharmony_ci } 640336d762aSopenharmony_ci 641336d762aSopenharmony_ci /// Configures the timestamp to use nanosecond precision. 642336d762aSopenharmony_ci pub fn format_timestamp_nanos(&mut self) -> &mut Self { 643336d762aSopenharmony_ci self.format_timestamp(Some(fmt::TimestampPrecision::Nanos)) 644336d762aSopenharmony_ci } 645336d762aSopenharmony_ci 646336d762aSopenharmony_ci /// Configures the end of line suffix. 647336d762aSopenharmony_ci pub fn format_suffix(&mut self, suffix: &'static str) -> &mut Self { 648336d762aSopenharmony_ci self.format.format_suffix = suffix; 649336d762aSopenharmony_ci self 650336d762aSopenharmony_ci } 651336d762aSopenharmony_ci 652336d762aSopenharmony_ci /// Adds a directive to the filter for a specific module. 653336d762aSopenharmony_ci /// 654336d762aSopenharmony_ci /// # Examples 655336d762aSopenharmony_ci /// 656336d762aSopenharmony_ci /// Only include messages for info and above for logs in `path::to::module`: 657336d762aSopenharmony_ci /// 658336d762aSopenharmony_ci /// ``` 659336d762aSopenharmony_ci /// use env_logger::Builder; 660336d762aSopenharmony_ci /// use log::LevelFilter; 661336d762aSopenharmony_ci /// 662336d762aSopenharmony_ci /// let mut builder = Builder::new(); 663336d762aSopenharmony_ci /// 664336d762aSopenharmony_ci /// builder.filter_module("path::to::module", LevelFilter::Info); 665336d762aSopenharmony_ci /// ``` 666336d762aSopenharmony_ci pub fn filter_module(&mut self, module: &str, level: LevelFilter) -> &mut Self { 667336d762aSopenharmony_ci self.filter.filter_module(module, level); 668336d762aSopenharmony_ci self 669336d762aSopenharmony_ci } 670336d762aSopenharmony_ci 671336d762aSopenharmony_ci /// Adds a directive to the filter for all modules. 672336d762aSopenharmony_ci /// 673336d762aSopenharmony_ci /// # Examples 674336d762aSopenharmony_ci /// 675336d762aSopenharmony_ci /// Only include messages for info and above for logs globally: 676336d762aSopenharmony_ci /// 677336d762aSopenharmony_ci /// ``` 678336d762aSopenharmony_ci /// use env_logger::Builder; 679336d762aSopenharmony_ci /// use log::LevelFilter; 680336d762aSopenharmony_ci /// 681336d762aSopenharmony_ci /// let mut builder = Builder::new(); 682336d762aSopenharmony_ci /// 683336d762aSopenharmony_ci /// builder.filter_level(LevelFilter::Info); 684336d762aSopenharmony_ci /// ``` 685336d762aSopenharmony_ci pub fn filter_level(&mut self, level: LevelFilter) -> &mut Self { 686336d762aSopenharmony_ci self.filter.filter_level(level); 687336d762aSopenharmony_ci self 688336d762aSopenharmony_ci } 689336d762aSopenharmony_ci 690336d762aSopenharmony_ci /// Adds filters to the logger. 691336d762aSopenharmony_ci /// 692336d762aSopenharmony_ci /// The given module (if any) will log at most the specified level provided. 693336d762aSopenharmony_ci /// If no module is provided then the filter will apply to all log messages. 694336d762aSopenharmony_ci /// 695336d762aSopenharmony_ci /// # Examples 696336d762aSopenharmony_ci /// 697336d762aSopenharmony_ci /// Only include messages for info and above for logs in `path::to::module`: 698336d762aSopenharmony_ci /// 699336d762aSopenharmony_ci /// ``` 700336d762aSopenharmony_ci /// use env_logger::Builder; 701336d762aSopenharmony_ci /// use log::LevelFilter; 702336d762aSopenharmony_ci /// 703336d762aSopenharmony_ci /// let mut builder = Builder::new(); 704336d762aSopenharmony_ci /// 705336d762aSopenharmony_ci /// builder.filter(Some("path::to::module"), LevelFilter::Info); 706336d762aSopenharmony_ci /// ``` 707336d762aSopenharmony_ci pub fn filter(&mut self, module: Option<&str>, level: LevelFilter) -> &mut Self { 708336d762aSopenharmony_ci self.filter.filter(module, level); 709336d762aSopenharmony_ci self 710336d762aSopenharmony_ci } 711336d762aSopenharmony_ci 712336d762aSopenharmony_ci /// Parses the directives string in the same form as the `RUST_LOG` 713336d762aSopenharmony_ci /// environment variable. 714336d762aSopenharmony_ci /// 715336d762aSopenharmony_ci /// See the module documentation for more details. 716336d762aSopenharmony_ci pub fn parse_filters(&mut self, filters: &str) -> &mut Self { 717336d762aSopenharmony_ci self.filter.parse(filters); 718336d762aSopenharmony_ci self 719336d762aSopenharmony_ci } 720336d762aSopenharmony_ci 721336d762aSopenharmony_ci /// Sets the target for the log output. 722336d762aSopenharmony_ci /// 723336d762aSopenharmony_ci /// Env logger can log to either stdout, stderr or a custom pipe. The default is stderr. 724336d762aSopenharmony_ci /// 725336d762aSopenharmony_ci /// The custom pipe can be used to send the log messages to a custom sink (for example a file). 726336d762aSopenharmony_ci /// Do note that direct writes to a file can become a bottleneck due to IO operation times. 727336d762aSopenharmony_ci /// 728336d762aSopenharmony_ci /// # Examples 729336d762aSopenharmony_ci /// 730336d762aSopenharmony_ci /// Write log message to `stdout`: 731336d762aSopenharmony_ci /// 732336d762aSopenharmony_ci /// ``` 733336d762aSopenharmony_ci /// use env_logger::{Builder, Target}; 734336d762aSopenharmony_ci /// 735336d762aSopenharmony_ci /// let mut builder = Builder::new(); 736336d762aSopenharmony_ci /// 737336d762aSopenharmony_ci /// builder.target(Target::Stdout); 738336d762aSopenharmony_ci /// ``` 739336d762aSopenharmony_ci pub fn target(&mut self, target: fmt::Target) -> &mut Self { 740336d762aSopenharmony_ci self.writer.target(target); 741336d762aSopenharmony_ci self 742336d762aSopenharmony_ci } 743336d762aSopenharmony_ci 744336d762aSopenharmony_ci /// Sets whether or not styles will be written. 745336d762aSopenharmony_ci /// 746336d762aSopenharmony_ci /// This can be useful in environments that don't support control characters 747336d762aSopenharmony_ci /// for setting colors. 748336d762aSopenharmony_ci /// 749336d762aSopenharmony_ci /// # Examples 750336d762aSopenharmony_ci /// 751336d762aSopenharmony_ci /// Never attempt to write styles: 752336d762aSopenharmony_ci /// 753336d762aSopenharmony_ci /// ``` 754336d762aSopenharmony_ci /// use env_logger::{Builder, WriteStyle}; 755336d762aSopenharmony_ci /// 756336d762aSopenharmony_ci /// let mut builder = Builder::new(); 757336d762aSopenharmony_ci /// 758336d762aSopenharmony_ci /// builder.write_style(WriteStyle::Never); 759336d762aSopenharmony_ci /// ``` 760336d762aSopenharmony_ci pub fn write_style(&mut self, write_style: fmt::WriteStyle) -> &mut Self { 761336d762aSopenharmony_ci self.writer.write_style(write_style); 762336d762aSopenharmony_ci self 763336d762aSopenharmony_ci } 764336d762aSopenharmony_ci 765336d762aSopenharmony_ci /// Parses whether or not to write styles in the same form as the `RUST_LOG_STYLE` 766336d762aSopenharmony_ci /// environment variable. 767336d762aSopenharmony_ci /// 768336d762aSopenharmony_ci /// See the module documentation for more details. 769336d762aSopenharmony_ci pub fn parse_write_style(&mut self, write_style: &str) -> &mut Self { 770336d762aSopenharmony_ci self.writer.parse_write_style(write_style); 771336d762aSopenharmony_ci self 772336d762aSopenharmony_ci } 773336d762aSopenharmony_ci 774336d762aSopenharmony_ci /// Sets whether or not the logger will be used in unit tests. 775336d762aSopenharmony_ci /// 776336d762aSopenharmony_ci /// If `is_test` is `true` then the logger will allow the testing framework to 777336d762aSopenharmony_ci /// capture log records rather than printing them to the terminal directly. 778336d762aSopenharmony_ci pub fn is_test(&mut self, is_test: bool) -> &mut Self { 779336d762aSopenharmony_ci self.writer.is_test(is_test); 780336d762aSopenharmony_ci self 781336d762aSopenharmony_ci } 782336d762aSopenharmony_ci 783336d762aSopenharmony_ci /// Initializes the global logger with the built env logger. 784336d762aSopenharmony_ci /// 785336d762aSopenharmony_ci /// This should be called early in the execution of a Rust program. Any log 786336d762aSopenharmony_ci /// events that occur before initialization will be ignored. 787336d762aSopenharmony_ci /// 788336d762aSopenharmony_ci /// # Errors 789336d762aSopenharmony_ci /// 790336d762aSopenharmony_ci /// This function will fail if it is called more than once, or if another 791336d762aSopenharmony_ci /// library has already initialized a global logger. 792336d762aSopenharmony_ci pub fn try_init(&mut self) -> Result<(), SetLoggerError> { 793336d762aSopenharmony_ci let logger = self.build(); 794336d762aSopenharmony_ci 795336d762aSopenharmony_ci let max_level = logger.filter(); 796336d762aSopenharmony_ci let r = log::set_boxed_logger(Box::new(logger)); 797336d762aSopenharmony_ci 798336d762aSopenharmony_ci if r.is_ok() { 799336d762aSopenharmony_ci log::set_max_level(max_level); 800336d762aSopenharmony_ci } 801336d762aSopenharmony_ci 802336d762aSopenharmony_ci r 803336d762aSopenharmony_ci } 804336d762aSopenharmony_ci 805336d762aSopenharmony_ci /// Initializes the global logger with the built env logger. 806336d762aSopenharmony_ci /// 807336d762aSopenharmony_ci /// This should be called early in the execution of a Rust program. Any log 808336d762aSopenharmony_ci /// events that occur before initialization will be ignored. 809336d762aSopenharmony_ci /// 810336d762aSopenharmony_ci /// # Panics 811336d762aSopenharmony_ci /// 812336d762aSopenharmony_ci /// This function will panic if it is called more than once, or if another 813336d762aSopenharmony_ci /// library has already initialized a global logger. 814336d762aSopenharmony_ci pub fn init(&mut self) { 815336d762aSopenharmony_ci self.try_init() 816336d762aSopenharmony_ci .expect("Builder::init should not be called after logger initialized"); 817336d762aSopenharmony_ci } 818336d762aSopenharmony_ci 819336d762aSopenharmony_ci /// Build an env logger. 820336d762aSopenharmony_ci /// 821336d762aSopenharmony_ci /// The returned logger implements the `Log` trait and can be installed manually 822336d762aSopenharmony_ci /// or nested within another logger. 823336d762aSopenharmony_ci pub fn build(&mut self) -> Logger { 824336d762aSopenharmony_ci assert!(!self.built, "attempt to re-use consumed builder"); 825336d762aSopenharmony_ci self.built = true; 826336d762aSopenharmony_ci 827336d762aSopenharmony_ci Logger { 828336d762aSopenharmony_ci writer: self.writer.build(), 829336d762aSopenharmony_ci filter: self.filter.build(), 830336d762aSopenharmony_ci format: self.format.build(), 831336d762aSopenharmony_ci } 832336d762aSopenharmony_ci } 833336d762aSopenharmony_ci} 834336d762aSopenharmony_ci 835336d762aSopenharmony_ciimpl Logger { 836336d762aSopenharmony_ci /// Creates the logger from the environment. 837336d762aSopenharmony_ci /// 838336d762aSopenharmony_ci /// The variables used to read configuration from can be tweaked before 839336d762aSopenharmony_ci /// passing in. 840336d762aSopenharmony_ci /// 841336d762aSopenharmony_ci /// # Examples 842336d762aSopenharmony_ci /// 843336d762aSopenharmony_ci /// Create a logger reading the log filter from an environment variable 844336d762aSopenharmony_ci /// called `MY_LOG`: 845336d762aSopenharmony_ci /// 846336d762aSopenharmony_ci /// ``` 847336d762aSopenharmony_ci /// use env_logger::Logger; 848336d762aSopenharmony_ci /// 849336d762aSopenharmony_ci /// let logger = Logger::from_env("MY_LOG"); 850336d762aSopenharmony_ci /// ``` 851336d762aSopenharmony_ci /// 852336d762aSopenharmony_ci /// Create a logger using the `MY_LOG` variable for filtering and 853336d762aSopenharmony_ci /// `MY_LOG_STYLE` for whether or not to write styles: 854336d762aSopenharmony_ci /// 855336d762aSopenharmony_ci /// ``` 856336d762aSopenharmony_ci /// use env_logger::{Logger, Env}; 857336d762aSopenharmony_ci /// 858336d762aSopenharmony_ci /// let env = Env::new().filter_or("MY_LOG", "info").write_style_or("MY_LOG_STYLE", "always"); 859336d762aSopenharmony_ci /// 860336d762aSopenharmony_ci /// let logger = Logger::from_env(env); 861336d762aSopenharmony_ci /// ``` 862336d762aSopenharmony_ci pub fn from_env<'a, E>(env: E) -> Self 863336d762aSopenharmony_ci where 864336d762aSopenharmony_ci E: Into<Env<'a>>, 865336d762aSopenharmony_ci { 866336d762aSopenharmony_ci Builder::from_env(env).build() 867336d762aSopenharmony_ci } 868336d762aSopenharmony_ci 869336d762aSopenharmony_ci /// Creates the logger from the environment using default variable names. 870336d762aSopenharmony_ci /// 871336d762aSopenharmony_ci /// This method is a convenient way to call `from_env(Env::default())` without 872336d762aSopenharmony_ci /// having to use the `Env` type explicitly. The logger will use the 873336d762aSopenharmony_ci /// [default environment variables]. 874336d762aSopenharmony_ci /// 875336d762aSopenharmony_ci /// # Examples 876336d762aSopenharmony_ci /// 877336d762aSopenharmony_ci /// Creates a logger using the default environment variables: 878336d762aSopenharmony_ci /// 879336d762aSopenharmony_ci /// ``` 880336d762aSopenharmony_ci /// use env_logger::Logger; 881336d762aSopenharmony_ci /// 882336d762aSopenharmony_ci /// let logger = Logger::from_default_env(); 883336d762aSopenharmony_ci /// ``` 884336d762aSopenharmony_ci /// 885336d762aSopenharmony_ci /// [default environment variables]: struct.Env.html#default-environment-variables 886336d762aSopenharmony_ci pub fn from_default_env() -> Self { 887336d762aSopenharmony_ci Builder::from_default_env().build() 888336d762aSopenharmony_ci } 889336d762aSopenharmony_ci 890336d762aSopenharmony_ci /// Returns the maximum `LevelFilter` that this env logger instance is 891336d762aSopenharmony_ci /// configured to output. 892336d762aSopenharmony_ci pub fn filter(&self) -> LevelFilter { 893336d762aSopenharmony_ci self.filter.filter() 894336d762aSopenharmony_ci } 895336d762aSopenharmony_ci 896336d762aSopenharmony_ci /// Checks if this record matches the configured filter. 897336d762aSopenharmony_ci pub fn matches(&self, record: &Record) -> bool { 898336d762aSopenharmony_ci self.filter.matches(record) 899336d762aSopenharmony_ci } 900336d762aSopenharmony_ci} 901336d762aSopenharmony_ci 902336d762aSopenharmony_ciimpl Log for Logger { 903336d762aSopenharmony_ci fn enabled(&self, metadata: &Metadata) -> bool { 904336d762aSopenharmony_ci self.filter.enabled(metadata) 905336d762aSopenharmony_ci } 906336d762aSopenharmony_ci 907336d762aSopenharmony_ci fn log(&self, record: &Record) { 908336d762aSopenharmony_ci if self.matches(record) { 909336d762aSopenharmony_ci // Log records are written to a thread-local buffer before being printed 910336d762aSopenharmony_ci // to the terminal. We clear these buffers afterwards, but they aren't shrinked 911336d762aSopenharmony_ci // so will always at least have capacity for the largest log record formatted 912336d762aSopenharmony_ci // on that thread. 913336d762aSopenharmony_ci // 914336d762aSopenharmony_ci // If multiple `Logger`s are used by the same threads then the thread-local 915336d762aSopenharmony_ci // formatter might have different color support. If this is the case the 916336d762aSopenharmony_ci // formatter and its buffer are discarded and recreated. 917336d762aSopenharmony_ci 918336d762aSopenharmony_ci thread_local! { 919336d762aSopenharmony_ci static FORMATTER: RefCell<Option<Formatter>> = RefCell::new(None); 920336d762aSopenharmony_ci } 921336d762aSopenharmony_ci 922336d762aSopenharmony_ci let print = |formatter: &mut Formatter, record: &Record| { 923336d762aSopenharmony_ci let _ = 924336d762aSopenharmony_ci (self.format)(formatter, record).and_then(|_| formatter.print(&self.writer)); 925336d762aSopenharmony_ci 926336d762aSopenharmony_ci // Always clear the buffer afterwards 927336d762aSopenharmony_ci formatter.clear(); 928336d762aSopenharmony_ci }; 929336d762aSopenharmony_ci 930336d762aSopenharmony_ci let printed = FORMATTER 931336d762aSopenharmony_ci .try_with(|tl_buf| { 932336d762aSopenharmony_ci match tl_buf.try_borrow_mut() { 933336d762aSopenharmony_ci // There are no active borrows of the buffer 934336d762aSopenharmony_ci Ok(mut tl_buf) => match *tl_buf { 935336d762aSopenharmony_ci // We have a previously set formatter 936336d762aSopenharmony_ci Some(ref mut formatter) => { 937336d762aSopenharmony_ci // Check the buffer style. If it's different from the logger's 938336d762aSopenharmony_ci // style then drop the buffer and recreate it. 939336d762aSopenharmony_ci if formatter.write_style() != self.writer.write_style() { 940336d762aSopenharmony_ci *formatter = Formatter::new(&self.writer); 941336d762aSopenharmony_ci } 942336d762aSopenharmony_ci 943336d762aSopenharmony_ci print(formatter, record); 944336d762aSopenharmony_ci } 945336d762aSopenharmony_ci // We don't have a previously set formatter 946336d762aSopenharmony_ci None => { 947336d762aSopenharmony_ci let mut formatter = Formatter::new(&self.writer); 948336d762aSopenharmony_ci print(&mut formatter, record); 949336d762aSopenharmony_ci 950336d762aSopenharmony_ci *tl_buf = Some(formatter); 951336d762aSopenharmony_ci } 952336d762aSopenharmony_ci }, 953336d762aSopenharmony_ci // There's already an active borrow of the buffer (due to re-entrancy) 954336d762aSopenharmony_ci Err(_) => { 955336d762aSopenharmony_ci print(&mut Formatter::new(&self.writer), record); 956336d762aSopenharmony_ci } 957336d762aSopenharmony_ci } 958336d762aSopenharmony_ci }) 959336d762aSopenharmony_ci .is_ok(); 960336d762aSopenharmony_ci 961336d762aSopenharmony_ci if !printed { 962336d762aSopenharmony_ci // The thread-local storage was not available (because its 963336d762aSopenharmony_ci // destructor has already run). Create a new single-use 964336d762aSopenharmony_ci // Formatter on the stack for this call. 965336d762aSopenharmony_ci print(&mut Formatter::new(&self.writer), record); 966336d762aSopenharmony_ci } 967336d762aSopenharmony_ci } 968336d762aSopenharmony_ci } 969336d762aSopenharmony_ci 970336d762aSopenharmony_ci fn flush(&self) {} 971336d762aSopenharmony_ci} 972336d762aSopenharmony_ci 973336d762aSopenharmony_ciimpl<'a> Env<'a> { 974336d762aSopenharmony_ci /// Get a default set of environment variables. 975336d762aSopenharmony_ci pub fn new() -> Self { 976336d762aSopenharmony_ci Self::default() 977336d762aSopenharmony_ci } 978336d762aSopenharmony_ci 979336d762aSopenharmony_ci /// Specify an environment variable to read the filter from. 980336d762aSopenharmony_ci pub fn filter<E>(mut self, filter_env: E) -> Self 981336d762aSopenharmony_ci where 982336d762aSopenharmony_ci E: Into<Cow<'a, str>>, 983336d762aSopenharmony_ci { 984336d762aSopenharmony_ci self.filter = Var::new(filter_env); 985336d762aSopenharmony_ci 986336d762aSopenharmony_ci self 987336d762aSopenharmony_ci } 988336d762aSopenharmony_ci 989336d762aSopenharmony_ci /// Specify an environment variable to read the filter from. 990336d762aSopenharmony_ci /// 991336d762aSopenharmony_ci /// If the variable is not set, the default value will be used. 992336d762aSopenharmony_ci pub fn filter_or<E, V>(mut self, filter_env: E, default: V) -> Self 993336d762aSopenharmony_ci where 994336d762aSopenharmony_ci E: Into<Cow<'a, str>>, 995336d762aSopenharmony_ci V: Into<Cow<'a, str>>, 996336d762aSopenharmony_ci { 997336d762aSopenharmony_ci self.filter = Var::new_with_default(filter_env, default); 998336d762aSopenharmony_ci 999336d762aSopenharmony_ci self 1000336d762aSopenharmony_ci } 1001336d762aSopenharmony_ci 1002336d762aSopenharmony_ci /// Use the default environment variable to read the filter from. 1003336d762aSopenharmony_ci /// 1004336d762aSopenharmony_ci /// If the variable is not set, the default value will be used. 1005336d762aSopenharmony_ci pub fn default_filter_or<V>(mut self, default: V) -> Self 1006336d762aSopenharmony_ci where 1007336d762aSopenharmony_ci V: Into<Cow<'a, str>>, 1008336d762aSopenharmony_ci { 1009336d762aSopenharmony_ci self.filter = Var::new_with_default(DEFAULT_FILTER_ENV, default); 1010336d762aSopenharmony_ci 1011336d762aSopenharmony_ci self 1012336d762aSopenharmony_ci } 1013336d762aSopenharmony_ci 1014336d762aSopenharmony_ci fn get_filter(&self) -> Option<String> { 1015336d762aSopenharmony_ci self.filter.get() 1016336d762aSopenharmony_ci } 1017336d762aSopenharmony_ci 1018336d762aSopenharmony_ci /// Specify an environment variable to read the style from. 1019336d762aSopenharmony_ci pub fn write_style<E>(mut self, write_style_env: E) -> Self 1020336d762aSopenharmony_ci where 1021336d762aSopenharmony_ci E: Into<Cow<'a, str>>, 1022336d762aSopenharmony_ci { 1023336d762aSopenharmony_ci self.write_style = Var::new(write_style_env); 1024336d762aSopenharmony_ci 1025336d762aSopenharmony_ci self 1026336d762aSopenharmony_ci } 1027336d762aSopenharmony_ci 1028336d762aSopenharmony_ci /// Specify an environment variable to read the style from. 1029336d762aSopenharmony_ci /// 1030336d762aSopenharmony_ci /// If the variable is not set, the default value will be used. 1031336d762aSopenharmony_ci pub fn write_style_or<E, V>(mut self, write_style_env: E, default: V) -> Self 1032336d762aSopenharmony_ci where 1033336d762aSopenharmony_ci E: Into<Cow<'a, str>>, 1034336d762aSopenharmony_ci V: Into<Cow<'a, str>>, 1035336d762aSopenharmony_ci { 1036336d762aSopenharmony_ci self.write_style = Var::new_with_default(write_style_env, default); 1037336d762aSopenharmony_ci 1038336d762aSopenharmony_ci self 1039336d762aSopenharmony_ci } 1040336d762aSopenharmony_ci 1041336d762aSopenharmony_ci /// Use the default environment variable to read the style from. 1042336d762aSopenharmony_ci /// 1043336d762aSopenharmony_ci /// If the variable is not set, the default value will be used. 1044336d762aSopenharmony_ci pub fn default_write_style_or<V>(mut self, default: V) -> Self 1045336d762aSopenharmony_ci where 1046336d762aSopenharmony_ci V: Into<Cow<'a, str>>, 1047336d762aSopenharmony_ci { 1048336d762aSopenharmony_ci self.write_style = Var::new_with_default(DEFAULT_WRITE_STYLE_ENV, default); 1049336d762aSopenharmony_ci 1050336d762aSopenharmony_ci self 1051336d762aSopenharmony_ci } 1052336d762aSopenharmony_ci 1053336d762aSopenharmony_ci fn get_write_style(&self) -> Option<String> { 1054336d762aSopenharmony_ci self.write_style.get() 1055336d762aSopenharmony_ci } 1056336d762aSopenharmony_ci} 1057336d762aSopenharmony_ci 1058336d762aSopenharmony_ciimpl<'a> Var<'a> { 1059336d762aSopenharmony_ci fn new<E>(name: E) -> Self 1060336d762aSopenharmony_ci where 1061336d762aSopenharmony_ci E: Into<Cow<'a, str>>, 1062336d762aSopenharmony_ci { 1063336d762aSopenharmony_ci Var { 1064336d762aSopenharmony_ci name: name.into(), 1065336d762aSopenharmony_ci default: None, 1066336d762aSopenharmony_ci } 1067336d762aSopenharmony_ci } 1068336d762aSopenharmony_ci 1069336d762aSopenharmony_ci fn new_with_default<E, V>(name: E, default: V) -> Self 1070336d762aSopenharmony_ci where 1071336d762aSopenharmony_ci E: Into<Cow<'a, str>>, 1072336d762aSopenharmony_ci V: Into<Cow<'a, str>>, 1073336d762aSopenharmony_ci { 1074336d762aSopenharmony_ci Var { 1075336d762aSopenharmony_ci name: name.into(), 1076336d762aSopenharmony_ci default: Some(default.into()), 1077336d762aSopenharmony_ci } 1078336d762aSopenharmony_ci } 1079336d762aSopenharmony_ci 1080336d762aSopenharmony_ci fn get(&self) -> Option<String> { 1081336d762aSopenharmony_ci env::var(&*self.name) 1082336d762aSopenharmony_ci .ok() 1083336d762aSopenharmony_ci .or_else(|| self.default.to_owned().map(|v| v.into_owned())) 1084336d762aSopenharmony_ci } 1085336d762aSopenharmony_ci} 1086336d762aSopenharmony_ci 1087336d762aSopenharmony_ciimpl<'a, T> From<T> for Env<'a> 1088336d762aSopenharmony_ciwhere 1089336d762aSopenharmony_ci T: Into<Cow<'a, str>>, 1090336d762aSopenharmony_ci{ 1091336d762aSopenharmony_ci fn from(filter_env: T) -> Self { 1092336d762aSopenharmony_ci Env::default().filter(filter_env.into()) 1093336d762aSopenharmony_ci } 1094336d762aSopenharmony_ci} 1095336d762aSopenharmony_ci 1096336d762aSopenharmony_ciimpl<'a> Default for Env<'a> { 1097336d762aSopenharmony_ci fn default() -> Self { 1098336d762aSopenharmony_ci Env { 1099336d762aSopenharmony_ci filter: Var::new(DEFAULT_FILTER_ENV), 1100336d762aSopenharmony_ci write_style: Var::new(DEFAULT_WRITE_STYLE_ENV), 1101336d762aSopenharmony_ci } 1102336d762aSopenharmony_ci } 1103336d762aSopenharmony_ci} 1104336d762aSopenharmony_ci 1105336d762aSopenharmony_cimod std_fmt_impls { 1106336d762aSopenharmony_ci use super::*; 1107336d762aSopenharmony_ci use std::fmt; 1108336d762aSopenharmony_ci 1109336d762aSopenharmony_ci impl fmt::Debug for Logger { 1110336d762aSopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1111336d762aSopenharmony_ci f.debug_struct("Logger") 1112336d762aSopenharmony_ci .field("filter", &self.filter) 1113336d762aSopenharmony_ci .finish() 1114336d762aSopenharmony_ci } 1115336d762aSopenharmony_ci } 1116336d762aSopenharmony_ci 1117336d762aSopenharmony_ci impl fmt::Debug for Builder { 1118336d762aSopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1119336d762aSopenharmony_ci if self.built { 1120336d762aSopenharmony_ci f.debug_struct("Logger").field("built", &true).finish() 1121336d762aSopenharmony_ci } else { 1122336d762aSopenharmony_ci f.debug_struct("Logger") 1123336d762aSopenharmony_ci .field("filter", &self.filter) 1124336d762aSopenharmony_ci .field("writer", &self.writer) 1125336d762aSopenharmony_ci .finish() 1126336d762aSopenharmony_ci } 1127336d762aSopenharmony_ci } 1128336d762aSopenharmony_ci } 1129336d762aSopenharmony_ci} 1130336d762aSopenharmony_ci 1131336d762aSopenharmony_ci/// Attempts to initialize the global logger with an env logger. 1132336d762aSopenharmony_ci/// 1133336d762aSopenharmony_ci/// This should be called early in the execution of a Rust program. Any log 1134336d762aSopenharmony_ci/// events that occur before initialization will be ignored. 1135336d762aSopenharmony_ci/// 1136336d762aSopenharmony_ci/// # Errors 1137336d762aSopenharmony_ci/// 1138336d762aSopenharmony_ci/// This function will fail if it is called more than once, or if another 1139336d762aSopenharmony_ci/// library has already initialized a global logger. 1140336d762aSopenharmony_cipub fn try_init() -> Result<(), SetLoggerError> { 1141336d762aSopenharmony_ci try_init_from_env(Env::default()) 1142336d762aSopenharmony_ci} 1143336d762aSopenharmony_ci 1144336d762aSopenharmony_ci/// Initializes the global logger with an env logger. 1145336d762aSopenharmony_ci/// 1146336d762aSopenharmony_ci/// This should be called early in the execution of a Rust program. Any log 1147336d762aSopenharmony_ci/// events that occur before initialization will be ignored. 1148336d762aSopenharmony_ci/// 1149336d762aSopenharmony_ci/// # Panics 1150336d762aSopenharmony_ci/// 1151336d762aSopenharmony_ci/// This function will panic if it is called more than once, or if another 1152336d762aSopenharmony_ci/// library has already initialized a global logger. 1153336d762aSopenharmony_cipub fn init() { 1154336d762aSopenharmony_ci try_init().expect("env_logger::init should not be called after logger initialized"); 1155336d762aSopenharmony_ci} 1156336d762aSopenharmony_ci 1157336d762aSopenharmony_ci/// Attempts to initialize the global logger with an env logger from the given 1158336d762aSopenharmony_ci/// environment variables. 1159336d762aSopenharmony_ci/// 1160336d762aSopenharmony_ci/// This should be called early in the execution of a Rust program. Any log 1161336d762aSopenharmony_ci/// events that occur before initialization will be ignored. 1162336d762aSopenharmony_ci/// 1163336d762aSopenharmony_ci/// # Examples 1164336d762aSopenharmony_ci/// 1165336d762aSopenharmony_ci/// Initialise a logger using the `MY_LOG` environment variable for filters 1166336d762aSopenharmony_ci/// and `MY_LOG_STYLE` for writing colors: 1167336d762aSopenharmony_ci/// 1168336d762aSopenharmony_ci/// ``` 1169336d762aSopenharmony_ci/// use env_logger::{Builder, Env}; 1170336d762aSopenharmony_ci/// 1171336d762aSopenharmony_ci/// # fn run() -> Result<(), Box<::std::error::Error>> { 1172336d762aSopenharmony_ci/// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); 1173336d762aSopenharmony_ci/// 1174336d762aSopenharmony_ci/// env_logger::try_init_from_env(env)?; 1175336d762aSopenharmony_ci/// 1176336d762aSopenharmony_ci/// Ok(()) 1177336d762aSopenharmony_ci/// # } 1178336d762aSopenharmony_ci/// # run().unwrap(); 1179336d762aSopenharmony_ci/// ``` 1180336d762aSopenharmony_ci/// 1181336d762aSopenharmony_ci/// # Errors 1182336d762aSopenharmony_ci/// 1183336d762aSopenharmony_ci/// This function will fail if it is called more than once, or if another 1184336d762aSopenharmony_ci/// library has already initialized a global logger. 1185336d762aSopenharmony_cipub fn try_init_from_env<'a, E>(env: E) -> Result<(), SetLoggerError> 1186336d762aSopenharmony_ciwhere 1187336d762aSopenharmony_ci E: Into<Env<'a>>, 1188336d762aSopenharmony_ci{ 1189336d762aSopenharmony_ci let mut builder = Builder::from_env(env); 1190336d762aSopenharmony_ci 1191336d762aSopenharmony_ci builder.try_init() 1192336d762aSopenharmony_ci} 1193336d762aSopenharmony_ci 1194336d762aSopenharmony_ci/// Initializes the global logger with an env logger from the given environment 1195336d762aSopenharmony_ci/// variables. 1196336d762aSopenharmony_ci/// 1197336d762aSopenharmony_ci/// This should be called early in the execution of a Rust program. Any log 1198336d762aSopenharmony_ci/// events that occur before initialization will be ignored. 1199336d762aSopenharmony_ci/// 1200336d762aSopenharmony_ci/// # Examples 1201336d762aSopenharmony_ci/// 1202336d762aSopenharmony_ci/// Initialise a logger using the `MY_LOG` environment variable for filters 1203336d762aSopenharmony_ci/// and `MY_LOG_STYLE` for writing colors: 1204336d762aSopenharmony_ci/// 1205336d762aSopenharmony_ci/// ``` 1206336d762aSopenharmony_ci/// use env_logger::{Builder, Env}; 1207336d762aSopenharmony_ci/// 1208336d762aSopenharmony_ci/// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); 1209336d762aSopenharmony_ci/// 1210336d762aSopenharmony_ci/// env_logger::init_from_env(env); 1211336d762aSopenharmony_ci/// ``` 1212336d762aSopenharmony_ci/// 1213336d762aSopenharmony_ci/// # Panics 1214336d762aSopenharmony_ci/// 1215336d762aSopenharmony_ci/// This function will panic if it is called more than once, or if another 1216336d762aSopenharmony_ci/// library has already initialized a global logger. 1217336d762aSopenharmony_cipub fn init_from_env<'a, E>(env: E) 1218336d762aSopenharmony_ciwhere 1219336d762aSopenharmony_ci E: Into<Env<'a>>, 1220336d762aSopenharmony_ci{ 1221336d762aSopenharmony_ci try_init_from_env(env) 1222336d762aSopenharmony_ci .expect("env_logger::init_from_env should not be called after logger initialized"); 1223336d762aSopenharmony_ci} 1224336d762aSopenharmony_ci 1225336d762aSopenharmony_ci/// Create a new builder with the default environment variables. 1226336d762aSopenharmony_ci/// 1227336d762aSopenharmony_ci/// The builder can be configured before being initialized. 1228336d762aSopenharmony_ci/// This is a convenient way of calling [`Builder::from_default_env`]. 1229336d762aSopenharmony_ci/// 1230336d762aSopenharmony_ci/// [`Builder::from_default_env`]: struct.Builder.html#method.from_default_env 1231336d762aSopenharmony_cipub fn builder() -> Builder { 1232336d762aSopenharmony_ci Builder::from_default_env() 1233336d762aSopenharmony_ci} 1234336d762aSopenharmony_ci 1235336d762aSopenharmony_ci/// Create a builder from the given environment variables. 1236336d762aSopenharmony_ci/// 1237336d762aSopenharmony_ci/// The builder can be configured before being initialized. 1238336d762aSopenharmony_ci#[deprecated( 1239336d762aSopenharmony_ci since = "0.8.0", 1240336d762aSopenharmony_ci note = "Prefer `env_logger::Builder::from_env()` instead." 1241336d762aSopenharmony_ci)] 1242336d762aSopenharmony_cipub fn from_env<'a, E>(env: E) -> Builder 1243336d762aSopenharmony_ciwhere 1244336d762aSopenharmony_ci E: Into<Env<'a>>, 1245336d762aSopenharmony_ci{ 1246336d762aSopenharmony_ci Builder::from_env(env) 1247336d762aSopenharmony_ci} 1248336d762aSopenharmony_ci 1249336d762aSopenharmony_ci#[cfg(test)] 1250336d762aSopenharmony_cimod tests { 1251336d762aSopenharmony_ci use super::*; 1252336d762aSopenharmony_ci 1253336d762aSopenharmony_ci #[test] 1254336d762aSopenharmony_ci fn env_get_filter_reads_from_var_if_set() { 1255336d762aSopenharmony_ci env::set_var("env_get_filter_reads_from_var_if_set", "from var"); 1256336d762aSopenharmony_ci 1257336d762aSopenharmony_ci let env = Env::new().filter_or("env_get_filter_reads_from_var_if_set", "from default"); 1258336d762aSopenharmony_ci 1259336d762aSopenharmony_ci assert_eq!(Some("from var".to_owned()), env.get_filter()); 1260336d762aSopenharmony_ci } 1261336d762aSopenharmony_ci 1262336d762aSopenharmony_ci #[test] 1263336d762aSopenharmony_ci fn env_get_filter_reads_from_default_if_var_not_set() { 1264336d762aSopenharmony_ci env::remove_var("env_get_filter_reads_from_default_if_var_not_set"); 1265336d762aSopenharmony_ci 1266336d762aSopenharmony_ci let env = Env::new().filter_or( 1267336d762aSopenharmony_ci "env_get_filter_reads_from_default_if_var_not_set", 1268336d762aSopenharmony_ci "from default", 1269336d762aSopenharmony_ci ); 1270336d762aSopenharmony_ci 1271336d762aSopenharmony_ci assert_eq!(Some("from default".to_owned()), env.get_filter()); 1272336d762aSopenharmony_ci } 1273336d762aSopenharmony_ci 1274336d762aSopenharmony_ci #[test] 1275336d762aSopenharmony_ci fn env_get_write_style_reads_from_var_if_set() { 1276336d762aSopenharmony_ci env::set_var("env_get_write_style_reads_from_var_if_set", "from var"); 1277336d762aSopenharmony_ci 1278336d762aSopenharmony_ci let env = 1279336d762aSopenharmony_ci Env::new().write_style_or("env_get_write_style_reads_from_var_if_set", "from default"); 1280336d762aSopenharmony_ci 1281336d762aSopenharmony_ci assert_eq!(Some("from var".to_owned()), env.get_write_style()); 1282336d762aSopenharmony_ci } 1283336d762aSopenharmony_ci 1284336d762aSopenharmony_ci #[test] 1285336d762aSopenharmony_ci fn env_get_write_style_reads_from_default_if_var_not_set() { 1286336d762aSopenharmony_ci env::remove_var("env_get_write_style_reads_from_default_if_var_not_set"); 1287336d762aSopenharmony_ci 1288336d762aSopenharmony_ci let env = Env::new().write_style_or( 1289336d762aSopenharmony_ci "env_get_write_style_reads_from_default_if_var_not_set", 1290336d762aSopenharmony_ci "from default", 1291336d762aSopenharmony_ci ); 1292336d762aSopenharmony_ci 1293336d762aSopenharmony_ci assert_eq!(Some("from default".to_owned()), env.get_write_style()); 1294336d762aSopenharmony_ci } 1295336d762aSopenharmony_ci 1296336d762aSopenharmony_ci #[test] 1297336d762aSopenharmony_ci fn builder_parse_env_overrides_existing_filters() { 1298336d762aSopenharmony_ci env::set_var( 1299336d762aSopenharmony_ci "builder_parse_default_env_overrides_existing_filters", 1300336d762aSopenharmony_ci "debug", 1301336d762aSopenharmony_ci ); 1302336d762aSopenharmony_ci let env = Env::new().filter("builder_parse_default_env_overrides_existing_filters"); 1303336d762aSopenharmony_ci 1304336d762aSopenharmony_ci let mut builder = Builder::new(); 1305336d762aSopenharmony_ci builder.filter_level(LevelFilter::Trace); 1306336d762aSopenharmony_ci // Overrides global level to debug 1307336d762aSopenharmony_ci builder.parse_env(env); 1308336d762aSopenharmony_ci 1309336d762aSopenharmony_ci assert_eq!(builder.filter.build().filter(), LevelFilter::Debug); 1310336d762aSopenharmony_ci } 1311336d762aSopenharmony_ci} 1312