Rust Logging
Published: 2019-08-13One key component of any robust application is being able to configure a logging framework and produce logs.
For Rust, we have a lightweight logging facade crate named log.
In order for logging to be produced, an actual logging framework must
be used that is compatible with the log
crate.
Since I'm coming from the JVM and familiar with great logging frameworks like log4j2, I was drawn to the log4rs crate.
Project Setup
After creating a new Rust project with cargo via crate new <your_project_name>
,
we need to specify our dependencies on the crates by editing Cargo.toml
and
updating the dependencies
section:
[dependencies]
# https://github.com/rust-lang-nursery/log
log = "0.4.8"
# https://github.com/sfackler/log4rs
log4rs = "0.8.3"
I like to document links to my libraries as comments for quick reference.
Logging Configuration
The first thing we need to do is to configure our logging framework.
There is more than one way to do this and I opted to have an external log4rs.yaml
file for
ease of use.
The downside is that I have to distribute this file with my binary, but the upside is
that it also allows me to change the configuration while my application is running by simply
editing the log4rs.yaml
.
For a simple configuration, create the log4rs.yaml
file at the root of your project:
# Scan this file for changes every 30 seconds
refresh_rate: 30 seconds
appenders:
# An appender named "stdout" that writes to stdout
stdout:
kind: console
# Set the default logging level to "warn" and attach the "stdout" appender to the root
root:
level: info
appenders:
- stdout
More examples here.
Logging
By default Cargo creates a src
directory containing a single main.rs
.
We need to edit this file and reference both the external crates:
extern crate log;
extern crate log4rs;
Next, to actually log messages, we have to use
methods from the log
crate. For example,
to log at the info
level (see the docs):
use log::info;
Next, in the main
function, we need to initialize our log4rs
framework and log
a test message:
fn main() {
log4rs::init_file("log4rs.yml", Default::default()).unwrap();
info!("Hello Rust!");
}
Putting it all together:
extern crate log;
extern crate log4rs;
use log::info;
fn main() {
log4rs::init_file("log4rs.yml", Default::default()).unwrap();
info!("Hello Rust!");
}
Let's test out the logging by running our program with cargo -q run
:
2019-08-13T23:53:39.193548108-05:00 INFO rust_logging - Hello Rust!
The logging macros accept format strings too:
let world = "World";
info!("Hello {}!", world);
Which outputs:
2019-08-13T23:57:32.405480832-05:00 INFO rust_logging - Hello World!