use std::sync::{Arc, Mutex};
use log4rc::{Appender, Layout, LogEvent, LogLevel, Logger};
struct KeyValueLayout;
impl Layout for KeyValueLayout {
fn format(&self, event: &LogEvent) -> String {
format!("level={} message={}", event.level.as_str(), event.message)
}
}
#[derive(Clone)]
struct VecAppender {
layout: Arc<dyn Layout>,
messages: Arc<Mutex<Vec<String>>>,
}
impl VecAppender {
fn new(layout: Arc<dyn Layout>) -> Self {
Self {
layout,
messages: Arc::new(Mutex::new(Vec::new())),
}
}
fn messages(&self) -> Vec<String> {
self.messages.lock().unwrap().clone()
}
}
impl Appender for VecAppender {
fn append(&self, event: &LogEvent) {
self.messages.lock().unwrap().push(self.layout.format(event));
}
}
fn main() {
let collector = VecAppender::new(Arc::new(KeyValueLayout));
Logger::builder(LogLevel::Info)
.appender(Box::new(collector.clone()))
.init();
log4rc::info!("Hello, appender!");
log4rc::debug!("This is filtered out at Info level");
log4rc::error!("Something went wrong");
for line in collector.messages() {
println!("captured: {line}");
}
}