05_sink/
05-sink.rs

1use std::sync::{Arc, Mutex};
2
3use spdlog::{
4    formatter::FormatterContext,
5    prelude::*,
6    sink::{GetSinkProp, Sink, SinkProp},
7    Record, StringBuf,
8};
9
10struct CollectVecSink {
11    prop: SinkProp,
12    collected: Mutex<Vec<String>>,
13}
14
15impl CollectVecSink {
16    fn new() -> Self {
17        Self {
18            prop: SinkProp::default(),
19            collected: Mutex::new(Vec::new()),
20        }
21    }
22
23    fn collected(&self) -> Vec<String> {
24        self.collected.lock().unwrap().clone()
25    }
26}
27
28impl GetSinkProp for CollectVecSink {
29    fn prop(&self) -> &SinkProp {
30        &self.prop
31    }
32}
33
34impl Sink for CollectVecSink {
35    fn log(&self, record: &Record) -> spdlog::Result<()> {
36        let mut string_buf = StringBuf::new();
37        let mut ctx = FormatterContext::new();
38        self.prop
39            .formatter()
40            .format(record, &mut string_buf, &mut ctx)?;
41        self.collected.lock().unwrap().push(string_buf.to_string());
42        Ok(())
43    }
44
45    fn flush(&self) -> spdlog::Result<()> {
46        Ok(())
47    }
48}
49
50fn main() -> Result<(), Box<dyn std::error::Error>> {
51    let my_sink = Arc::new(CollectVecSink::new());
52    let example = Logger::builder().sink(my_sink.clone()).build()?;
53
54    info!(logger: example, "Hello, world!");
55    warn!(logger: example, "Meow~");
56
57    let collected = my_sink.collected();
58    println!("collected:\n{collected:#?}");
59
60    assert_eq!(collected.len(), 2);
61    assert!(collected[0].contains("[info]") && collected[0].contains("Hello, world!"));
62    assert!(collected[1].contains("[warn]") && collected[1].contains("Meow~"));
63
64    Ok(())
65}