Skip to main content

pepe_log/
lib.rs

1use std::sync::Mutex;
2
3pub use ::slog;
4use format::LogFormat;
5use once_cell::sync::Lazy;
6use slog::{o, Drain, FnValue, Logger, PushFnValue, Record};
7
8pub static LOGGER: Lazy<slog::Logger> = Lazy::new(new_logger);
9
10pub fn new_logger() -> Logger {
11    match LogFormat::from_env() {
12        LogFormat::PlainText => {
13            let decorator = slog_term::PlainDecorator::new(std::io::stdout());
14            let drain = slog_term::FullFormat::new(decorator).build().fuse();
15            let drain = slog_async::Async::new(drain).chan_size(1000).build().fuse();
16            let drain = slog_envlogger::new(drain).fuse();
17            let drain = Mutex::new(drain).map(slog::Fuse);
18            slog::Logger::root(drain, o!())
19        }
20        LogFormat::Json => {
21            let drain = slog_json::Json::new(std::io::stdout()).build().fuse();
22            let drain = slog_async::Async::new(drain).chan_size(1000).build().fuse();
23            let drain = slog_envlogger::new(drain).fuse();
24            let drain = Mutex::new(drain).map(slog::Fuse);
25            slog::Logger::root(
26                drain,
27                o!(
28                    "ts" => PushFnValue(move |_: &Record, ser| {
29                        ser.emit(chrono::Local::now().to_rfc3339())
30                    }),
31                    "lvl" => FnValue(move |rec: &Record| {
32                        rec.level().as_short_str()
33                    }),
34                    "msg" => PushFnValue(move |rec: &Record, ser| {
35                        ser.emit(rec.msg())
36                    }),
37                ),
38            )
39        }
40    }
41}
42
43#[macro_export]
44macro_rules! trace(
45    (#$tag:expr, $($args:tt)+) => {
46        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Trace, $tag, $($args)+)
47    };
48    ($($args:tt)+) => {
49        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Trace, "", $($args)+)
50    };
51);
52
53#[macro_export]
54macro_rules! debug(
55    (#$tag:expr, $($args:tt)+) => {
56        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Debug, $tag, $($args)+)
57    };
58    ($($args:tt)+) => {
59        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Debug, "", $($args)+)
60    };
61);
62
63#[macro_export]
64macro_rules! info(
65    (#$tag:expr, $($args:tt)+) => {
66        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Info, $tag, $($args)+)
67    };
68    ($($args:tt)+) => {
69        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Info, "", $($args)+)
70    };
71);
72
73#[macro_export]
74macro_rules! warn(
75    (#$tag:expr, $($args:tt)+) => {
76        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Warning, $tag, $($args)+)
77    };
78    ($($args:tt)+) => {
79        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Warning, "", $($args)+)
80    };
81);
82
83#[macro_export]
84macro_rules! error(
85    (#$tag:expr, $($args:tt)+) => {
86        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Error, $tag, $($args)+)
87    };
88    ($($args:tt)+) => {
89        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Error, "", $($args)+)
90    };
91);
92
93#[macro_export]
94macro_rules! crit(
95    (#$tag:expr, $($args:tt)+) => {
96        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Critical, $tag, $($args)+)
97    };
98    ($($args:tt)+) => {
99        $crate::slog::log!($crate::LOGGER, $crate::slog::Level::Critical, "", $($args)+)
100    };
101);
102
103mod format {
104    use std::env;
105
106    #[derive(Copy, Clone)]
107    pub(crate) enum LogFormat {
108        PlainText,
109        Json,
110    }
111
112    impl Default for LogFormat {
113        fn default() -> Self {
114            Self::Json
115        }
116    }
117
118    impl<S: AsRef<str>> From<S> for LogFormat {
119        fn from(s: S) -> Self {
120            match s.as_ref() {
121                "plain" => Self::PlainText,
122                "json" => Self::Json,
123                "" => Default::default(),
124                _ => panic!("Unrecognized {} value: '{}'", Self::ENV_NAME, s.as_ref()),
125            }
126        }
127    }
128
129    impl LogFormat {
130        const ENV_NAME: &'static str = "RUST_LOG_FORMAT";
131
132        pub(crate) fn from_env() -> Self {
133            Self::from(env::var(Self::ENV_NAME).ok().unwrap_or_default())
134        }
135    }
136}
137
138#[test]
139fn test_simple_info() {
140    info!("test"; "q" => 2);
141    info!("test");
142}