use std::env; use colored::Colorize; use fern::Dispatch; use log::{Record, SetLoggerError}; fn format_regular>(log: S, record: &Record) -> String { let log = log.into(); let line_prefix = |line: String, extend: bool| { let prefix = if extend { match record.level() { log::Level::Trace => " ]".bright_blue(), log::Level::Debug => " ?".green(), log::Level::Info => " >".blue(), log::Level::Warn => " #".yellow(), log::Level::Error => " !".red(), }.to_string() } else { match record.level() { log::Level::Trace => "[TRACE]".bright_blue(), log::Level::Debug => "??".green(), log::Level::Info => "=>".blue(), log::Level::Warn => "##".yellow(), log::Level::Error => "!!".red() }.to_string() }; return format!("{} {}", prefix, line); }; let mut lines = log.lines().peekable(); let mut output = match lines.peek() { Some(_line) => line_prefix(lines.next().unwrap().to_string(), false), None => return "".to_string(), }; for line in lines { output.push_str(&*format!("\n{}", line_prefix(line.to_string(), true))); } output } pub fn setup_logger() -> Result<(), SetLoggerError> { Dispatch::new() .format(|out, message, record| { match record.metadata().target() { // command output logging "command:stdout" => out.finish(format_args!("{} {}", ">>".cyan(), message.to_string())), "command:stderr" => out.finish(format_args!("{} {}", ">>".red(), message.to_string())), // this target means, it's an item and not a log. "item" => out.finish(format_args!("{} {}", "*".blue(), message.to_string())), // default logging _ => out.finish(format_args!("{}", format_regular(message.to_string(), record))), } }) .level( env::var("PKGR_LOG_LEVEL") .unwrap_or_else(|_| "info".to_string()) .parse() .unwrap_or(log::LevelFilter::Info), ) .chain(std::io::stdout()) .apply() }