1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
mod test_utils;
use flexi_logger::{
detailed_format,
writers::{FileLogWriter, LogWriter},
DeferredNow, FileSpec, Logger,
};
use log::*;
use std::sync::Arc;
#[macro_use]
mod macros {
#[macro_export]
macro_rules! sec_alert_error {
($($arg:tt)*) => (
error!(target: "{Sec,Alert,_Default}", $($arg)*);
)
}
}
#[test]
fn test() {
// more complex just to support validation:
let (sec_writer, sec_handle) = SecWriter::new();
let logger = Logger::try_with_str("info, fantasy = trace")
.unwrap()
.format(detailed_format)
.print_message()
.log_to_file(
FileSpec::default()
.suppress_timestamp()
.directory(self::test_utils::dir()),
)
.add_writer("Sec", sec_writer)
.add_writer("Alert", alert_logger())
.start()
.unwrap_or_else(|e| panic!("Logger initialization failed with {e}"));
// Explicitly send logs to different loggers
error!(target : "{Sec}", "This is a security-relevant error message");
error!(target : "{Sec,Alert}", "This is a security-relevant alert message");
error!(target : "{Sec,Alert,_Default}", "This is a security-relevant alert and log message");
error!(target : "{Alert}", "This is an alert");
// Nicer: use explicit macros
sec_alert_error!("This is another security-relevant alert and log message");
warn!("This is a warning");
info!("This is an info message");
debug!("This is a debug message - you must not see it!");
trace!("This is a trace message - you must not see it!");
trace!(target: "phantasia", "this is a trace you should not see");
trace!(target: "fantasy", "this is a trace you should see");
// Switching off logging has no effect on non-default targets
logger.parse_new_spec("Off").unwrap();
sec_alert_error!("This is a further security-relevant alert and log message");
// Verification:
#[rustfmt::skip]
logger.validate_logs(&[
("ERROR", "multi_logger", "a security-relevant alert and log message"),
("ERROR", "multi_logger", "another security-relevant alert and log message"),
("WARN", "multi_logger", "warning"),
("INFO", "multi_logger", "info"),
("TRACE", "multi_logger", "this is a trace you should see"),
]);
#[rustfmt::skip]
sec_handle.validate_logs(&[
("ERROR", "multi_logger", "security-relevant error"),
("ERROR", "multi_logger", "a security-relevant alert"),
("ERROR", "multi_logger", "security-relevant alert and log message"),
("ERROR", "multi_logger", "another security-relevant alert"),
("ERROR", "multi_logger", "a further security-relevant alert"),
]);
}
struct SecWriter(Arc<FileLogWriter>);
impl SecWriter {
pub fn new() -> (Box<SecWriter>, Arc<FileLogWriter>) {
let a_flw = Arc::new(
FileLogWriter::builder(
FileSpec::default()
.directory(self::test_utils::dir())
.discriminant("Security")
.suffix("seclog"),
)
.print_message()
.try_build()
.unwrap(),
);
(Box::new(SecWriter(Arc::clone(&a_flw))), a_flw)
}
}
impl LogWriter for SecWriter {
fn write(&self, now: &mut DeferredNow, record: &Record) -> std::io::Result<()> {
self.0.write(now, record)
}
fn flush(&self) -> std::io::Result<()> {
self.0.flush()
}
fn max_log_level(&self) -> log::LevelFilter {
log::LevelFilter::Error
}
}
pub fn alert_logger() -> Box<FileLogWriter> {
Box::new(
FileLogWriter::builder(
FileSpec::default()
.directory(self::test_utils::dir())
.discriminant("Alert")
.suffix("alerts"),
)
.print_message()
.try_build()
.unwrap(),
)
}
|