use crate::service::{ServiceError, StandardWriteMessageFormatter, WriteMessageFormatter};
use crate::{Fallback, LoggerStatus, Message, Service};
use std::any::Any;
use std::sync::Mutex;
pub struct VectorMessage {
pub level: String,
pub message: String,
}
pub struct Vector {
logs: Mutex<Vec<VectorMessage>>,
}
impl Vector {
pub fn new(capacity: usize) -> Box<Self> {
Box::new(Self {
logs: Mutex::new(Vec::with_capacity(capacity)),
})
}
pub fn inspect_vector<R>(&self, f: impl FnOnce(&Vec<VectorMessage>) -> R) -> Option<R> {
self.logs.lock().ok().map(|r| f(&*r))
}
pub fn recover_vector(self) -> Result<Vec<VectorMessage>, ServiceError> {
self.logs
.into_inner()
.map_err(|_| ServiceError::LockPoisoned)
}
}
impl Service for Vector {
fn status(&self) -> LoggerStatus {
LoggerStatus::Running
}
fn work(&self, msg: &Message) -> Result<(), ServiceError> {
let mut logs = self.logs.lock().map_err(|_| ServiceError::LockPoisoned)?;
logs.push(VectorMessage {
level: msg.level().to_string(),
message: msg.content().to_string(),
});
Ok(())
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl Fallback for Vector {
fn fallback(&self, error: &ServiceError, msg: &Message) {
let mut formatter = StandardWriteMessageFormatter::default();
let mut out = std::io::stdout();
let _ = formatter.format_io(msg, &mut out);
let _ = eprintln!("FmtWriteService Error: {}", error);
}
}