Expand description
A lightweight logging facade.
Thelog
crate provides a single logging API that abstracts over theactual logging implementation. Libraries can use the logging API providedby this crate, and the consumer of those libraries can choose the loggingimplementation that is most suitable for its use case.
If no logging implementation is selected, the facade falls back to a “noop”implementation that ignores all log messages. The overhead in this caseis very small - just an integer load, comparison and jump.
A log request consists of atarget, alevel, and abody. A target is astring which defaults to the module path of the location of the log request,though that default may be overridden. Logger implementations typically usethe target to filter requests based on some user configuration.
§Usage
The basic use of the log crate is through the five logging macros:error!
,warn!
,info!
,debug!
andtrace!
whereerror!
represents the highest-priority log messagesandtrace!
the lowest. The log messages are filtered by configuringthe log level to exclude messages with a lower priority.Each of these macros accept format strings similarly toprintln!
.
Avoid writing expressions with side-effects in log statements. They may not be evaluated.
§In libraries
Libraries should link only to thelog
crate, and use the providedmacros to log whatever information will be useful to downstream consumers.
§Examples
uselog::{info, warn};pub fnshave_the_yak(yak:&mutYak) {info!(target:"yak_events","Commencing yak shaving for {yak:?}");loop{matchfind_a_razor() {Ok(razor) => {info!("Razor located: {razor}"); yak.shave(razor);break; }Err(err) => {warn!("Unable to locate a razor: {err}, retrying"); } } }}
§In executables
Executables should choose a logging implementation and initialize it early in theruntime of the program. Logging implementations will typically include afunction to do this. Any log messages generated beforethe implementation is initialized will be ignored.
The executable itself may use thelog
crate to log as well.
§Warning
The logging system may only be initialized once.
§Structured logging
If you enable thekv
feature you can associate structured valueswith your log records. If we take the example from before, we can includesome additional context besides what’s in the formatted message:
uselog::{info, warn};pub fnshave_the_yak(yak:&mutYak) {info!(target:"yak_events", yak:serde;"Commencing yak shaving");loop{matchfind_a_razor() {Ok(razor) => {info!(razor;"Razor located"); yak.shave(razor);break; }Err(e) => {warn!(e:err;"Unable to locate a razor, retrying"); } } }}
See thekv
module documentation for more details.
§Available logging implementations
In order to produce log output executables have to usea logger implementation compatible with the facade.There are many available implementations to choose from,here are some of the most popular ones:
- Simple minimal loggers:
- Complex configurable frameworks:
- Adaptors for other facilities:
- For WebAssembly binaries:
- For dynamic libraries:
- You may need to construct an FFI-safe wrapper over
log
to initialize in your libraries
- You may need to construct an FFI-safe wrapper over
- Utilities:
§Implementing a Logger
Loggers implement theLog
trait. Here’s a very basic example that simplylogs all messages at theError
,Warn
orInfo
levels to stdout:
uselog::{Record, Level, Metadata};structSimpleLogger;impllog::LogforSimpleLogger {fnenabled(&self, metadata:&Metadata) -> bool { metadata.level() <= Level::Info }fnlog(&self, record:&Record) {ifself.enabled(record.metadata()) {println!("{} - {}", record.level(), record.args()); } }fnflush(&self) {}}
Loggers are installed by calling theset_logger
function. The maximumlog level also needs to be adjusted via theset_max_level
function. Thelogging facade uses this as an optimization to improve performance of logmessages at levels that are disabled. It’s important to set it, as itdefaults toOff
, so no log messages will ever be captured!In the case of our example logger, we’ll want to set the maximum log leveltoInfo
, since we ignore anyDebug
orTrace
level log messages. A logging implementation shouldprovide a function that wraps a call toset_logger
andset_max_level
, handling initialization of the logger:
uselog::{SetLoggerError, LevelFilter};staticLOGGER: SimpleLogger = SimpleLogger;pub fninit() ->Result<(), SetLoggerError> { log::set_logger(&LOGGER) .map(|()| log::set_max_level(LevelFilter::Info))}
Implementations that adjust their configurations at runtime should take careto adjust the maximum log level as well.
§Use withstd
set_logger
requires you to provide a&'static Log
, which can be hard toobtain if your logger depends on some runtime configuration. Theset_boxed_logger
function is available with thestd
Cargo feature. It isidentical toset_logger
except that it takes aBox<Log>
rather than a&'static Log
:
pub fninit() ->Result<(), SetLoggerError> { log::set_boxed_logger(Box::new(SimpleLogger)) .map(|()| log::set_max_level(LevelFilter::Info))}
§Compile time filters
Log levels can be statically disabled at compile time by enabling one of these Cargo features:
max_level_off
max_level_error
max_level_warn
max_level_info
max_level_debug
max_level_trace
Log invocations at disabled levels will be skipped and will not even be present in theresulting binary. These features control the value of theSTATIC_MAX_LEVEL
constant. Thelogging macros check this value before logging a message. By default, no levels are disabled.
It is possible to override this level for release builds only with the following features:
release_max_level_off
release_max_level_error
release_max_level_warn
release_max_level_info
release_max_level_debug
release_max_level_trace
Libraries should avoid using the max level features because they’re global and can’t be changedonce they’re set.
For example, a crate can disable trace level logs in debug builds and trace, debug, and infolevel logs in release builds with the following configuration:
[dependencies]log = { version = "0.4", features = ["max_level_debug", "release_max_level_warn"] }
§Crate Feature Flags
The following crate feature flags are available in addition to the filters. They areconfigured in yourCargo.toml
.
std
allows use ofstd
crate instead of the defaultcore
. Enables usingstd::error
andset_boxed_logger
functionality.serde
enables support for serialization and deserialization ofLevel
andLevelFilter
.
[dependencies]log = { version = "0.4", features = ["std", "serde"] }
§Version compatibility
The 0.3 and 0.4 versions of thelog
crate are almost entirely compatible. Log messagesmade usinglog
0.3 will forward transparently to a logger implementation usinglog
0.4. Logmessages made usinglog
0.4 will forward to a logger implementation usinglog
0.3, but themodule path and file name information associated with the message will unfortunately be lost.
Modules§
- kv
- Structured logging.
Macros§
- debug
- Logs a message at the debug level.
- error
- Logs a message at the error level.
- info
- Logs a message at the info level.
- log
- The standard logging macro.
- log_
enabled - Determines if a message logged at the specified level in that module willbe logged.
- trace
- Logs a message at the trace level.
- warn
- Logs a message at the warn level.
Structs§
- Metadata
- Metadata about a log message.
- Metadata
Builder - Builder for
Metadata
. - Parse
Level Error - The type returned by
from_str
when the string doesn’t match any of the log levels. - Record
- The “payload” of a log message.
- Record
Builder - Builder for
Record
. - SetLogger
Error - The type returned by
set_logger
ifset_logger
has already been called.
Enums§
- Level
- An enum representing the available verbosity levels of the logger.
- Level
Filter - An enum representing the available verbosity level filters of the logger.
Constants§
- STATIC_
MAX_ LEVEL - The statically resolved maximum log level.
Traits§
- Log
- A trait encapsulating the operations required of a logger.
Functions§
- logger
- Returns a reference to the logger.
- max_
level - Returns the current maximum log level.
- set_
boxed_ logger - Sets the global logger to a
Box<Log>
. - set_
logger - Sets the global logger to a
&'static Log
. - set_
logger_ ⚠racy - A thread-unsafe version of
set_logger
. - set_
max_ level - Sets the global maximum log level.
- set_
max_ ⚠level_ racy - A thread-unsafe version of
set_max_level
.