by_axum/
logger.rs

1use slog::Drain;
2use static_str_ops::staticize;
3use std::result;
4
5pub struct RuntimeLevelFilter<D> {
6    pub drain: D,
7}
8
9impl<D> Drain for RuntimeLevelFilter<D>
10where
11    D: Drain,
12{
13    type Ok = Option<D::Ok>;
14    type Err = Option<D::Err>;
15
16    fn log(
17        &self,
18        record: &slog::Record,
19        values: &slog::OwnedKVList,
20    ) -> result::Result<Self::Ok, Self::Err> {
21        if record.level().is_at_least(match option_env!("LOG_LEVEL") {
22            Some("trace") => slog::Level::Trace,
23            Some("debug") => slog::Level::Debug,
24            Some("info") => slog::Level::Info,
25            Some("warn") => slog::Level::Warning,
26            Some("error") => slog::Level::Error,
27            Some("critical") => slog::Level::Critical,
28            _ => slog::Level::Info,
29        }) {
30            self.drain.log(record, values).map(Some).map_err(Some)
31        } else {
32            Ok(None)
33        }
34    }
35}
36
37pub fn root() -> slog::Logger {
38    let decorator = slog_term::PlainSyncDecorator::new(std::io::stdout());
39    let drain = slog_term::FullFormat::new(decorator).build().fuse();
40    let drain = RuntimeLevelFilter { drain }.fuse();
41    let drain = slog_async::Async::new(drain).build().fuse();
42
43    slog::Logger::root(
44        drain,
45        slog::o!("service" => option_env!("SERVICE").unwrap_or("unknown-server").to_string()),
46    )
47}
48
49pub fn new_log_for_api(log: slog::Logger, method: &'static str, api: &str) -> slog::Logger {
50    let api = staticize(api);
51
52    log.new(slog::o!("API Method" => method, "API Endpoint" => api))
53}