use std::fs::File;
use fern::colors::{Color, ColoredLevelConfig};
use log::LevelFilter;
use crate::config::ConfigProvider;
use crate::Error;
pub fn init_logging(provider: &dyn ConfigProvider) -> Result<(), Error> {
let config = provider.config().map_err(|e| {
Error::Config(format!(
"Failed to get workflow configuration for logging: {e}"
))
})?;
let log_file_path = config.workflow_cache.join("workflow.log");
if let Some(parent) = log_file_path.parent() {
std::fs::create_dir_all(parent).ok();
}
let colors = ColoredLevelConfig::new()
.error(Color::Red)
.warn(Color::Yellow)
.info(Color::Green)
.debug(Color::Blue)
.trace(Color::White);
let log_file = match File::create(&log_file_path) {
Ok(file) => file,
Err(e) => {
eprintln!("Warning: Could not create log file: {e}");
return fern::Dispatch::new()
.format(move |out, message, record| {
out.finish(format_args!(
"[{} {} {}] {}",
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
colors.color(record.level()),
record.target(),
message
))
})
.chain(std::io::stderr())
.level(LevelFilter::Debug)
.apply()
.map_err(|e| {
Error::Logging(format!("Failed to initialize stderr-only logger: {e}"))
});
}
};
fern::Dispatch::new()
.format(move |out, message, record| {
out.finish(format_args!(
"[{} {} {}] {}",
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
colors.color(record.level()),
record.target(),
message
))
})
.chain(
fern::Dispatch::new()
.level(LevelFilter::Info)
.chain(std::io::stderr()),
)
.chain(
fern::Dispatch::new()
.level(LevelFilter::Debug)
.chain(log_file),
)
.level(LevelFilter::Debug)
.apply()
.map_err(|e| Error::Logging(format!("Failed to initialize logger: {e}")))
}