Skip to main content

alembic_log/
handler.rs

1use chrono::Local;
2
3use crate::{
4    sinks::base::{LogLevels, LogMessage},
5    utils::{self},
6};
7use std::{collections::HashMap, error::Error};
8
9pub struct Handler {
10    sinks: Vec<Box<dyn LogMessage>>, // Box dyn that implements the LogMessage trait
11    log_level: u8, // the level at which we should emit logs. Default level is Error
12    level_map: HashMap<LogLevels, u8>, // a mapping of log levels to u8 values for comparison
13}
14
15impl Handler {
16    pub fn new() -> Result<Self, Box<dyn Error>> {
17        Ok(Handler {
18            sinks: vec![],
19            log_level: 3, // default log level is Error
20            level_map: map_log_levels(),
21        })
22    }
23
24    pub fn add_sink(&mut self, sink: Box<dyn LogMessage>) {
25        // Adds individual sinks to the handler
26        self.sinks.push(sink)
27    }
28
29    pub fn set_sinks(&mut self, sinks: Vec<Box<dyn LogMessage>>) {
30        // Replaces the handler's entire vector with the incoming vector
31        self.sinks = sinks
32    }
33
34    pub fn set_log_level(&mut self, new_log_level: LogLevels) {
35        self.log_level = *self.level_map.get(&new_log_level).unwrap();
36    }
37
38    fn log_to_sinks(&mut self, message: &str, log_level: LogLevels) {
39        // Generate timestamp here so all sinks have the same timestamp
40        let timestamp: chrono::DateTime<Local> = utils::generate_human_timestamp();
41
42        let message_log_level: u8 = *self.level_map.get(&log_level).unwrap();
43
44        // only emit if the message level is greater than or equal to the handler's log level
45        if message_log_level >= self.log_level {
46            for s in self.sinks.iter_mut() {
47                s.log_message(&String::from(message), timestamp, &log_level);
48            }
49        }
50    }
51
52    pub fn debug(&mut self, message: &str) {
53        self.log_to_sinks(message, LogLevels::Debug);
54    }
55
56    pub fn info(&mut self, message: &str) {
57        self.log_to_sinks(message, LogLevels::Info);
58    }
59
60    pub fn warn(&mut self, message: &str) {
61        self.log_to_sinks(message, LogLevels::Warn);
62    }
63
64    pub fn error(&mut self, message: &str) {
65        self.log_to_sinks(message, LogLevels::Error);
66    }
67
68    pub fn fatal(&mut self, message: &str) {
69        self.log_to_sinks(message, LogLevels::Fatal);
70    }
71}
72
73fn map_log_levels() -> HashMap<LogLevels, u8> {
74    let mut level_map: HashMap<LogLevels, u8> = HashMap::new();
75    level_map.insert(LogLevels::Debug, 0);
76    level_map.insert(LogLevels::Info, 1);
77    level_map.insert(LogLevels::Warn, 2);
78    level_map.insert(LogLevels::Error, 3);
79    level_map.insert(LogLevels::Fatal, 4);
80    level_map
81}