use anyhow::{Context, Result}; use std::{fs::OpenOptions, path::Path}; use time::{format_description::well_known::Rfc3339, UtcOffset}; use tracing_subscriber::{ filter::LevelFilter, fmt::{self, time::OffsetTime}, layer::SubscriberExt, util::SubscriberInitExt, Layer, }; use crate::config; /// Initializes the logger. pub fn init_logger(data_dir: &Path, utc_offset: &config::UtcOffset) -> Result<()> { // Set UTC offset for time formatting. let timer = OffsetTime::new( UtcOffset::from_hms(utc_offset.hours, utc_offset.minutes, 0) .context("Failed to set the time offset from the given utc_hours_offset!")?, Rfc3339, ); // Use the DEBUG level in debug builds. let stdout_level_filter = if cfg!(debug_assertions) { LevelFilter::DEBUG } else { LevelFilter::INFO }; // Stdout logger. let stdout_layer = fmt::layer() .with_ansi(true) .with_timer(timer.clone()) .with_filter(stdout_level_filter); // Log file. let log_file = { let mut buf = data_dir.to_path_buf(); buf.push("log.txt"); OpenOptions::new() .create(true) .append(true) .open(buf) .context("Failed to open the log file in append mode!")? }; let file_layer = fmt::layer() .with_writer(log_file) .with_ansi(false) .with_timer(timer) .with_filter(LevelFilter::INFO); tracing_subscriber::registry() .with(stdout_layer.and_then(file_layer)) .try_init() .context("Failed to initialize logging!")?; Ok(()) }