Skip to main content

fiaas_logger/
lib.rs

1use humantime;
2use log::*;
3use serde_json::json;
4use std::thread;
5use std::time::SystemTime;
6
7pub use log::Level;
8
9pub enum FiaasEnv {
10    Local,
11    Dev,
12    Prod,
13}
14
15struct FiaasLogger {
16    finn_app: &'static str,
17    env: FiaasEnv,
18    level: log::Level,
19}
20
21impl Log for FiaasLogger {
22    fn enabled(&self, metadata: &Metadata) -> bool {
23        metadata.level() <= self.level
24    }
25
26    fn log(&self, record: &Record) {
27        if self.enabled(record.metadata()) {
28            let timestamp = humantime::format_rfc3339_millis(SystemTime::now());
29
30            match self.env {
31                FiaasEnv::Local => match record.level() {
32                    Level::Error => eprintln!(
33                        "[{timestamp} {level} {logger}] {message}",
34                        timestamp = timestamp,
35                        logger = record.target(),
36                        level = record.level(),
37                        message = record.args(),
38                    ),
39                    _ => println!(
40                        "[{timestamp} {level} {logger}] {message}",
41                        timestamp = timestamp,
42                        logger = record.target(),
43                        level = record.level(),
44                        message = record.args(),
45                    ),
46                },
47                FiaasEnv::Dev | FiaasEnv::Prod => {
48                    let t = thread::current();
49                    match record.level() {
50                        Level::Error => eprintln!(
51                            "{}",
52                            serde_json::to_string(&json!({
53                              "@version":1,
54                              "@timestamp": timestamp.to_string(),
55                              "logger": record.target(),
56                              "thread": format!("{}-{:?}", t.name().unwrap_or("unnamed"), t.id()),
57                              "level": record.level().to_string(),
58                              "message": record.args(),
59                              "finn_app": self.finn_app
60                            }))
61                            .unwrap()
62                        ),
63                        _ => println!(
64                            "{}",
65                            serde_json::to_string(&json!({
66                              "@version":1,
67                              "@timestamp": timestamp.to_string(),
68                              "logger": record.target(),
69                              "thread": format!("{}-{:?}", t.name().unwrap_or("unnamed"), t.id()),
70                              "level": record.level().to_string(),
71                              "message": record.args(),
72                              "finn_app": self.finn_app
73                            }))
74                            .unwrap()
75                        ),
76                    }
77                }
78            }
79        }
80    }
81
82    fn flush(&self) {}
83}
84
85pub fn try_init(
86    finn_app: &'static str,
87    env: FiaasEnv,
88    level: Level,
89) -> Result<(), log::SetLoggerError> {
90    let r = log::set_boxed_logger(Box::new(FiaasLogger {
91        finn_app,
92        env,
93        level,
94    }));
95    if r.is_ok() {
96        log::set_max_level(level.to_level_filter());
97    }
98    r
99}
100
101pub fn init(finn_app: &'static str, env: FiaasEnv, level: Level) {
102    try_init(finn_app, env, level).unwrap();
103}
104
105pub fn init_env(finn_app: &'static str) {
106    let level = match std::env::var("RUST_LOG")
107        .expect("RUST_LOG must be set")
108        .as_ref()
109    {
110        "error" => Level::Error,
111        "warn" => Level::Warn,
112        "info" => Level::Info,
113        "debug" => Level::Debug,
114        "trace" => Level::Trace,
115        _ => panic!("RUST_LOG must be one of error, warn, info, debug and trace"),
116    };
117
118    let env = match std::env::var("FIAAS_ENVIRONMENT")
119        .expect("FIAAS_ENVIRONMENT must be set")
120        .as_ref()
121    {
122        "local" => FiaasEnv::Local,
123        "dev" => FiaasEnv::Dev,
124        "prod" => FiaasEnv::Prod,
125        _ => panic!("FIAAS_ENVIRONMENT must be one of local, dev and prod"),
126    };
127
128    init(finn_app, env, level);
129}