Loggers play the most significant role in the software development community that not all developers take it seriously. Due to this, all have lost countless hours while debugging the code. So it is helpful to use logger. So, lets explore how to use loggers in Rust.
Importance of Logger?
Logger provides tremendous help to the developer while understanding the code. But also some developer assumes that there is no need of stack trace if the logger is implemented in the code but actually it is not at all true. The stack trace is great and gives you full track of things. Where it generates and what went wrong. But it cannot tell why it generates. Here loggers help us and give information that why it happened.
Loggers In Rust
We can use loggers in our rust code by adding log crate. And if we want to print log by stdout and stderr then we have to use env-logger crate also.
[dependencies]
env_logger = "0.5.12"
log = "0.4.6"
There are many levels of loggers. In rust code, we have to manually set the level of the logger. The hierarchies of the loggers are in decreasing order ERROR, WARN, INFO, DEBUG. If we define log level to error then it will log only an error message. And if we define log level to warn then it will log both an error and warn message like this, it follows.
#[macro_use]
extern crate log;
extern crate env_logger;
use env_logger::Env;
use env_logger::init;
fn main() {
let env = Env::default()
.filter_or("MY_LOG_LEVEL", "debug")
.write_style_or("MY_LOG_STYLE", "always");
env_logger::init_from_env(env);
debug!("this is debug log");
info!("this is information log");
warn!("this is warning log");
error!("this is error log");
}
output :-
Compiling future v0.1.0 (/home/knoldus/Rustprojects/futures)
Finished dev [unoptimized + debuginfo] target(s) in 1.63s
Running `target/debug/future`
DEBUG 2019-03-05T06:35:06Z: future: this is debug log
INFO 2019-03-05T06:35:06Z: future: this is information log
WARN 2019-03-05T06:35:06Z: future: this is warning log
ERROR 2019-03-05T06:35:06Z: future: this is error log
In the above example, we define the level of the logger to DEBUG by using a filter_or function. so it will log all the message of other loggers.
In rust, we can also store our logs in
[dependencies]
log = "0.4.6"
simplelog = "0.3.0"
#[macro_use]
extern crate log;
extern crate simplelog;
use simplelog::*;
use std::fs::File;
fn main() {
CombinedLogger::init(
vec![
WriteLogger::new(LogLevelFilter::Debug, Config::default(), File::create("my_rust_binary.log").unwrap()),
]
).unwrap();
debug!("this is debug log");
info!("this is information log");
warn!("this is warning log");
error!("this is error log");
}
output:-
Compiling future v0.1.0 (/home/knoldus/Rustprojects/futures)
Finished dev [unoptimized + debuginfo] target(s) in 0.67s
Runningtarget/debug/future
In the above example, we can write logs into a particular file by creating an object of WriteLogger. And define log level by LogLevelFilter.