add working multi log file example

This commit is contained in:
jb-alvarado 2024-06-03 21:35:02 +02:00
parent 4f7eff53d1
commit e84aa7e4e3

View File

@ -0,0 +1,83 @@
use flexi_logger::writers::{FileLogWriter, LogWriter};
use flexi_logger::{Age, Cleanup, Criterion, DeferredNow, FileSpec, Naming, Record};
use log::{debug, error, info, kv::Value, trace, warn};
use std::collections::HashMap;
use std::io;
use std::sync::{Arc, Mutex};
struct MultiFileLogger {
writers: Arc<Mutex<HashMap<String, Arc<Mutex<FileLogWriter>>>>>,
}
impl MultiFileLogger {
pub fn new() -> Self {
MultiFileLogger {
writers: Arc::new(Mutex::new(HashMap::new())),
}
}
fn get_writer(&self, channel: &str) -> io::Result<Arc<Mutex<FileLogWriter>>> {
let mut writers = self.writers.lock().unwrap();
if !writers.contains_key(channel) {
let writer = FileLogWriter::builder(
FileSpec::default()
.suppress_timestamp()
.basename("ffplayout")
.discriminant(channel),
)
.append()
.rotate(
Criterion::Age(Age::Day),
Naming::Timestamps,
Cleanup::KeepLogFiles(7),
)
.print_message()
.try_build()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
writers.insert(channel.to_string(), Arc::new(Mutex::new(writer)));
}
Ok(writers.get(channel).unwrap().clone())
}
}
impl LogWriter for MultiFileLogger {
fn write(&self, now: &mut DeferredNow, record: &Record) -> io::Result<()> {
let channel = record
.key_values()
.get("channel".into())
.unwrap_or(Value::null())
.to_string();
let writer = self.get_writer(&channel);
let w = writer?.lock().unwrap().write(now, record);
w
}
fn flush(&self) -> io::Result<()> {
let writers = self.writers.lock().unwrap();
for writer in writers.values() {
writer.lock().unwrap().flush()?;
}
Ok(())
}
}
fn main() {
let logger = MultiFileLogger::new();
flexi_logger::Logger::try_with_str("trace")
.expect("LogSpecification String has errors")
.print_message()
.add_writer("file", Box::new(logger))
.log_to_stderr()
.start()
.unwrap();
trace!(target: "{file}", channel = 1; "This is a trace message for file1");
trace!("This is a trace message for console");
debug!(target: "{file}", channel = 2; "This is a debug message for file2");
info!(target:"{file}", channel = 2; "This is an info message for file2");
warn!(target: "{file}", channel = 1; "This is a warning for file1");
error!(target: "{file}", channel = 2; "This is an error message for file2");
info!("This is a info message for console");
}