From c1a66c16193dec249b26677d23d9f664ac833e40 Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sat, 5 Dec 2020 00:09:42 -0500 Subject: [PATCH 01/10] [01 of 10]: filter::parse_spec(): add more parse_spec_global* tests These test parse_spec() against strings that contain only a legit log level name. Several case variants are exercised, and confirmed to obtain the same result. --- src/filter/mod.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/filter/mod.rs b/src/filter/mod.rs index ba813028..6c77986c 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -569,6 +569,36 @@ mod tests { assert!(filter.is_none()); } + #[test] + fn parse_spec_global_bare_warn_lc() { + // test parse_spec with no crate, in isolation, all lowercase + let (dirs, filter) = parse_spec("warn"); + assert_eq!(dirs.len(), 1); + assert_eq!(dirs[0].name, None); + assert_eq!(dirs[0].level, LevelFilter::Warn); + assert!(filter.is_none()); + } + + #[test] + fn parse_spec_global_bare_warn_uc() { + // test parse_spec with no crate, in isolation, all uppercase + let (dirs, filter) = parse_spec("WARN"); + assert_eq!(dirs.len(), 1); + assert_eq!(dirs[0].name, None); + assert_eq!(dirs[0].level, LevelFilter::Warn); + assert!(filter.is_none()); + } + + #[test] + fn parse_spec_global_bare_warn_mixed() { + // test parse_spec with no crate, in isolation, mixed case + let (dirs, filter) = parse_spec("wArN"); + assert_eq!(dirs.len(), 1); + assert_eq!(dirs[0].name, None); + assert_eq!(dirs[0].level, LevelFilter::Warn); + assert!(filter.is_none()); + } + #[test] fn parse_spec_valid_filter() { let (dirs, filter) = parse_spec("crate1::mod1=error,crate1::mod2,crate2=debug/abc"); From 4395685ca1fcd0f55fe6231396960f1053eed3f6 Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sat, 5 Dec 2020 00:16:48 -0500 Subject: [PATCH 02/10] [02 of 10]: filter::parse_spec(): add more parse_default* tests Add tests that elaborate on the existing parse_default() unit test. These new tests exercise all of log::Level variants (plus the "OFF" pseudo log level), and also serve as minimal examples of how to set the default log level. For example, they exercise both lowercase and uppercase variants. There is one mixed case variant test thrown in, too, since that is specifically allowed for by the external log::Level::from_str() implementation on which we depend. There is also a test to ensure all log::Level variants are accounted for in the above tests. That one is intended to avoid the false sense of comfort from passing tests in the unlikely event that a new variant is added to the externally defined log::Level enum. (Note that this compile-time check does not include the "OFF" pseudo log level, as it exists outside of the log::Level enum.) --- src/filter/mod.rs | 180 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) diff --git a/src/filter/mod.rs b/src/filter/mod.rs index 6c77986c..d70f0173 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -395,6 +395,26 @@ mod tests { assert!(!enabled(&logger.directives, Level::Debug, "crate2")); } + // Some of our tests are only correct or complete when they cover the full + // universe of variants for log::Level. In the unlikely event that a new + // variant is added in the future, this test will detect the scenario and + // alert us to the need to review and update the tests. In such a + // situation, this test will fail to compile, and the error message will + // look something like this: + // + // error[E0004]: non-exhaustive patterns: `NewVariant` not covered + // --> src/filter/mod.rs:413:15 + // | + // 413 | match level_universe { + // | ^^^^^^^^^^^^^^ pattern `NewVariant` not covered + #[test] + fn ensure_tests_cover_level_universe() { + let level_universe: Level = Level::Trace; // use of trace variant is arbitrary + match level_universe { + Level::Error | Level::Warn | Level::Info | Level::Debug | Level::Trace => (), + } + } + #[test] fn parse_default() { let logger = Builder::new().parse("info,crate1::mod1=warn").build(); @@ -402,6 +422,166 @@ mod tests { assert!(enabled(&logger.directives, Level::Info, "crate2::mod2")); } + #[test] + fn parse_default_bare_level_off_lc() { + let logger = Builder::new().parse("off").build(); + assert!(!enabled(&logger.directives, Level::Error, "")); + assert!(!enabled(&logger.directives, Level::Warn, "")); + assert!(!enabled(&logger.directives, Level::Info, "")); + assert!(!enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_off_uc() { + let logger = Builder::new().parse("OFF").build(); + assert!(!enabled(&logger.directives, Level::Error, "")); + assert!(!enabled(&logger.directives, Level::Warn, "")); + assert!(!enabled(&logger.directives, Level::Info, "")); + assert!(!enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_error_lc() { + let logger = Builder::new().parse("error").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(!enabled(&logger.directives, Level::Warn, "")); + assert!(!enabled(&logger.directives, Level::Info, "")); + assert!(!enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_error_uc() { + let logger = Builder::new().parse("ERROR").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(!enabled(&logger.directives, Level::Warn, "")); + assert!(!enabled(&logger.directives, Level::Info, "")); + assert!(!enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_warn_lc() { + let logger = Builder::new().parse("warn").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(!enabled(&logger.directives, Level::Info, "")); + assert!(!enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_warn_uc() { + let logger = Builder::new().parse("WARN").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(!enabled(&logger.directives, Level::Info, "")); + assert!(!enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_info_lc() { + let logger = Builder::new().parse("info").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(!enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_info_uc() { + let logger = Builder::new().parse("INFO").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(!enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_debug_lc() { + let logger = Builder::new().parse("debug").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_debug_uc() { + let logger = Builder::new().parse("DEBUG").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_trace_lc() { + let logger = Builder::new().parse("trace").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(enabled(&logger.directives, Level::Debug, "")); + assert!(enabled(&logger.directives, Level::Trace, "")); + } + + #[test] + fn parse_default_bare_level_trace_uc() { + let logger = Builder::new().parse("TRACE").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(enabled(&logger.directives, Level::Debug, "")); + assert!(enabled(&logger.directives, Level::Trace, "")); + } + + // In practice, the desired log level is typically specified by a token + // that is either all lowercase (e.g., 'trace') or all uppercase (.e.g, + // 'TRACE'), but this tests serves as a reminder that + // log::Level::from_str() ignores all case variants. + #[test] + fn parse_default_bare_level_debug_mixed() { + { + let logger = Builder::new().parse("Debug").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + { + let logger = Builder::new().parse("debuG").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + { + let logger = Builder::new().parse("deBug").build(); + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + { + let logger = Builder::new().parse("DeBuG").build(); // LaTeX flavor! + assert!(enabled(&logger.directives, Level::Error, "")); + assert!(enabled(&logger.directives, Level::Warn, "")); + assert!(enabled(&logger.directives, Level::Info, "")); + assert!(enabled(&logger.directives, Level::Debug, "")); + assert!(!enabled(&logger.directives, Level::Trace, "")); + } + } + #[test] fn match_full_path() { let logger = make_logger_filter(vec![ From 80c225feb25f553433337c5af112bfdba9ab092c Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sat, 5 Dec 2020 01:54:26 -0500 Subject: [PATCH 03/10] [03 of 10]: update docs to note that level names are case insensitive The fact that user-specified logging level names are handled in a case-insensitive fashion is now noted in both the 'README.md' file and in the crate-level API docs. --- README.md | 10 ++++++++++ src/lib.rs | 6 +++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ca699f35..4327ebce 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,16 @@ $ RUST_LOG=info ./main [2018-11-03T06:09:06Z INFO default] starting up ``` +The letter case is not significant for the logging level names; e.g., `debug`, +`DEBUG`, and `dEbuG` all represent the same logging level. Therefore, the +previous example could also have been written this way, specifying the log +level as `INFO` rather than as `info`: + +```bash +$ RUST_LOG=INFO ./main +[2018-11-03T06:09:06Z INFO default] starting up +``` + `env_logger` can be configured in other ways besides an environment variable. See [the examples](https://github.com/env-logger-rs/env_logger/tree/master/examples) for more approaches. ### In tests diff --git a/src/lib.rs b/src/lib.rs index 6b38390e..83110551 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,7 +101,9 @@ //! //! The actual `level` is optional to specify. If omitted, all logging will //! be enabled. If specified, it must be one of the strings `debug`, `error`, -//! `info`, `warn`, or `trace`. +//! `info`, `warn`, or `trace`. The letter case is not significant for the +//! logging level names; e.g., `debug`, `DEBUG`, and `dEbuG` all represent the +//! same logging level. //! //! As the log level for a module is optional, the module to enable logging for //! is also optional. If only a `level` is provided, then the global log @@ -111,7 +113,9 @@ //! //! * `hello` turns on all logging for the 'hello' module //! * `info` turns on all info logging +//! * `INFO` turns on all info logging (same as previous) //! * `hello=debug` turns on debug logging for 'hello' +//! * `hello=DEBUG` turns on debug logging for 'hello' (same as previous) //! * `hello,std::option` turns on hello, and std's option logging //! * `error,hello=warn` turn on global error logging and also warn for hello //! From 0adfb6f32901779a63a7ca3ed7ee60f4f383d004 Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sat, 5 Dec 2020 01:59:26 -0500 Subject: [PATCH 04/10] [04 of 10]: markdown now shows 'RUST_LOG' in bold (first mention only) The first mention of the 'RUST_LOG' environment variable in the prose in both the 'README.md' file and in the crate-level API docs now uses bold text markdown. This is intended to draw attention to it for both first time readers and for those skimming the docs quickly. --- README.md | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4327ebce..eefe7614 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ fn main() { } ``` -Then when running the executable, specify a value for the `RUST_LOG` +Then when running the executable, specify a value for the **`RUST_LOG`** environment variable that corresponds with the log messages you want to show. ```bash diff --git a/src/lib.rs b/src/lib.rs index 83110551..90cca7fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,7 +84,7 @@ //! ## Enabling logging //! //! Log levels are controlled on a per-module basis, and by default all logging -//! is disabled except for `error!`. Logging is controlled via the `RUST_LOG` +//! is disabled except for `error!`. Logging is controlled via the **`RUST_LOG`** //! environment variable. The value of this environment variable is a //! comma-separated list of logging directives. A logging directive is of the //! form: From 809b117ad77a01d1f60408a1b03e4db3a86b8777 Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sat, 5 Dec 2020 02:38:02 -0500 Subject: [PATCH 05/10] [05 of 10]: update crate-level docs to note non-env-var configuration For symmetry with the 'README.md' file, the crate-level API docs now note that 'env_logger' can be configured by means other than via environment variables, and (like README.md) directs the user to the examples in the GitHub repo. This is useful information for somebody first discovering the 'env_logger' crate on crates.io; it provides a more comprehensive picture of how the crate is intended to be used. --- src/lib.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 90cca7fa..18eb2b89 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,9 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! A simple logger configured via environment variables which writes -//! to stdout or stderr, for use with the logging facade exposed by the -//! [`log` crate][log-crate-url]. +//! A simple logger that can be configured via environment variables, for use +//! with the logging facade exposed by the [`log` crate][log-crate-url]. +//! +//! Despite having "env" in its name, **`env_logger`** can also be configured by +//! other means besides environment variables. See [the examples][gh-repo-examples] +//! in the source repository for more approaches. +//! +//! By default, `env_logger` writes logs to `stderr`, but can be configured to +//! instead write them to `stdout`. //! //! ## Example //! @@ -227,6 +233,7 @@ //! env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(); //! ``` //! +//! [gh-repo-examples]: https://github.com/env-logger-rs/env_logger/tree/master/examples //! [log-crate-url]: https://docs.rs/log/ //! [`Builder`]: struct.Builder.html //! [`Builder::is_test`]: struct.Builder.html#method.is_test From d1a4dad0ef2978a5987ebe5f9cb72ea5a75c489e Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sat, 5 Dec 2020 03:37:34 -0500 Subject: [PATCH 06/10] [06 of 10]: docs: clarify default enabled/disabled log level behavior The "Enabling logging" section of the crate-level docs are here updated to clarify the default behavior as it pertains to the logging level. Previously, the first paragraph stated that all logging is disabled except for the default level, but the third paragraph stated that if no log level was specified then /all/ logging was enabled. It turns out that the third paragraph was really intended as a continuation of the second paragraph, the applicable context of which is limited to those scenarios in which a logging directive has been supplied. This changeset reworks the paragraph structure slightly to make the intent more clear, and also to make it easy to quickly identify the most important aspects: A. Old para 1 split into two separate paras: - first states clearly the default behavior (now in bold) - second introduces 'RUST_LOG' and logging directives B. Old para 3 split into two separate paras: - first now qualifies the statement with "When specifying the crate name or a module path..." - second introduces log level names C. The existing statement that describes the behavior when only a log level is provided (it sets the global log level) is now in bold markdown. It might make sense to refine this further at some point so that the flow of the text answers in order the user's questions: 1. "What is the default behavior?" (Already first; good.) 2. "How do I set the log level for the entire app?" 3. "How do I set the log level more surgically?" Our current flow is: (1), (3), (2) --- src/lib.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 18eb2b89..aadc7d4e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,11 +89,12 @@ //! //! ## Enabling logging //! -//! Log levels are controlled on a per-module basis, and by default all logging -//! is disabled except for `error!`. Logging is controlled via the **`RUST_LOG`** -//! environment variable. The value of this environment variable is a -//! comma-separated list of logging directives. A logging directive is of the -//! form: +//! Log levels are controlled on a per-module basis, and **by default all +//! logging is disabled except for the `error` level**. +//! +//! Logging is controlled via the **`RUST_LOG`** environment variable. The +//! value of this environment variable is a comma-separated list of logging +//! directives. A logging directive is of the form: //! //! ```text //! path::to::module=level @@ -105,15 +106,18 @@ //! Furthermore, this path is a prefix-search, so all modules nested in the //! specified module will also have logging enabled. //! -//! The actual `level` is optional to specify. If omitted, all logging will -//! be enabled. If specified, it must be one of the strings `debug`, `error`, -//! `info`, `warn`, or `trace`. The letter case is not significant for the -//! logging level names; e.g., `debug`, `DEBUG`, and `dEbuG` all represent the -//! same logging level. +//! When providing the crate name or a module path, explicitly specifying the +//! log level is optional. If omitted, all logging for the item (and its +//! children) will be enabled. +//! +//! When specifying a logging level, the name provided must be one of the +//! strings `debug`, `error`, `info`, `warn`, or `trace`. The letter case is +//! not significant for the logging level names; e.g., `debug`, `DEBUG`, and +//! `dEbuG` all represent the same logging level. //! //! As the log level for a module is optional, the module to enable logging for -//! is also optional. If only a `level` is provided, then the global log -//! level for all modules is set to this value. +//! is also optional. **If only a level is provided, then the global log +//! level for all modules is set to this value.** //! //! Some examples of valid values of `RUST_LOG` are: //! From df7bd104d0d2c69e7677f9c9d1b1b32ef1965f04 Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sat, 5 Dec 2020 04:39:05 -0500 Subject: [PATCH 07/10] [07 of 10]: docs: show log levels in bulleted list The 'README.md' and crate-level API docs are both updated to show the available logging levels in a bulleted list (rather then a comma-separated list in the prose), and to note that they correspond to the externally defined log::Level enum in the 'log' crate. For the README.md file, this is an addition. The universe of valid log levels was not previously listed there. The order of the log levels is also now sorted in the list highest precedence to lowest: error, warn, info, debug, trace The previous order in which they were presented was: debug, error, info, warn, trace --- README.md | 11 +++++++++++ src/lib.rs | 17 +++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index eefe7614..77b8fc57 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,17 @@ $ RUST_LOG=INFO ./main [2018-11-03T06:09:06Z INFO default] starting up ``` +The log levels that may be specified correspond to the [`log::Level`][level-enum] +enum from the `log` crate. They are: + + * `error` + * `warn` + * `info` + * `debug` + * `trace` + +[level-enum]: https://docs.rs/log/latest/log/enum.Level.html "log::Level (docs.rs)" + `env_logger` can be configured in other ways besides an environment variable. See [the examples](https://github.com/env-logger-rs/env_logger/tree/master/examples) for more approaches. ### In tests diff --git a/src/lib.rs b/src/lib.rs index aadc7d4e..6439cde7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -110,10 +110,18 @@ //! log level is optional. If omitted, all logging for the item (and its //! children) will be enabled. //! -//! When specifying a logging level, the name provided must be one of the -//! strings `debug`, `error`, `info`, `warn`, or `trace`. The letter case is -//! not significant for the logging level names; e.g., `debug`, `DEBUG`, and -//! `dEbuG` all represent the same logging level. +//! The names of the log levels that may be specified correspond to the +//! variations of the [`log::Level`][level-enum] enum from the `log` +//! crate. They are: +//! +//! * `error` +//! * `warn` +//! * `info` +//! * `debug` +//! * `trace` +//! +//! The letter case is not significant for the logging level names; e.g., +//! `debug`, `DEBUG`, and `dEbuG` all represent the same logging level. //! //! As the log level for a module is optional, the module to enable logging for //! is also optional. **If only a level is provided, then the global log @@ -238,6 +246,7 @@ //! ``` //! //! [gh-repo-examples]: https://github.com/env-logger-rs/env_logger/tree/master/examples +//! [level-enum]: https://docs.rs/log/latest/log/enum.Level.html //! [log-crate-url]: https://docs.rs/log/ //! [`Builder`]: struct.Builder.html //! [`Builder::is_test`]: struct.Builder.html#method.is_test From 484ca2b2f5e0689822cb173108476dd1871cfa86 Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sat, 5 Dec 2020 05:08:56 -0500 Subject: [PATCH 08/10] [08 of 10]: document 'OFF' pseudo log level feature --- README.md | 4 ++++ src/lib.rs | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/README.md b/README.md index 77b8fc57..82547f09 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,10 @@ enum from the `log` crate. They are: [level-enum]: https://docs.rs/log/latest/log/enum.Level.html "log::Level (docs.rs)" +There is also a pseudo logging level, `off`, which may be specified to disable +all logging for a given module or for the entire application. As with the +logging levels, the letter case is not significant. + `env_logger` can be configured in other ways besides an environment variable. See [the examples](https://github.com/env-logger-rs/env_logger/tree/master/examples) for more approaches. ### In tests diff --git a/src/lib.rs b/src/lib.rs index 6439cde7..9a30d695 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -123,6 +123,13 @@ //! The letter case is not significant for the logging level names; e.g., //! `debug`, `DEBUG`, and `dEbuG` all represent the same logging level. //! +//! There is also a pseudo logging level, `off`, which may be specified to +//! disable all logging for a given module or for the entire application. As +//! with the logging levels, the letter case is not significant[^fn-off]. +//! +//! [^fn-off]: Similar to the universe of log level names, the `off` pseudo +//! log level feature is also provided by the underlying `log` crate. +//! //! As the log level for a module is optional, the module to enable logging for //! is also optional. **If only a level is provided, then the global log //! level for all modules is set to this value.** @@ -130,12 +137,16 @@ //! Some examples of valid values of `RUST_LOG` are: //! //! * `hello` turns on all logging for the 'hello' module +//! * `trace` turns on all logging for the application, regardless of its name +//! * `TRACE` turns on all logging for the application, regardless of its name (same as previous) //! * `info` turns on all info logging //! * `INFO` turns on all info logging (same as previous) //! * `hello=debug` turns on debug logging for 'hello' //! * `hello=DEBUG` turns on debug logging for 'hello' (same as previous) //! * `hello,std::option` turns on hello, and std's option logging //! * `error,hello=warn` turn on global error logging and also warn for hello +//! * `error,hello=off`` turn on global error logging, but turn off logging for hello +//! * `OFF` turns off all logging for the application //! //! ## Filtering results //! From b844d58d70122d01446e29218649e01362c351ed Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sat, 5 Dec 2020 05:40:05 -0500 Subject: [PATCH 09/10] [09 of 10]: docs: term "logging directives" emphasized (first mention) Add markdown to emphasize (typical rendering would be italics) the term "logging directive" upon the first mention in the text. --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9a30d695..d36642dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,8 +93,8 @@ //! logging is disabled except for the `error` level**. //! //! Logging is controlled via the **`RUST_LOG`** environment variable. The -//! value of this environment variable is a comma-separated list of logging -//! directives. A logging directive is of the form: +//! value of this environment variable is a comma-separated list of *logging +//! directives*. A logging directive is of the form: //! //! ```text //! path::to::module=level From 5595a4d215cf614d98af47c76ed7bb1442fc342f Mon Sep 17 00:00:00 2001 From: "Alan D. Salewski" Date: Sun, 6 Dec 2020 18:14:37 -0500 Subject: [PATCH 10/10] [10 of 10]: docs: explain use of lower case log level names Since our convention throughout the docs is to use the lower case form of log level names (e.g., "info" rather than "INFO"), users might mistakenly infer that we are implying that only the lower case forms are legit. Careful readers might even suspect that the handful of departures are typos rather than deliberate examples. This change adds a blurblet to the README.md and to the top-level API docs explaining the convention and the motivation for using it (consistency). --- README.md | 5 +++++ src/lib.rs | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 82547f09..bc54171d 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,11 @@ $ RUST_LOG=INFO ./main [2018-11-03T06:09:06Z INFO default] starting up ``` +So which form should you use? For consistency, our convention is to use lower +case names. Where our docs do use other forms, they do so in the context of +specific examples, so you won't be surprised if you see similar usage in the +wild. + The log levels that may be specified correspond to the [`log::Level`][level-enum] enum from the `log` crate. They are: diff --git a/src/lib.rs b/src/lib.rs index d36642dc..284be258 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -120,9 +120,6 @@ //! * `debug` //! * `trace` //! -//! The letter case is not significant for the logging level names; e.g., -//! `debug`, `DEBUG`, and `dEbuG` all represent the same logging level. -//! //! There is also a pseudo logging level, `off`, which may be specified to //! disable all logging for a given module or for the entire application. As //! with the logging levels, the letter case is not significant[^fn-off]. @@ -130,6 +127,12 @@ //! [^fn-off]: Similar to the universe of log level names, the `off` pseudo //! log level feature is also provided by the underlying `log` crate. //! +//! The letter case is not significant for the logging level names; e.g., +//! `debug`, `DEBUG`, and `dEbuG` all represent the same logging level. For +//! consistency, our convention is to use the lower case names. Where our docs +//! do use other forms, they do so in the context of specific examples, so you +//! won't be surprised if you see similar usage in the wild. +//! //! As the log level for a module is optional, the module to enable logging for //! is also optional. **If only a level is provided, then the global log //! level for all modules is set to this value.** @@ -146,7 +149,8 @@ //! * `hello,std::option` turns on hello, and std's option logging //! * `error,hello=warn` turn on global error logging and also warn for hello //! * `error,hello=off`` turn on global error logging, but turn off logging for hello -//! * `OFF` turns off all logging for the application +//! * `off` turns off all logging for the application +//! * `OFF` turns off all logging for the application (same as previous) //! //! ## Filtering results //!