nullnet_liblogging/
lib.rs1#![doc = include_str!("../README.md")]
2
3use std::iter::{IntoIterator, Iterator};
4use std::str::FromStr;
5
6use log::LevelFilter;
7
8use crate::console_logger::ConsoleLogger;
9pub use crate::syslog_logger::SyslogEndpoint;
10use crate::syslog_logger::SyslogLogger;
11
12mod console_logger;
13mod syslog_logger;
14
15static DEFAULT_ALLOWED_TARGETS: once_cell::sync::Lazy<Vec<String>> =
16 once_cell::sync::Lazy::new(|| {
17 vec!["nullnet", "appguard", "wallguard"]
18 .into_iter()
19 .map(str::to_lowercase)
20 .collect()
21 });
22
23pub struct Logger {
25 syslog: SyslogLogger,
26 console: ConsoleLogger,
27 allowed_targets: Vec<String>,
28}
29
30impl Logger {
31 pub fn init(
39 syslog_server: SyslogEndpoint,
40 process_name: &str,
41 allowed_targets: Vec<&'static str>,
42 ) {
43 let env_log_level = std::env::var("LOG_LEVEL").unwrap_or("trace".to_string());
44 let level_filter = LevelFilter::from_str(&env_log_level).unwrap_or(LevelFilter::Trace);
45 if level_filter.to_level().is_some() {
46 let allowed_targets = allowed_targets.into_iter().map(str::to_lowercase).collect();
47 log::set_boxed_logger(Box::new(Logger {
48 syslog: SyslogLogger::new(syslog_server, process_name),
49 console: ConsoleLogger::new(),
50 allowed_targets,
51 }))
52 .unwrap_or_default();
53 }
54 log::set_max_level(level_filter);
55 }
56}
57
58impl log::Log for Logger {
59 fn enabled(&self, metadata: &log::Metadata) -> bool {
60 self.syslog.enabled(metadata) || self.console.enabled(metadata)
61 }
62
63 fn log(&self, record: &log::Record) {
64 let target = record.target().to_lowercase();
65 if DEFAULT_ALLOWED_TARGETS
66 .iter()
67 .any(|s| target.starts_with(s))
68 || self.allowed_targets.iter().any(|s| target.starts_with(s))
69 {
70 self.syslog.log(record);
71 self.console.log(record);
72 }
73 }
74
75 fn flush(&self) {
76 self.syslog.flush();
77 self.console.flush();
78 }
79}