use log::Record;
use log4rs::encode::{Encode, Write};
use serde_json::json;
use crate::NEWLINE;
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct SLSEncoder;
impl SLSEncoder {
pub fn new() -> Self {
SLSEncoder
}
}
impl Default for SLSEncoder {
fn default() -> Self {
Self::new()
}
}
impl Encode for SLSEncoder {
fn encode(&self, w: &mut dyn Write, record: &Record) -> anyhow::Result<()> {
let args_str = record.args().to_string();
if let Ok(value) = serde_json::from_str::<serde_json::Value>(&args_str) {
if let Some(logs) = value.get("__logs__") {
if let Some(log_array) = logs.as_array() {
for log_entry in log_array {
if log_entry.is_object() {
w.write_fmt(format_args!("{}", log_entry))?;
w.write_all(NEWLINE.as_bytes())?;
} else {
return Err(anyhow::anyhow!(
"[SLSEncoder] Invalid log entry in __logs__ array: expected object, got {:?}",
log_entry
));
}
}
return Ok(());
}
}
if value.is_object() {
w.write_fmt(format_args!("{}", value))?;
w.write_all(NEWLINE.as_bytes())?;
return Ok(());
}
}
let log_entry = json!({
"message": record.args(),
});
w.write_fmt(format_args!("{}", log_entry))?;
w.write_all(NEWLINE.as_bytes())?;
Ok(())
}
}