File size: 2,259 Bytes
f14b4e9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | use indicatif::MultiProgress;
use indicatif_log_bridge::LogWrapper;
use log::{Level, Log, Metadata, Record};
use std::sync::OnceLock;
use super::ui;
/// Tracks indicatif progress bars so they can be stalled when outputting logs.
static MULTI_PROGRESS: OnceLock<MultiProgress> = OnceLock::new();
/// Gets or creates a global indicatif progress bar tracker.
pub fn get_multi_progress() -> &'static MultiProgress {
MULTI_PROGRESS.get_or_init(MultiProgress::new)
}
/// A logger implementation that outputs library logs to console UI messages.
struct UiLogger {
verbose: bool,
}
impl Log for UiLogger {
/// Configures logger to take logs from firm libraries.
fn enabled(&self, metadata: &Metadata) -> bool {
// Determine if the log originates from a firm crate
let target = metadata.target();
let is_firm_crate = target.contains("firm");
// In verbose mode, set debug level for firm crates and warn level for others
if self.verbose && is_firm_crate {
metadata.level() <= Level::Debug
} else {
metadata.level() <= Level::Warn
}
}
/// Pipes library logs to the appropriate UI message.
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
match record.level() {
Level::Error => ui::error(&record.args().to_string()),
Level::Warn => ui::warning(&record.args().to_string()),
Level::Info => ui::info(&record.args().to_string()),
Level::Debug => ui::debug(&record.args().to_string()),
Level::Trace => ui::debug(&record.args().to_string()),
}
}
}
fn flush(&self) {}
}
/// Initializes logging for the CLI.
pub fn initialize(verbose: bool) -> Result<(), log::SetLoggerError> {
let ui_logger = UiLogger { verbose };
// Wrap logger, allowing indicatif progress bars to be suspended when we output logs
let wrapped_logger = LogWrapper::new(get_multi_progress().clone(), Box::new(ui_logger));
log::set_boxed_logger(Box::new(wrapped_logger))?;
if verbose {
log::set_max_level(log::LevelFilter::Debug);
} else {
log::set_max_level(log::LevelFilter::Warn);
}
Ok(())
}
|