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