use super::LogFormatter;
use crate::events::ComponentEvent;
use crate::parsing::ParseResult;
use serde_json;
use std::error::Error;
pub mod cleanup;
pub mod common;
pub mod discard;
pub mod error;
pub mod postfix_script;
pub mod postsuper;
pub mod qmgr;
pub mod relay;
pub mod smtp;
pub mod smtpd;
pub use cleanup::format_cleanup_event;
pub use common::*;
pub use discard::DiscardJsonFormatter;
pub use error::ErrorJsonFormatter;
pub use postfix_script::format_postfix_script_event;
pub use postsuper::format_postsuper_event;
pub use qmgr::format_qmgr_event;
pub use relay::RelayJsonFormatter;
pub use smtp::format_smtp_event;
pub use smtpd::format_smtpd_event;
pub struct JsonFormatter;
impl JsonFormatter {
pub fn new() -> Self {
Self
}
}
impl LogFormatter for JsonFormatter {
fn format_single(
&self,
line_number: usize,
line: &str,
result: &ParseResult,
) -> Result<String, Box<dyn Error>> {
let mut parsed_data = serde_json::Map::new();
parsed_data.insert(
"line_number".to_string(),
serde_json::Value::Number(serde_json::Number::from(line_number)),
);
parsed_data.insert(
"original_line".to_string(),
serde_json::Value::String(line.to_string()),
);
parsed_data.insert(
"confidence".to_string(),
serde_json::Value::Number(
serde_json::Number::from_f64(result.confidence as f64).unwrap(),
),
);
if let Some(event) = &result.event {
parsed_data.insert(
"timestamp".to_string(),
serde_json::Value::String(event.timestamp.to_rfc3339()),
);
parsed_data.insert(
"hostname".to_string(),
serde_json::Value::String(event.hostname.clone()),
);
parsed_data.insert(
"component".to_string(),
serde_json::Value::String(event.component.clone()),
);
parsed_data.insert(
"process_id".to_string(),
serde_json::Value::Number(serde_json::Number::from(event.process_id)),
);
parsed_data.insert(
"log_level".to_string(),
serde_json::Value::String(format!("{:?}", event.log_level)),
);
if let Some(queue_id) = &event.queue_id {
parsed_data.insert(
"queue_id".to_string(),
serde_json::Value::String(queue_id.clone()),
);
}
match &event.event {
ComponentEvent::Smtpd(smtpd_event) => {
let event_data = format_smtpd_event(smtpd_event);
for (key, value) in event_data {
parsed_data.insert(key, value);
}
}
ComponentEvent::Smtp(smtp_event) => {
let event_data = format_smtp_event(smtp_event);
for (key, value) in event_data {
parsed_data.insert(key, value);
}
}
ComponentEvent::Qmgr(qmgr_event) => {
let event_data = format_qmgr_event(qmgr_event);
for (key, value) in event_data {
parsed_data.insert(key, value);
}
}
ComponentEvent::Cleanup(cleanup_event) => {
let event_data = format_cleanup_event(cleanup_event);
if let serde_json::Value::Object(map) = event_data {
for (key, value) in map {
parsed_data.insert(key, value);
}
}
}
ComponentEvent::Error(error_event) => {
let event_data = ErrorJsonFormatter::format_error_event(error_event);
if let serde_json::Value::Object(map) = event_data {
for (key, value) in map {
parsed_data.insert(key, value);
}
}
}
ComponentEvent::Relay(relay_event) => {
let event_data = RelayJsonFormatter::new().format_event(relay_event);
if let serde_json::Value::Object(map) = event_data {
for (key, value) in map {
parsed_data.insert(key, value);
}
}
}
ComponentEvent::Discard(discard_event) => {
let event_data = DiscardJsonFormatter::new().format_event(discard_event);
if let serde_json::Value::Object(map) = event_data {
for (key, value) in map {
parsed_data.insert(key, value);
}
}
}
ComponentEvent::PostfixScript(postfix_script_event) => {
let event_data = format_postfix_script_event(postfix_script_event);
if let serde_json::Value::Object(map) = event_data {
for (key, value) in map {
parsed_data.insert(key, value);
}
}
}
ComponentEvent::Postsuper(postsuper_event) => {
let event_data = format_postsuper_event(postsuper_event);
if let serde_json::Value::Object(map) = event_data {
for (key, value) in map {
parsed_data.insert(key, value);
}
}
}
ComponentEvent::Unknown(unknown_event) => {
parsed_data.insert(
"event_type".to_string(),
serde_json::Value::String("unknown".to_string()),
);
parsed_data.insert(
"message".to_string(),
serde_json::Value::String(unknown_event.message.clone()),
);
}
_ => {
parsed_data.insert(
"event_type".to_string(),
serde_json::Value::String("other".to_string()),
);
parsed_data.insert(
"message".to_string(),
serde_json::Value::String(format!("{:?}", event.event)),
);
}
}
} else {
parsed_data.insert(
"error".to_string(),
serde_json::Value::String("parse_failed".to_string()),
);
if !result.parsing_errors.is_empty() {
parsed_data.insert(
"error_details".to_string(),
serde_json::Value::String(format!("{:?}", result.parsing_errors[0])),
);
}
}
Ok(serde_json::to_string(&serde_json::Value::Object(
parsed_data,
))?)
}
fn format_multiple(
&self,
results: Vec<(usize, String, ParseResult)>,
) -> Result<String, Box<dyn Error>> {
let mut json_objects = Vec::new();
for (line_number, line, result) in results {
let json_str = self.format_single(line_number, &line, &result)?;
let json_value: serde_json::Value = serde_json::from_str(&json_str)?;
json_objects.push(json_value);
}
let json_array = serde_json::Value::Array(json_objects);
Ok(serde_json::to_string_pretty(&json_array)?)
}
}
impl Default for JsonFormatter {
fn default() -> Self {
Self::new()
}
}