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}