From 26b40be7ed751e90be39c328904db2e28b10e23b Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Fri, 29 Aug 2014 12:00:39 +0200 Subject: [PATCH] doc: Runnable examples logging. Also use //! Instead of /*! in liblog. --- src/liblog/lib.rs | 262 ++++++++++++++++++++++++------------------- src/liblog/macros.rs | 115 ++++++++++++++----- 2 files changed, 236 insertions(+), 141 deletions(-) diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 0bad742933b..32222fb16ce 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -8,120 +8,154 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - -Utilities for program-wide and customizable logging - -## Example - -``` -#![feature(phase)] -#[phase(plugin, link)] extern crate log; - -fn main() { - debug!("this is a debug {}", "message"); - error!("this is printed by default"); - - if log_enabled!(log::INFO) { - let x = 3i * 4i; // expensive computation - info!("the answer was: {}", x); - } -} -``` - -## Logging Macros - -There are five macros that the logging subsystem uses: - -* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any - related `format!` arguments -* `debug!(...)` - a macro hard-wired to the log level of `DEBUG` -* `info!(...)` - a macro hard-wired to the log level of `INFO` -* `warn!(...)` - a macro hard-wired to the log level of `WARN` -* `error!(...)` - a macro hard-wired to the log level of `ERROR` - -All of these macros use the same style of syntax as the `format!` syntax -extension. Details about the syntax can be found in the documentation of -`std::fmt` along with the Rust tutorial/manual. - -If you want to check at runtime if a given logging level is enabled (e.g. if the -information you would want to log is expensive to produce), you can use the -following macro: - -* `log_enabled!(level)` - returns true if logging of the given level is enabled - -## Enabling logging - -Log levels are controlled on a per-module basis, and by default all logging is -disabled except for `error!` (a log level of 1). 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=log_level -``` - -The path to the module is rooted in the name of the crate it was compiled for, -so if your program is contained in a file `hello.rs`, for example, to turn on -logging for this file you would use a value of `RUST_LOG=hello`. -Furthermore, this path is a prefix-search, so all modules nested in the -specified module will also have logging enabled. - -The actual `log_level` is optional to specify. If omitted, all logging will be -enabled. If specified, the it must be either a numeric in the range of 1-255, or -it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric -is specified, then all logging less than or equal to that numeral is enabled. -For example, if logging level 3 is active, error, warn, and info logs will be -printed, but debug will be omitted. - -As the log level for a module is optional, the module to enable logging for is -also optional. If only a `log_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: - -* `hello` turns on all logging for the 'hello' module -* `info` turns on all info logging -* `hello=debug` turns on debug logging for 'hello' -* `hello=3` turns on info logging for 'hello' -* `hello,std::option` turns on hello, and std's option logging -* `error,hello=warn` turn on global error logging and also warn for hello - -## Filtering results - -A RUST_LOG directive may include a regex filter. The syntax is to append `/` -followed by a regex. Each message is checked against the regex, and is only -logged if it matches. Note that the matching is done after formatting the log -string but before adding any logging meta-data. There is a single filter for all -modules. - -Some examples: - -* `hello/foo` turns on all logging for the 'hello' module where the log message -includes 'foo'. -* `info/f.o` turns on all info logging where the log message includes 'foo', -'f1o', 'fao', etc. -* `hello=debug/foo*foo` turns on debug logging for 'hello' where the the log -message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc. -* `error,hello=warn/[0-9] scopes` turn on global error logging and also warn for - hello. In both cases the log message must include a single digit number - followed by 'scopes' - -## Performance and Side Effects - -Each of these macros will expand to code similar to: - -```rust,ignore -if log_level <= my_module_log_level() { - ::log::log(log_level, format!(...)); -} -``` - -What this means is that each of these macros are very cheap at runtime if -they're turned off (just a load and an integer comparison). This also means that -if logging is disabled, none of the components of the log will be executed. - -*/ +//! Utilities for program-wide and customizable logging +//! +//! ## Example +//! +//! ``` +//! #![feature(phase)] +//! #[phase(plugin, link)] extern crate log; +//! +//! fn main() { +//! debug!("this is a debug {}", "message"); +//! error!("this is printed by default"); +//! +//! if log_enabled!(log::INFO) { +//! let x = 3i * 4i; // expensive computation +//! info!("the answer was: {}", x); +//! } +//! } +//! ``` +//! +//! Assumes the binary is `main`: +//! +//! ```{.bash} +//! $ RUST_LOG=error ./main +//! ERROR:main: this is printed by default +//! ``` +//! +//! ```{.bash} +//! $ RUST_LOG=info ./main +//! ERROR:main: this is printed by default +//! INFO:main: the answer was: 12 +//! ``` +//! +//! ```{.bash} +//! $ RUST_LOG=debug ./main +//! DEBUG:main: this is a debug message +//! ERROR:main: this is printed by default +//! INFO:main: the answer was: 12 +//! ``` +//! +//! You can also set the log level on a per module basis: +//! +//! ```{.bash} +//! $ RUST_LOG=main=info ./main +//! ERROR:main: this is printed by default +//! INFO:main: the answer was: 12 +//! ``` +//! +//! And enable all logging: +//! +//! ```{.bash} +//! $ RUST_LOG=main ./main +//! DEBUG:main: this is a debug message +//! ERROR:main: this is printed by default +//! INFO:main: the answer was: 12 +//! ``` +//! +//! +//! ## Logging Macros +//! +//! There are five macros that the logging subsystem uses: +//! +//! * `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any +//! related `format!` arguments +//! * `debug!(...)` - a macro hard-wired to the log level of `DEBUG` +//! * `info!(...)` - a macro hard-wired to the log level of `INFO` +//! * `warn!(...)` - a macro hard-wired to the log level of `WARN` +//! * `error!(...)` - a macro hard-wired to the log level of `ERROR` +//! +//! All of these macros use the same style of syntax as the `format!` syntax +//! extension. Details about the syntax can be found in the documentation of +//! `std::fmt` along with the Rust tutorial/manual. +//! +//! If you want to check at runtime if a given logging level is enabled (e.g. if the +//! information you would want to log is expensive to produce), you can use the +//! following macro: +//! +//! * `log_enabled!(level)` - returns true if logging of the given level is enabled +//! +//! ## Enabling logging +//! +//! Log levels are controlled on a per-module basis, and by default all logging is +//! disabled except for `error!` (a log level of 1). 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=log_level +//! ``` +//! +//! The path to the module is rooted in the name of the crate it was compiled for, +//! so if your program is contained in a file `hello.rs`, for example, to turn on +//! logging for this file you would use a value of `RUST_LOG=hello`. +//! Furthermore, this path is a prefix-search, so all modules nested in the +//! specified module will also have logging enabled. +//! +//! The actual `log_level` is optional to specify. If omitted, all logging will be +//! enabled. If specified, the it must be either a numeric in the range of 1-255, or +//! it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric +//! is specified, then all logging less than or equal to that numeral is enabled. +//! For example, if logging level 3 is active, error, warn, and info logs will be +//! printed, but debug will be omitted. +//! +//! As the log level for a module is optional, the module to enable logging for is +//! also optional. If only a `log_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: +//! +//! * `hello` turns on all logging for the 'hello' module +//! * `info` turns on all info logging +//! * `hello=debug` turns on debug logging for 'hello' +//! * `hello=3` turns on info logging for 'hello' +//! * `hello,std::option` turns on hello, and std's option logging +//! * `error,hello=warn` turn on global error logging and also warn for hello +//! +//! ## Filtering results +//! +//! A RUST_LOG directive may include a regex filter. The syntax is to append `/` +//! followed by a regex. Each message is checked against the regex, and is only +//! logged if it matches. Note that the matching is done after formatting the log +//! string but before adding any logging meta-data. There is a single filter for all +//! modules. +//! +//! Some examples: +//! +//! * `hello/foo` turns on all logging for the 'hello' module where the log message +//! includes 'foo'. +//! * `info/f.o` turns on all info logging where the log message includes 'foo', +//! 'f1o', 'fao', etc. +//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the the log +//! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc. +//! * `error,hello=warn/[0-9] scopes` turn on global error logging and also warn for +//! hello. In both cases the log message must include a single digit number +//! followed by 'scopes' +//! +//! ## Performance and Side Effects +//! +//! Each of these macros will expand to code similar to: +//! +//! ```rust,ignore +//! if log_level <= my_module_log_level() { +//! ::log::log(log_level, format!(...)); +//! } +//! ``` +//! +//! What this means is that each of these macros are very cheap at runtime if +//! they're turned off (just a load and an integer comparison). This also means that +//! if logging is disabled, none of the components of the log will be executed. #![crate_name = "log"] #![experimental] diff --git a/src/liblog/macros.rs b/src/liblog/macros.rs index fe74b7d67ff..4f8837083ae 100644 --- a/src/liblog/macros.rs +++ b/src/liblog/macros.rs @@ -24,11 +24,31 @@ /// #![feature(phase)] /// #[phase(plugin, link)] extern crate log; /// -/// # fn main() { -/// log!(log::DEBUG, "this is a debug message"); -/// log!(log::WARN, "this is a warning {}", "message"); -/// log!(6, "this is a custom logging level: {level}", level=6u); -/// # } +/// fn main() { +/// log!(log::WARN, "this is a warning {}", "message"); +/// log!(log::DEBUG, "this is a debug message"); +/// log!(6, "this is a custom logging level: {level}", level=6u); +/// } +/// ``` +/// +/// Assumes the binary is `main`: +/// +/// ```{.bash} +/// $ RUST_LOG=warn ./main +/// WARN:main: this is a warning message +/// ``` +/// +/// ```{.bash} +/// $ RUST_LOG=debug ./main +/// DEBUG:main: this is a debug message +/// WARN:main: this is a warning message +/// ``` +/// +/// ```{.bash} +/// $ RUST_LOG=6 ./main +/// DEBUG:main: this is a debug message +/// WARN:main: this is a warning message +/// 6:main: this is a custom logging level: 6 /// ``` #[macro_export] macro_rules! log( @@ -53,11 +73,19 @@ macro_rules! log( /// #![feature(phase)] /// #[phase(plugin, link)] extern crate log; /// -/// # fn main() { -/// # let error = 3u; -/// error!("the build has failed with error code: {}", error); -/// # } +/// fn main() { +/// let error = 3u; +/// error!("the build has failed with error code: {}", error); +/// } /// ``` +/// +/// Assumes the binary is `main`: +/// +/// ```{.bash} +/// $ RUST_LOG=error ./main +/// ERROR:main: the build has failed with error code: 3 +/// ``` +/// #[macro_export] macro_rules! error( ($($arg:tt)*) => (log!(::log::ERROR, $($arg)*)) @@ -71,10 +99,17 @@ macro_rules! error( /// #![feature(phase)] /// #[phase(plugin, link)] extern crate log; /// -/// # fn main() { -/// # let code = 3u; -/// warn!("you may like to know that a process exited with: {}", code); -/// # } +/// fn main() { +/// let code = 3u; +/// warn!("you may like to know that a process exited with: {}", code); +/// } +/// ``` +/// +/// Assumes the binary is `main`: +/// +/// ```{.bash} +/// $ RUST_LOG=warn ./main +/// WARN:main: you may like to know that a process exited with: 3 /// ``` #[macro_export] macro_rules! warn( @@ -89,10 +124,17 @@ macro_rules! warn( /// #![feature(phase)] /// #[phase(plugin, link)] extern crate log; /// -/// # fn main() { -/// # let ret = 3i; -/// info!("this function is about to return: {}", ret); -/// # } +/// fn main() { +/// let ret = 3i; +/// info!("this function is about to return: {}", ret); +/// } +/// ``` +/// +/// Assumes the binary is `main`: +/// +/// ```{.bash} +/// $ RUST_LOG=info ./main +/// INFO:main: this function is about to return: 3 /// ``` #[macro_export] macro_rules! info( @@ -109,9 +151,16 @@ macro_rules! info( /// #![feature(phase)] /// #[phase(plugin, link)] extern crate log; /// -/// # fn main() { -/// debug!("x = {x}, y = {y}", x=10i, y=20i); -/// # } +/// fn main() { +/// debug!("x = {x}, y = {y}", x=10i, y=20i); +/// } +/// ``` +/// +/// Assumes the binary is `main`: +/// +/// ```{.bash} +/// $ RUST_LOG=debug ./main +/// DEBUG:main: x = 10, y = 20 /// ``` #[macro_export] macro_rules! debug( @@ -126,14 +175,26 @@ macro_rules! debug( /// #![feature(phase)] /// #[phase(plugin, link)] extern crate log; /// -/// # fn main() { -/// # struct Point { x: int, y: int } -/// # fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } } -/// if log_enabled!(log::DEBUG) { -/// let x = some_expensive_computation(); -/// debug!("x.x = {}, x.y = {}", x.x, x.y); +/// struct Point { x: int, y: int } +/// fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } } +/// +/// fn main() { +/// if log_enabled!(log::DEBUG) { +/// let x = some_expensive_computation(); +/// debug!("x.x = {}, x.y = {}", x.x, x.y); +/// } /// } -/// # } +/// ``` +/// +/// Assumes the binary is `main`: +/// +/// ```{.bash} +/// $ RUST_LOG=error ./main +/// ``` +/// +/// ```{.bash} +/// $ RUST_LOG=debug ./main +/// DEBUG:main: x.x = 1, x.y = 2 /// ``` #[macro_export] macro_rules! log_enabled(