pepe-log 0.0.3

Logging functions for PepeTeam template application
Documentation
use std::sync::Mutex;

pub use ::slog;
use format::LogFormat;
use once_cell::sync::Lazy;
use slog::{o, Drain, FnValue, Logger, PushFnValue, Record};

pub static LOGGER: Lazy<slog::Logger> = Lazy::new(|| new_logger());

pub fn new_logger() -> Logger {
    match LogFormat::from_env() {
        LogFormat::PlainText => {
            let decorator = slog_term::PlainDecorator::new(std::io::stdout());
            let drain = slog_term::FullFormat::new(decorator).build().fuse();
            let drain = slog_async::Async::new(drain).chan_size(1000).build().fuse();
            // let drain = slog_envlogger::new(drain).fuse();
            let drain = Mutex::new(drain).map(slog::Fuse);
            slog::Logger::root(drain, o!())
        }
        LogFormat::Json => {
            let drain = slog_json::Json::new(std::io::stdout()).build().fuse();
            let drain = slog_async::Async::new(drain).chan_size(1000).build().fuse();
            // let drain = slog_envlogger::new(drain).fuse();
            let drain = Mutex::new(drain).map(slog::Fuse);
            slog::Logger::root(
                drain,
                o!(
                    "ts" => PushFnValue(move |_: &Record, ser| {
                        ser.emit(chrono::Local::now().to_rfc3339())
                    }),
                    "lvl" => FnValue(move |rec: &Record| {
                        rec.level().as_short_str()
                    }),
                    "msg" => PushFnValue(move |rec: &Record, ser| {
                        ser.emit(rec.msg())
                    }),
                ),
            )
        }
    }
}

#[macro_export]
macro_rules! trace(
    (#$tag:expr, $($args:tt)+) => {
        $crate::slog::trace!($crate::LOGGER, $tag, $($args)+)
    };
    ($l:expr, $($args:tt)+) => {
        $crate::slog::trace!($crate::LOGGER, "", $($args)+)
    };
);

#[macro_export]
macro_rules! debug(
    (#$tag:expr, $($args:tt)+) => {
        $crate::slog::debug!($crate::LOGGER, $tag, $($args)+)
    };
    ($l:expr, $($args:tt)+) => {
        $crate::slog::debug!($crate::LOGGER, "", $($args)+)
    };
);

#[macro_export]
macro_rules! info(
    (#$tag:expr, $($args:tt)+) => {
        $crate::slog::info!($crate::LOGGER, $tag, $($args)+)
    };
    ($l:expr, $($args:tt)+) => {
        $crate::slog::info!($crate::LOGGER, "", $($args)+)
    };
);

#[macro_export]
macro_rules! warn(
    (#$tag:expr, $($args:tt)+) => {
        $crate::slog::warn!($crate::LOGGER, $tag, $($args)+)
    };
    ($l:expr, $($args:tt)+) => {
        $crate::slog::warn!($crate::LOGGER, "", $($args)+)
    };
);

#[macro_export]
macro_rules! error(
    (#$tag:expr, $($args:tt)+) => {
        $crate::slog::error!($crate::LOGGER, $tag, $($args)+)
    };
    ($l:expr, $($args:tt)+) => {
        $crate::slog::error!($crate::LOGGER, "", $($args)+)
    };
);

#[macro_export]
macro_rules! crit(
    (#$tag:expr, $($args:tt)+) => {
        $crate::slog::crit!($crate::LOGGER, $tag, $($args)+)
    };
    ($l:expr, $($args:tt)+) => {
        $crate::slog::crit!($crate::LOGGER, "", $($args)+)
    };
);

mod format {
    use std::env;

    #[derive(Copy, Clone)]
    pub(crate) enum LogFormat {
        PlainText,
        Json,
    }

    impl Default for LogFormat {
        fn default() -> Self {
            Self::Json
        }
    }

    impl<S: AsRef<str>> From<S> for LogFormat {
        fn from(s: S) -> Self {
            match s.as_ref() {
                "plain" => Self::PlainText,
                "json" => Self::Json,
                "" => Default::default(),
                _ => panic!("Unrecognized {} value: '{}'", Self::ENV_NAME, s.as_ref()),
            }
        }
    }

    impl LogFormat {
        const ENV_NAME: &'static str = "RUST_LOG_FORMAT";

        pub(crate) fn from_env() -> Self {
            Self::from(env::var(Self::ENV_NAME).ok().unwrap_or_default())
        }
    }
}