postfix_log_parser/formatters/json/
mod.rs1use super::LogFormatter;
2use crate::events::ComponentEvent;
3use crate::parsing::ParseResult;
4use serde_json;
5use std::error::Error;
6
7pub mod cleanup;
8pub mod common;
9pub mod discard;
10pub mod error;
11pub mod qmgr;
12pub mod relay;
13pub mod smtp;
14pub mod smtpd;
15
16pub use cleanup::format_cleanup_event;
17pub use common::*;
18pub use discard::DiscardJsonFormatter;
19pub use error::ErrorJsonFormatter;
20pub use qmgr::format_qmgr_event;
21pub use relay::RelayJsonFormatter;
22pub use smtp::format_smtp_event;
23pub use smtpd::format_smtpd_event;
24
25pub struct JsonFormatter;
27
28impl JsonFormatter {
29 pub fn new() -> Self {
30 Self
31 }
32}
33
34impl LogFormatter for JsonFormatter {
35 fn format_single(
36 &self,
37 line_number: usize,
38 line: &str,
39 result: &ParseResult,
40 ) -> Result<String, Box<dyn Error>> {
41 let mut parsed_data = serde_json::Map::new();
42
43 parsed_data.insert(
45 "line_number".to_string(),
46 serde_json::Value::Number(serde_json::Number::from(line_number)),
47 );
48 parsed_data.insert(
49 "original_line".to_string(),
50 serde_json::Value::String(line.to_string()),
51 );
52 parsed_data.insert(
53 "confidence".to_string(),
54 serde_json::Value::Number(
55 serde_json::Number::from_f64(result.confidence as f64).unwrap(),
56 ),
57 );
58
59 if let Some(event) = &result.event {
60 parsed_data.insert(
62 "timestamp".to_string(),
63 serde_json::Value::String(event.timestamp.to_rfc3339()),
64 );
65 parsed_data.insert(
66 "hostname".to_string(),
67 serde_json::Value::String(event.hostname.clone()),
68 );
69 parsed_data.insert(
70 "component".to_string(),
71 serde_json::Value::String(event.component.clone()),
72 );
73 parsed_data.insert(
74 "process_id".to_string(),
75 serde_json::Value::Number(serde_json::Number::from(event.process_id)),
76 );
77 parsed_data.insert(
78 "log_level".to_string(),
79 serde_json::Value::String(format!("{:?}", event.log_level)),
80 );
81
82 if let Some(queue_id) = &event.queue_id {
83 parsed_data.insert(
84 "queue_id".to_string(),
85 serde_json::Value::String(queue_id.clone()),
86 );
87 }
88
89 match &event.event {
91 ComponentEvent::Smtpd(smtpd_event) => {
92 let event_data = format_smtpd_event(smtpd_event);
93 for (key, value) in event_data {
94 parsed_data.insert(key, value);
95 }
96 }
97 ComponentEvent::Smtp(smtp_event) => {
98 let event_data = format_smtp_event(smtp_event);
99 for (key, value) in event_data {
100 parsed_data.insert(key, value);
101 }
102 }
103 ComponentEvent::Qmgr(qmgr_event) => {
104 let event_data = format_qmgr_event(qmgr_event);
105 for (key, value) in event_data {
106 parsed_data.insert(key, value);
107 }
108 }
109 ComponentEvent::Cleanup(cleanup_event) => {
110 let event_data = format_cleanup_event(cleanup_event);
111 if let serde_json::Value::Object(map) = event_data {
112 for (key, value) in map {
113 parsed_data.insert(key, value);
114 }
115 }
116 }
117 ComponentEvent::Error(error_event) => {
118 let event_data = ErrorJsonFormatter::format_error_event(error_event);
119 if let serde_json::Value::Object(map) = event_data {
120 for (key, value) in map {
121 parsed_data.insert(key, value);
122 }
123 }
124 }
125 ComponentEvent::Relay(relay_event) => {
126 let event_data = RelayJsonFormatter::new().format_event(relay_event);
127 if let serde_json::Value::Object(map) = event_data {
128 for (key, value) in map {
129 parsed_data.insert(key, value);
130 }
131 }
132 }
133 ComponentEvent::Discard(discard_event) => {
134 let event_data = DiscardJsonFormatter::new().format_event(discard_event);
135 if let serde_json::Value::Object(map) = event_data {
136 for (key, value) in map {
137 parsed_data.insert(key, value);
138 }
139 }
140 }
141 ComponentEvent::Unknown(unknown_event) => {
142 parsed_data.insert(
143 "event_type".to_string(),
144 serde_json::Value::String("unknown".to_string()),
145 );
146 parsed_data.insert(
147 "message".to_string(),
148 serde_json::Value::String(unknown_event.message.clone()),
149 );
150 }
151 _ => {
152 parsed_data.insert(
153 "event_type".to_string(),
154 serde_json::Value::String("other".to_string()),
155 );
156 parsed_data.insert(
157 "message".to_string(),
158 serde_json::Value::String(format!("{:?}", event.event)),
159 );
160 }
161 }
162 } else {
163 parsed_data.insert(
165 "error".to_string(),
166 serde_json::Value::String("parse_failed".to_string()),
167 );
168 if !result.parsing_errors.is_empty() {
169 parsed_data.insert(
170 "error_details".to_string(),
171 serde_json::Value::String(format!("{:?}", result.parsing_errors[0])),
172 );
173 }
174 }
175
176 Ok(serde_json::to_string(&serde_json::Value::Object(
177 parsed_data,
178 ))?)
179 }
180
181 fn format_multiple(
182 &self,
183 results: Vec<(usize, String, ParseResult)>,
184 ) -> Result<String, Box<dyn Error>> {
185 let mut json_objects = Vec::new();
186
187 for (line_number, line, result) in results {
188 let json_str = self.format_single(line_number, &line, &result)?;
189 let json_value: serde_json::Value = serde_json::from_str(&json_str)?;
190 json_objects.push(json_value);
191 }
192
193 let json_array = serde_json::Value::Array(json_objects);
194 Ok(serde_json::to_string_pretty(&json_array)?)
195 }
196}