rollup merge of #16846 : treeman/debug-doc

This commit is contained in:
Alex Crichton 2014-08-30 23:47:53 -07:00
commit daefa70f99
2 changed files with 236 additions and 141 deletions

View File

@ -8,120 +8,154 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
/*! //! Utilities for program-wide and customizable logging
//!
Utilities for program-wide and customizable logging //! ## Example
//!
## Example //! ```
//! #![feature(phase)]
``` //! #[phase(plugin, link)] extern crate log;
#![feature(phase)] //!
#[phase(plugin, link)] extern crate log; //! fn main() {
//! debug!("this is a debug {}", "message");
fn main() { //! error!("this is printed by default");
debug!("this is a debug {}", "message"); //!
error!("this is printed by default"); //! if log_enabled!(log::INFO) {
//! let x = 3i * 4i; // expensive computation
if log_enabled!(log::INFO) { //! info!("the answer was: {}", x);
let x = 3i * 4i; // expensive computation //! }
info!("the answer was: {}", x); //! }
} //! ```
} //!
``` //! Assumes the binary is `main`:
//!
## Logging Macros //! ```{.bash}
//! $ RUST_LOG=error ./main
There are five macros that the logging subsystem uses: //! ERROR:main: this is printed by default
//! ```
* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any //!
related `format!` arguments //! ```{.bash}
* `debug!(...)` - a macro hard-wired to the log level of `DEBUG` //! $ RUST_LOG=info ./main
* `info!(...)` - a macro hard-wired to the log level of `INFO` //! ERROR:main: this is printed by default
* `warn!(...)` - a macro hard-wired to the log level of `WARN` //! INFO:main: the answer was: 12
* `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 //! ```{.bash}
extension. Details about the syntax can be found in the documentation of //! $ RUST_LOG=debug ./main
`std::fmt` along with the Rust tutorial/manual. //! DEBUG:main: this is a debug message
//! ERROR:main: this is printed by default
If you want to check at runtime if a given logging level is enabled (e.g. if the //! INFO:main: the answer was: 12
information you would want to log is expensive to produce), you can use the //! ```
following macro: //!
//! You can also set the log level on a per module basis:
* `log_enabled!(level)` - returns true if logging of the given level is enabled //!
//! ```{.bash}
## Enabling logging //! $ RUST_LOG=main=info ./main
//! ERROR:main: this is printed by default
Log levels are controlled on a per-module basis, and by default all logging is //! INFO:main: the answer was: 12
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: //! And enable all logging:
//!
```text //! ```{.bash}
path::to::module=log_level //! $ RUST_LOG=main ./main
``` //! DEBUG:main: this is a debug message
//! ERROR:main: this is printed by default
The path to the module is rooted in the name of the crate it was compiled for, //! INFO:main: the answer was: 12
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. //! ## Logging Macros
//!
The actual `log_level` is optional to specify. If omitted, all logging will be //! There are five macros that the logging subsystem uses:
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 //! * `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
is specified, then all logging less than or equal to that numeral is enabled. //! related `format!` arguments
For example, if logging level 3 is active, error, warn, and info logs will be //! * `debug!(...)` - a macro hard-wired to the log level of `DEBUG`
printed, but debug will be omitted. //! * `info!(...)` - a macro hard-wired to the log level of `INFO`
//! * `warn!(...)` - a macro hard-wired to the log level of `WARN`
As the log level for a module is optional, the module to enable logging for is //! * `error!(...)` - a macro hard-wired to the log level of `ERROR`
also optional. If only a `log_level` is provided, then the global log level for //!
all modules is set to this value. //! 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
Some examples of valid values of `RUST_LOG` are: //! `std::fmt` along with the Rust tutorial/manual.
//!
* `hello` turns on all logging for the 'hello' module //! If you want to check at runtime if a given logging level is enabled (e.g. if the
* `info` turns on all info logging //! information you would want to log is expensive to produce), you can use the
* `hello=debug` turns on debug logging for 'hello' //! following macro:
* `hello=3` turns on info logging for 'hello' //!
* `hello,std::option` turns on hello, and std's option logging //! * `log_enabled!(level)` - returns true if logging of the given level is enabled
* `error,hello=warn` turn on global error logging and also warn for hello //!
//! ## Enabling logging
## Filtering results //!
//! Log levels are controlled on a per-module basis, and by default all logging is
A RUST_LOG directive may include a regex filter. The syntax is to append `/` //! disabled except for `error!` (a log level of 1). Logging is controlled via the
followed by a regex. Each message is checked against the regex, and is only //! `RUST_LOG` environment variable. The value of this environment variable is a
logged if it matches. Note that the matching is done after formatting the log //! comma-separated list of logging directives. A logging directive is of the form:
string but before adding any logging meta-data. There is a single filter for all //!
modules. //! ```text
//! path::to::module=log_level
Some examples: //! ```
//!
* `hello/foo` turns on all logging for the 'hello' module where the log message //! The path to the module is rooted in the name of the crate it was compiled for,
includes 'foo'. //! so if your program is contained in a file `hello.rs`, for example, to turn on
* `info/f.o` turns on all info logging where the log message includes 'foo', //! logging for this file you would use a value of `RUST_LOG=hello`.
'f1o', 'fao', etc. //! Furthermore, this path is a prefix-search, so all modules nested in the
* `hello=debug/foo*foo` turns on debug logging for 'hello' where the the log //! specified module will also have logging enabled.
message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc. //!
* `error,hello=warn/[0-9] scopes` turn on global error logging and also warn for //! The actual `log_level` is optional to specify. If omitted, all logging will be
hello. In both cases the log message must include a single digit number //! enabled. If specified, the it must be either a numeric in the range of 1-255, or
followed by 'scopes' //! 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.
## Performance and Side Effects //! For example, if logging level 3 is active, error, warn, and info logs will be
//! printed, but debug will be omitted.
Each of these macros will expand to code similar to: //!
//! As the log level for a module is optional, the module to enable logging for is
```rust,ignore //! also optional. If only a `log_level` is provided, then the global log level for
if log_level <= my_module_log_level() { //! all modules is set to this value.
::log::log(log_level, format!(...)); //!
} //! Some examples of valid values of `RUST_LOG` are:
``` //!
//! * `hello` turns on all logging for the 'hello' module
What this means is that each of these macros are very cheap at runtime if //! * `info` turns on all info logging
they're turned off (just a load and an integer comparison). This also means that //! * `hello=debug` turns on debug logging for 'hello'
if logging is disabled, none of the components of the log will be executed. //! * `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"] #![crate_name = "log"]
#![experimental] #![experimental]

View File

@ -24,11 +24,31 @@
/// #![feature(phase)] /// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log; /// #[phase(plugin, link)] extern crate log;
/// ///
/// # fn main() { /// fn main() {
/// log!(log::DEBUG, "this is a debug message"); /// log!(log::WARN, "this is a warning {}", "message");
/// 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); /// 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_export]
macro_rules! log( macro_rules! log(
@ -53,11 +73,19 @@ macro_rules! log(
/// #![feature(phase)] /// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log; /// #[phase(plugin, link)] extern crate log;
/// ///
/// # fn main() { /// fn main() {
/// # let error = 3u; /// let error = 3u;
/// error!("the build has failed with error code: {}", error); /// 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_export]
macro_rules! error( macro_rules! error(
($($arg:tt)*) => (log!(::log::ERROR, $($arg)*)) ($($arg:tt)*) => (log!(::log::ERROR, $($arg)*))
@ -71,10 +99,17 @@ macro_rules! error(
/// #![feature(phase)] /// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log; /// #[phase(plugin, link)] extern crate log;
/// ///
/// # fn main() { /// fn main() {
/// # let code = 3u; /// let code = 3u;
/// warn!("you may like to know that a process exited with: {}", code); /// 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_export]
macro_rules! warn( macro_rules! warn(
@ -89,10 +124,17 @@ macro_rules! warn(
/// #![feature(phase)] /// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log; /// #[phase(plugin, link)] extern crate log;
/// ///
/// # fn main() { /// fn main() {
/// # let ret = 3i; /// let ret = 3i;
/// info!("this function is about to return: {}", ret); /// 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_export]
macro_rules! info( macro_rules! info(
@ -109,9 +151,16 @@ macro_rules! info(
/// #![feature(phase)] /// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log; /// #[phase(plugin, link)] extern crate log;
/// ///
/// # fn main() { /// fn main() {
/// debug!("x = {x}, y = {y}", x=10i, y=20i); /// 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_export]
macro_rules! debug( macro_rules! debug(
@ -126,14 +175,26 @@ macro_rules! debug(
/// #![feature(phase)] /// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log; /// #[phase(plugin, link)] extern crate log;
/// ///
/// # fn main() { /// struct Point { x: int, y: int }
/// # struct Point { x: int, y: int } /// fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } }
/// # fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } } ///
/// if log_enabled!(log::DEBUG) { /// fn main() {
/// let x = some_expensive_computation(); /// if log_enabled!(log::DEBUG) {
/// debug!("x.x = {}, x.y = {}", x.x, x.y); /// 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_export]
macro_rules! log_enabled( macro_rules! log_enabled(