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::datastore::config::DatastoreConfig;
10use crate::datastore_logger::DatastoreLogger;
11use crate::syslog_logger::SyslogLogger;
12
13mod console_logger;
14mod datastore;
15mod datastore_logger;
16mod syslog_logger;
17
18static DEFAULT_ALLOWED_TARGETS: once_cell::sync::Lazy<Vec<String>> =
19 once_cell::sync::Lazy::new(|| {
20 vec!["nullnet", "appguard", "wallguard"]
21 .into_iter()
22 .map(str::to_lowercase)
23 .collect()
24 });
25
26pub struct Logger {
28 console: ConsoleLogger,
29 syslog: SyslogLogger,
30 datastore: DatastoreLogger,
31 allowed_targets: Vec<String>,
32}
33
34impl Logger {
35 pub fn init(logger_config: LoggerConfig) {
40 let LoggerConfig {
41 console,
42 syslog,
43 datastore,
44 allowed_targets,
45 } = logger_config;
46
47 let env_log_level = std::env::var("LOG_LEVEL").unwrap_or("trace".to_string());
48 let level_filter = LevelFilter::from_str(&env_log_level).unwrap_or(LevelFilter::Trace);
49 if level_filter.to_level().is_some() {
50 let allowed_targets = allowed_targets.into_iter().map(str::to_lowercase).collect();
51 log::set_boxed_logger(Box::new(Logger {
52 console: ConsoleLogger::new(console),
53 syslog: SyslogLogger::new(syslog),
54 datastore: DatastoreLogger::new(datastore),
55 allowed_targets,
56 }))
57 .unwrap_or_default();
58 }
59 log::set_max_level(level_filter);
60 }
61}
62
63impl log::Log for Logger {
64 fn enabled(&self, metadata: &log::Metadata) -> bool {
65 !metadata.target().starts_with("nullnet_liblogging")
66 && (self.syslog.enabled(metadata)
67 || self.console.enabled(metadata)
68 || self.datastore.enabled(metadata))
69 }
70
71 fn log(&self, record: &log::Record) {
72 if self.enabled(record.metadata()) {
73 let target = record.target().to_lowercase();
74 if DEFAULT_ALLOWED_TARGETS
75 .iter()
76 .any(|s| target.starts_with(s))
77 || self.allowed_targets.iter().any(|s| target.starts_with(s))
78 {
79 self.syslog.log(record);
80 self.console.log(record);
81 self.datastore.log(record);
82 }
83 }
84 }
85
86 fn flush(&self) {
87 self.syslog.flush();
88 self.console.flush();
89 self.datastore.flush();
90 }
91}
92
93pub struct LoggerConfig {
95 console: bool,
96 syslog: bool,
97 datastore: Option<DatastoreConfig>,
98 allowed_targets: Vec<&'static str>,
99}
100
101impl LoggerConfig {
102 #[must_use]
113 pub fn new(
114 console: bool,
115 syslog: bool,
116 datastore: Option<DatastoreConfig>,
117 allowed_targets: Vec<&'static str>,
118 ) -> Self {
119 Self {
120 console,
121 syslog,
122 datastore,
123 allowed_targets,
124 }
125 }
126}