logging/
handler.rs

1//! Log handling implementations for the logger.
2
3use std::{
4  fmt::Debug,
5  fs::OpenOptions,
6  io::Write,
7  time::SystemTime,
8};
9
10use crate::LogLevel;
11
12pub trait Handler {
13  fn trace(&mut self, message: String);
14  fn debug(&mut self, message: String);
15  fn info(&mut self, message: String);
16  fn warn(&mut self, message: String);
17  fn error(&mut self, message: String);
18  fn fatal(&mut self, message: String);
19}
20
21/// A handler that logs to a file.
22
23#[derive(Debug, Clone, PartialEq, PartialOrd)]
24pub struct FileHandler {
25  file: String,
26  log_buffer: Vec<String>,
27}
28
29impl FileHandler {
30  pub fn new(file: String) -> Self {
31    Self {
32      file,
33      log_buffer: Vec::new(),
34    }
35  }
36
37  /// Logs a message to the file.
38  fn log(&mut self, log_level: LogLevel, message: String) {
39    let timestamp = SystemTime::now()
40      .duration_since(SystemTime::UNIX_EPOCH)
41      .unwrap()
42      .as_secs();
43
44    let log_message = format!("[{}]-[{:?}]: {}", timestamp, log_level, message);
45
46    let colored_message = match log_level {
47      LogLevel::TRACE => format!("\x1B[37m{}\x1B[0m", log_message),
48      LogLevel::DEBUG => format!("\x1B[35m{}\x1B[0m", log_message),
49      LogLevel::INFO => format!("\x1B[32m{}\x1B[0m", log_message),
50      LogLevel::WARN => format!("\x1B[33m{}\x1B[0m", log_message),
51      LogLevel::ERROR => format!("\x1B[31;1m{}\x1B[0m", log_message),
52      LogLevel::FATAL => format!("\x1B[31;1m{}\x1B[0m", log_message),
53    };
54
55    self.log_buffer.push(colored_message);
56
57    // Flush buffer every ten messages.
58    if self.log_buffer.len() < 10 {
59      return;
60    }
61
62    let log_message = self.log_buffer.join("\n");
63
64    let mut file = OpenOptions::new()
65      .append(true)
66      .create(true)
67      .open(self.file.clone())
68      .unwrap();
69
70    file
71      .write_all(log_message.as_bytes())
72      .expect("Unable to write data");
73
74    self.log_buffer.clear();
75  }
76}
77
78impl Handler for FileHandler {
79  fn trace(&mut self, message: String) {
80    self.log(LogLevel::TRACE, message)
81  }
82
83  fn debug(&mut self, message: String) {
84    self.log(LogLevel::DEBUG, message)
85  }
86
87  fn info(&mut self, message: String) {
88    self.log(LogLevel::INFO, message)
89  }
90
91  fn warn(&mut self, message: String) {
92    self.log(LogLevel::WARN, message)
93  }
94
95  fn error(&mut self, message: String) {
96    self.log(LogLevel::ERROR, message)
97  }
98
99  fn fatal(&mut self, message: String) {
100    self.log(LogLevel::FATAL, message)
101  }
102}
103
104#[derive(Debug, Clone, PartialEq, PartialOrd)]
105pub struct ConsoleHandler {
106  name: String,
107}
108
109impl ConsoleHandler {
110  pub fn new(name: &str) -> Self {
111    return Self {
112      name: name.to_string(),
113    };
114  }
115
116  fn log(&mut self, log_level: LogLevel, message: String) {
117    let timestamp = SystemTime::now()
118      .duration_since(SystemTime::UNIX_EPOCH)
119      .unwrap()
120      .as_secs();
121
122    let log_message = format!(
123      "[{}]-[{:?}]-[{}]: {}",
124      timestamp, log_level, self.name, message
125    );
126
127    let colored_message = match log_level {
128      LogLevel::TRACE => format!("\x1B[37m{}\x1B[0m", log_message),
129      LogLevel::DEBUG => format!("\x1B[35m{}\x1B[0m", log_message),
130      LogLevel::INFO => format!("\x1B[32m{}\x1B[0m", log_message),
131      LogLevel::WARN => format!("\x1B[33m{}\x1B[0m", log_message),
132      LogLevel::ERROR => format!("\x1B[31;1m{}\x1B[0m", log_message),
133      LogLevel::FATAL => format!("\x1B[31;1m{}\x1B[0m", log_message),
134    };
135
136    println!("{}", colored_message);
137  }
138}
139
140impl Handler for ConsoleHandler {
141  fn trace(&mut self, message: String) {
142    self.log(LogLevel::TRACE, message);
143  }
144
145  fn debug(&mut self, message: String) {
146    self.log(LogLevel::DEBUG, message);
147  }
148
149  fn info(&mut self, message: String) {
150    self.log(LogLevel::INFO, message);
151  }
152
153  fn warn(&mut self, message: String) {
154    self.log(LogLevel::WARN, message);
155  }
156
157  fn error(&mut self, message: String) {
158    self.log(LogLevel::ERROR, message);
159  }
160
161  fn fatal(&mut self, message: String) {
162    self.log(LogLevel::FATAL, message);
163  }
164}