logging/
lib.rs

1//! A simple logging library for lambda-rs crates.
2
3use std::fmt::Debug;
4
5/// A trait for handling log messages.
6pub mod handler;
7
8/// The log level for the logger.
9#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
10pub enum LogLevel {
11  TRACE,
12  DEBUG,
13  INFO,
14  WARN,
15  ERROR,
16  FATAL,
17}
18
19/// Logger implementation.
20pub struct Logger {
21  name: String,
22  level: LogLevel,
23  handlers: Vec<Box<dyn handler::Handler>>,
24}
25
26impl Logger {
27  /// Creates a new logger with the given log level and name.
28  pub fn new(level: LogLevel, name: &str) -> Self {
29    Self {
30      name: name.to_string(),
31      level,
32      handlers: Vec::new(),
33    }
34  }
35
36  /// Returns the global logger.
37  pub fn global() -> &'static mut Self {
38    // TODO(vmarcella): Fix the instantiation for the global logger.
39    unsafe {
40      if LOGGER.is_none() {
41        LOGGER = Some(Logger {
42          level: LogLevel::TRACE,
43          name: "lambda-rs".to_string(),
44          handlers: vec![Box::new(handler::ConsoleHandler::new("lambda-rs"))],
45        });
46      }
47    };
48    return unsafe { &mut LOGGER }
49      .as_mut()
50      .expect("Logger not initialized");
51  }
52
53  /// Adds a handler to the logger. Handlers are called in the order they
54  /// are added.
55  pub fn add_handler(&mut self, handler: Box<dyn handler::Handler>) {
56    self.handlers.push(handler);
57  }
58
59  fn compare_levels(&self, level: LogLevel) -> bool {
60    level as u8 >= self.level as u8
61  }
62
63  /// Logs a trace message to all handlers.
64  pub fn trace(&mut self, message: String) {
65    if !self.compare_levels(LogLevel::TRACE) {
66      return;
67    }
68
69    for handler in self.handlers.iter_mut() {
70      handler.trace(message.clone());
71    }
72  }
73
74  /// Logs a debug message to all handlers.
75  pub fn debug(&mut self, message: String) {
76    if !self.compare_levels(LogLevel::DEBUG) {
77      return;
78    }
79    for handler in self.handlers.iter_mut() {
80      handler.debug(message.clone());
81    }
82  }
83
84  /// Logs an info message to all handlers.
85  pub fn info(&mut self, message: String) {
86    if !self.compare_levels(LogLevel::INFO) {
87      return;
88    }
89
90    for handler in self.handlers.iter_mut() {
91      handler.info(message.clone());
92    }
93  }
94
95  /// Logs a warning to all handlers.
96  pub fn warn(&mut self, message: String) {
97    if !self.compare_levels(LogLevel::WARN) {
98      return;
99    }
100    for handler in self.handlers.iter_mut() {
101      handler.warn(message.clone());
102    }
103  }
104
105  /// Logs an error to all handlers.
106  pub fn error(&mut self, message: String) {
107    if !self.compare_levels(LogLevel::ERROR) {
108      return;
109    }
110
111    for handler in self.handlers.iter_mut() {
112      handler.error(message.clone());
113    }
114  }
115
116  ///  Logs a fatal error to all handlers and exits the program.
117  pub fn fatal(&mut self, message: String) {
118    if !self.compare_levels(LogLevel::FATAL) {
119      return;
120    }
121
122    for handler in self.handlers.iter_mut() {
123      handler.fatal(message.clone());
124    }
125    std::process::exit(1);
126  }
127}
128
129pub(crate) static mut LOGGER: Option<Logger> = None;
130
131/// Trace logging macro using the global logger instance.
132#[macro_export]
133macro_rules! trace {
134  ($($arg:tt)*) => {
135      logging::Logger::global().trace(format!("{}", format_args!($($arg)*)));
136  };
137}
138
139/// Trace logging macro using the global logger instance.
140#[macro_export]
141macro_rules! debug {
142  ($($arg:tt)*) => {
143      logging::Logger::global().debug(format!("{}", format_args!($($arg)*)));
144  };
145}
146
147/// Trace logging macro using the global logger instance.
148#[macro_export]
149macro_rules! info {
150  ($($arg:tt)*) => {
151      logging::Logger::global().info(format!("{}", format_args!($($arg)*)));
152  };
153}
154
155// Define logging macros that use the global logger instance
156#[macro_export]
157macro_rules! warn {
158  ($($arg:tt)*) => {
159      logging::Logger::global().warn(format!("{}", format_args!($($arg)*)));
160  };
161}
162
163#[macro_export]
164macro_rules! error {
165  ($($arg:tt)*) => {
166      logging::Logger::global().error(format!("{}", format_args!($($arg)*)));
167  };
168}
169
170#[macro_export]
171macro_rules! fatal {
172  ($($arg:tt)*) => {
173      logging::Logger::global().fatal(format!("{}", format_args!($($arg)*)));
174  };
175}