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}