The Logging Backend
In order for the logger facade functions to work, we will need to add a logging backend. For this project, we'll use simplelog.
Add this dependency to crates/obsidian_app/Cargo.toml
:
simplelog = { version = "0.9.0", features = ["termcolor"] }
Note: The
termcolor
feature allows for colored terminal log output.
Now we can create a logger module to setup the logger backend.
// crates/obsidian_app/src/lib.rs
mod logger;
...
// crates/obsidian_app/src/logger.rs
use anyhow::{Context, Result};
use simplelog::{CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger};
use std::{fs::File, path::Path};
pub fn create_logger(path: impl AsRef<Path>) -> Result<()> {
let name = path.as_ref().display().to_string();
let error_message = format!("Failed to create log file named: {}", name);
let file = File::create(path).context(error_message)?;
CombinedLogger::init(vec![
TermLogger::new(LevelFilter::Info, Config::default(), TerminalMode::Mixed),
WriteLogger::new(LevelFilter::max(), Config::default(), file),
])?;
Ok(())
}
The CombinedLogger lets us create a TermLogger and a WriteLogger at the same time. We will only log messages with the severity Info and above to the terminal, and we will log all messages to the configuration file.
And finally we can invoke the create_logger
function in our run_application
method:
pub fn run_application(mut runner: impl Run + 'static, configuration: AppConfig) -> Result<()> {
create_logger(&configuration.logfile_name)?;
...
}