1use std::fmt::Debug;
4
5pub mod handler;
7
8#[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
19pub struct Logger {
21 name: String,
22 level: LogLevel,
23 handlers: Vec<Box<dyn handler::Handler>>,
24}
25
26impl Logger {
27 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 pub fn global() -> &'static mut Self {
38 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 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 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 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 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 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 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 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#[macro_export]
133macro_rules! trace {
134 ($($arg:tt)*) => {
135 logging::Logger::global().trace(format!("{}", format_args!($($arg)*)));
136 };
137}
138
139#[macro_export]
141macro_rules! debug {
142 ($($arg:tt)*) => {
143 logging::Logger::global().debug(format!("{}", format_args!($($arg)*)));
144 };
145}
146
147#[macro_export]
149macro_rules! info {
150 ($($arg:tt)*) => {
151 logging::Logger::global().info(format!("{}", format_args!($($arg)*)));
152 };
153}
154
155#[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}