File: test_custom_log_writer.rs

package info (click to toggle)
rust-flexi-logger 0.29.8-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,084 kB
  • sloc: makefile: 2
file content (115 lines) | stat: -rw-r--r-- 3,327 bytes parent folder | download
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
mod test_utils;

use flexi_logger::writers::LogWriter;
use flexi_logger::{default_format, DeferredNow, FormatFunction, Logger};
use log::*;
use std::sync::Mutex;

const COUNT: u8 = 2;

#[test]
fn test_custom_log_writer() {
    if let Some(value) = test_utils::dispatch(COUNT) {
        work(value)
    }
}

fn work(value: u8) {
    let mut logger = Logger::try_with_str("info").unwrap();
    match value {
        0 => {
            logger = logger.log_to_writer(Box::new(CustomWriter {
                data: Mutex::new(Vec::new()),
                format: default_format,
                mode: 0,
            }));
        }
        1 => {
            logger = logger.log_to_writer(Box::new(CustomWriter {
                data: Mutex::new(Vec::new()),
                format: default_format,
                mode: 1,
            }));
            logger = logger.format(custom_format);
        }
        COUNT..=u8::MAX => unreachable!("asAS"),
    }
    let handle = logger
        .start()
        .unwrap_or_else(|e| panic!("Logger initialization failed with {e}"));

    error!("This is an error 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!");

    handle.validate_logs(&[
        (
            "ERROR",
            "test_custom_log_writer",
            "This is an error message",
        ),
        ("WARN", "test_custom_log_writer", "This is a warning"),
        ("INFO", "test_custom_log_writer", "This is an info message"),
    ]);
}

pub struct CustomWriter {
    data: Mutex<Vec<u8>>,
    format: FormatFunction,
    mode: u8,
}

impl LogWriter for CustomWriter {
    fn write(&self, now: &mut DeferredNow, record: &Record) -> std::io::Result<()> {
        let mut data = self.data.lock().unwrap();
        (self.format)(&mut *data, now, record)
    }

    fn flush(&self) -> std::io::Result<()> {
        Ok(())
    }

    fn format(&mut self, format: FormatFunction) {
        self.format = format;
    }

    fn max_log_level(&self) -> log::LevelFilter {
        log::LevelFilter::Trace
    }

    fn validate_logs(&self, expected: &[(&'static str, &'static str, &'static str)]) {
        let data = self.data.lock().unwrap();
        let expected_data = match self.mode {
            0 => expected
                .iter()
                .fold(Vec::new(), |mut acc, (level, module, message)| {
                    acc.extend(format!("{level} [{module}] {message}").bytes());
                    acc
                }),
            1 => expected
                .iter()
                .fold(Vec::new(), |mut acc, (level, _module, message)| {
                    acc.extend(format!("{level}: {message}").bytes());
                    acc
                }),
            COUNT..=u8::MAX => {
                unreachable!("sadadsd")
            }
        };
        assert_eq!(
            String::from_utf8_lossy(&data),
            String::from_utf8_lossy(&expected_data)
        );
    }
}

fn custom_format(
    writer: &mut dyn std::io::Write,
    _now: &mut DeferredNow,
    record: &Record,
) -> Result<(), std::io::Error> {
    // Only write the message and the level, without the module
    write!(writer, "{}: {}", record.level(), &record.args())
}