1use file_handler::file_manager::FileManager;
9use formatter::{LogColor, LogFormatter};
10use std::sync::RwLockWriteGuard;
11
12use crate::{
13 helper::{get_current_date_in_string, get_current_time_in_string},
14 Config, Level, CONFIG,
15};
16pub mod file_handler;
18pub mod formatter;
19pub mod from_file_config;
20
21struct LogInfo {
22 file: String,
23 line: u32,
24 message: String,
25 level: Level,
26}
27
28fn get_log_level() -> Level {
30 get_config().level
31}
32fn get_config() -> Config {
33 let config_lock = match CONFIG.read() {
34 Ok(r) => r,
35 Err(e) => {
36 eprintln!("Problem with getting config, here's an error: {}", e);
37 return Default::default();
38 }
39 };
40 if let Some(ref cfg) = *config_lock {
41 cfg.clone()
42 } else {
43 eprintln!("Problem with getting config!");
44 Default::default()
45 }
46}
47
48fn get_log_format(level: Level) -> LogFormatter {
49 let tmp_cfg = get_config();
50 match level {
51 Level::TRACE => tmp_cfg.trace_log_format,
52 Level::DEBUG => tmp_cfg.debug_log_format,
53 Level::INFO => tmp_cfg.info_log_format,
54 Level::WARN => tmp_cfg.warn_log_format,
55 Level::ERROR => tmp_cfg.error_log_format,
56 }
57}
58
59fn get_file_manager() -> Option<FileManager> {
60 let tmp_cfg = get_config();
61 tmp_cfg.file_manager
62}
63
64fn get_write_config() -> Option<RwLockWriteGuard<'static, Option<Config>>> {
65 match CONFIG.write() {
66 Ok(guard) => Some(guard),
67 Err(e) => {
68 eprintln!(
69 "An error while getting the config to write, here's an error: {}",
70 e
71 );
72 None
73 } }
75}
76
77pub fn set_file(format: &str) {
95 let file_manager = match FileManager::init_from_string(format, get_config()) {
96 Ok(r) => r,
97 Err(e) => {
98 eprintln!(
99 "Couldn't establish file config due to the next reason: {}",
100 e
101 );
102 return;
103 }
104 };
105
106 let config_lock = get_write_config();
107 if config_lock.is_none() {
108 eprintln!("An error while getting the config to write!");
109 return;
110 }
111 let mut config_lock = config_lock.unwrap();
112 if let Some(ref mut cfg) = *config_lock {
113 cfg.file_manager = Some(file_manager);
114 }
115}
116
117pub fn set_compression(ctype: &str) {
126 let f_manager = get_file_manager();
127 if f_manager.is_none() {
128 eprintln!("Can't set a compression when the file isn't set!");
129 return;
130 }
131 let mut f_manager = f_manager.unwrap();
132 f_manager.set_compression(ctype);
133
134 let config_lock = get_write_config();
135 if config_lock.is_none() {
136 eprintln!("An error while getting the config to write!");
137 return;
138 }
139 let mut config_lock = config_lock.unwrap();
140 if let Some(ref mut cfg) = *config_lock {
141 cfg.file_manager = Some(f_manager);
142 }
143}
144
145pub fn add_rotation(constraint: &str) {
166 let f_manager = get_file_manager();
167 if f_manager.is_none() {
168 eprintln!("Can't set a compression when the file isn't set!");
169 return;
170 }
171 let mut f_manager = f_manager.unwrap();
172
173 if !f_manager.add_rotation(constraint) {
174 eprintln!("Incorrect value given for the rotation!");
175 return;
176 }
177
178 let config_lock = get_write_config();
179 if config_lock.is_none() {
180 eprintln!("An error while getting the config to write!");
181 return;
182 }
183 let mut config_lock = config_lock.unwrap();
184 if let Some(ref mut cfg) = *config_lock {
185 cfg.file_manager = Some(f_manager);
186 }
187}
188
189pub fn set_log_level(lvl: Level) {
192 let config_lock = get_write_config();
193 if config_lock.is_none() {
194 eprintln!("An error while getting the config to write!");
195 return;
196 }
197 let mut config_lock = config_lock.unwrap();
198 if let Some(ref mut cfg) = *config_lock {
199 cfg.level = lvl;
200 }
201}
202pub fn set_print_to_terminal(val: bool) {
205 let config_lock = get_write_config();
206 if config_lock.is_none() {
207 eprintln!("An error while getting the config to write!");
208 return;
209 }
210 let mut config_lock = config_lock.unwrap();
211 if let Some(ref mut cfg) = *config_lock {
212 cfg.print_to_terminal = val;
213 }
214}
215pub fn set_colorized(val: bool) {
218 let config_lock = get_write_config();
219 if config_lock.is_none() {
220 eprintln!("An error while getting the config to write!");
221 return;
222 }
223 let mut config_lock = config_lock.unwrap();
224 if let Some(ref mut cfg) = *config_lock {
225 cfg.colorized = val;
226 }
227}
228
229pub fn set_global_formatting(format: &str) {
232 set_level_formatting(Level::TRACE, format);
233 set_level_formatting(Level::DEBUG, format);
234 set_level_formatting(Level::INFO, format);
235 set_level_formatting(Level::WARN, format);
236 set_level_formatting(Level::ERROR, format);
237}
238
239pub fn set_level_formatting(level: Level, format: &str) {
243 let config_lock = get_write_config();
244 if config_lock.is_none() {
245 eprintln!("An error while getting the config to write!");
246 return;
247 }
248 let mut config_lock = config_lock.unwrap();
249 if let Some(ref mut cfg) = *config_lock {
250 match level {
251 Level::TRACE => cfg.trace_log_format = LogFormatter::parse_from_string(format),
252 Level::DEBUG => cfg.debug_log_format = LogFormatter::parse_from_string(format),
253 Level::INFO => cfg.info_log_format = LogFormatter::parse_from_string(format),
254 Level::WARN => cfg.warn_log_format = LogFormatter::parse_from_string(format),
255 Level::ERROR => cfg.error_log_format = LogFormatter::parse_from_string(format),
256 }
257 }
258}
259
260fn string_log(log_info: &LogInfo, colorize: bool) -> String {
262 let mut mess_to_print = String::new();
263 let curr_time: String = get_current_time_in_string();
264 let curr_date = get_current_date_in_string();
265 for log_part in get_log_format(log_info.level).parts {
266 let str_to_push = match log_part.part {
267 formatter::LogPart::Message => &log_info.message,
268 formatter::LogPart::Time => &curr_time,
269 formatter::LogPart::File => &log_info.file,
270 formatter::LogPart::Line => &log_info.line.to_string(),
271 formatter::LogPart::Date => &curr_date,
272 formatter::LogPart::Level => &log_info.level.to_string(),
273 formatter::LogPart::Text(text) => &text.clone(),
274 };
275 if colorize && log_part.color.is_some() {
276 let colored_str = LogColor::colorize_str(str_to_push, log_part.color.unwrap());
277 mess_to_print.push_str(&colored_str);
278 } else {
279 mess_to_print.push_str(str_to_push);
280 }
281 }
282 mess_to_print
283}
284fn print_log(log_info: &LogInfo) {
285 let mess_to_print = string_log(log_info, get_config().colorized);
286 println!("{}", mess_to_print);
287}
288fn write_file_log(log_info: &LogInfo) {
289 let mut file_manager = get_file_manager().unwrap();
290 let mess_to_print = string_log(log_info, false);
291
292 let res = file_manager.write_log(&mess_to_print, get_config());
293 match res {
294 Ok(_) => {}
295 Err(e) => {
296 eprintln!(
297 "Couldn't write a log to the file due to the next error: {}",
298 e
299 );
300 }
301 }
302
303 let w_conf = get_write_config();
306 if let Some(mut temp_cfg) = w_conf {
307 if let Some(ref mut cfg) = *temp_cfg {
308 cfg.file_manager = Some(file_manager)
309 }
310 }
311}
312fn log_handler(log_info: LogInfo) {
313 if get_config().print_to_terminal {
314 print_log(&log_info);
315 }
316 if get_config().file_manager.is_some() {
317 write_file_log(&log_info);
318 }
319}
320
321fn macro_handler(file: &str, line: u32, deb_str: String, level: Level) {
323 let log_info = LogInfo {
324 file: file.to_string(),
325 line,
326 message: deb_str,
327 level,
328 };
329 if level >= get_log_level() {
330 log_handler(log_info);
331 }
332}
333
334pub fn __debug_handler(file: &str, line: u32, deb_str: String, level: Level) {
338 macro_handler(file, line, deb_str, level);
339}
340
341#[macro_export]
344macro_rules! trace {
354 ($($arg:tt)*) => {{
355 let res_str = format!($($arg)*);
356 $crate::logger::__debug_handler(file!(), line!(), res_str, $crate::Level::TRACE);
357 }};
358 }
359
360#[macro_export]
361macro_rules! debug {
371 ($($arg:tt)*) => {{
372 let res_str = format!($($arg)*);
373 $crate::logger::__debug_handler(file!(), line!(), res_str, $crate::Level::DEBUG);
374 }};
375 }
376
377#[macro_export]
378macro_rules! info {
388 ($($arg:tt)*) => {{
389 let res_str = format!($($arg)*);
390 $crate::logger::__debug_handler(file!(), line!(), res_str, $crate::Level::INFO);
391 }};
392 }
393
394#[macro_export]
395macro_rules! warn {
405 ($($arg:tt)*) => {{
406 let res_str = format!($($arg)*);
407 $crate::logger::__debug_handler(file!(), line!(), res_str, $crate::Level::WARN);
408 }};
409 }
410
411#[macro_export]
412macro_rules! error {
422 ($($arg:tt)*) => {{
423 let res_str = format!($($arg)*);
424 $crate::logger::__debug_handler(file!(), line!(), res_str, $crate::Level::ERROR);
425 }};
426 }
427
428pub fn init() {
430 let mut config = CONFIG.write().unwrap();
431 *config = Some(Config {
432 ..Default::default()
433 })
434}