use anyhow::{Context, Result}; use std::fs::OpenOptions; use time::{format_description::well_known::Rfc3339, UtcOffset}; use tracing_subscriber::{ filter::LevelFilter, fmt::{self, time::OffsetTime}, layer::SubscriberExt, util::SubscriberInitExt, Layer, }; /// Initializes the logger. pub fn init_logger(log_file: &str, utc_offset_hours: i8, utc_offset_minutes: i8) -> 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 = OpenOptions::new() .create(true) .append(true) .open(log_file) .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(()) }