use clap::ArgMatches;
use crate::config::Runtime;
use failure::Error;
use getset::Getters;
use slog::{o, Drain, Level, Logger};
use slog_async::Async;
use slog_term::{CompactFormat, TermDecorator};
use std::convert::TryFrom;
#[derive(Clone, Debug, Default, Getters)]
pub struct Loggers {
#[get = "pub"]
stdout: Option<Logger>,
#[get = "pub"]
stderr: Option<Logger>,
}
impl Loggers {
pub fn split(&self) -> (Option<Logger>, Option<Logger>) {
(self.stdout.clone(), self.stderr.clone())
}
}
impl<'a> TryFrom<&'a ArgMatches<'a>> for Loggers {
type Error = Error;
fn try_from(matches: &'a ArgMatches<'a>) -> Result<Self, Error> {
let level = match matches.occurrences_of("v") {
0 => Level::Warning,
1 => Level::Info,
2 => Level::Debug,
3 | _ => Level::Trace,
};
let dm_env = Runtime::env();
let stdout_decorator = TermDecorator::new().stdout().build();
let stdout_drain = CompactFormat::new(stdout_decorator).build().fuse();
let stdout_async_drain = Async::new(stdout_drain).build().filter_level(level).fuse();
let stdout = Logger::root(stdout_async_drain, o!("env" => dm_env.clone()));
let stderr_decorator = TermDecorator::new().stdout().build();
let stderr_drain = CompactFormat::new(stderr_decorator).build().fuse();
let stderr_async_drain = Async::new(stderr_drain)
.build()
.filter_level(Level::Error)
.fuse();
let stderr = Logger::root(stderr_async_drain, o!("env" => dm_env.clone()));
Ok(Self {
stdout: Some(stdout),
stderr: Some(stderr),
})
}
}