postfix_log_parser/events/
base.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use super::{
5 anvil::AnvilEvent, bounce::BounceEvent, discard::DiscardEvent, master::MasterEvent,
6 pickup::PickupEvent, postfix_script::PostfixScriptEvent, postmap::PostmapEvent,
7 relay::RelayEvent, trivial_rewrite::TrivialRewriteEvent, CleanupEvent, ErrorEvent, LocalEvent,
8 QmgrEvent, SmtpEvent, SmtpdEvent, VirtualEvent,
9};
10
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
14pub struct BaseEvent {
15 pub timestamp: DateTime<Utc>,
17 pub hostname: String,
19 pub component: String,
21 pub process_id: u32,
23 pub log_level: PostfixLogLevel,
25 pub raw_message: String,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct PostfixLogEvent {
34 pub raw_log: String,
38
39 pub timestamp: DateTime<Utc>,
43
44 pub hostname: String,
48
49 pub component: String,
53
54 pub process_id: u32,
58
59 pub log_level: PostfixLogLevel,
63
64 pub event: ComponentEvent,
68
69 pub queue_id: Option<String>,
73}
74
75impl PostfixLogEvent {
76 pub fn new(
78 raw_log: String,
79 timestamp: DateTime<Utc>,
80 hostname: String,
81 component: String,
82 process_id: u32,
83 log_level: PostfixLogLevel,
84 event: ComponentEvent,
85 queue_id: Option<String>,
86 ) -> Self {
87 Self {
88 raw_log,
89 timestamp,
90 hostname,
91 component,
92 process_id,
93 log_level,
94 event,
95 queue_id,
96 }
97 }
98
99 pub fn event_type(&self) -> &'static str {
101 self.event.event_type()
102 }
103
104 pub fn is_error_level(&self) -> bool {
106 self.log_level.is_error_level()
107 }
108
109 pub fn is_warning_level(&self) -> bool {
111 self.log_level.is_warning_level()
112 }
113
114 pub fn is_debug_level(&self) -> bool {
116 self.log_level.is_debug_level()
117 }
118
119 pub fn severity_level(&self) -> u8 {
121 self.log_level.severity_level()
122 }
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
129pub enum ComponentEvent {
130 Smtpd(SmtpdEvent),
132 Qmgr(QmgrEvent),
134 Smtp(SmtpEvent),
136 Cleanup(CleanupEvent),
138 Error(ErrorEvent),
140 Relay(RelayEvent),
142 Discard(DiscardEvent),
144 Bounce(BounceEvent),
146 PostfixScript(PostfixScriptEvent),
148 Master(MasterEvent),
150 Local(LocalEvent),
152 Pickup(PickupEvent),
154 Postmap(PostmapEvent),
156 Anvil(AnvilEvent),
158 TrivialRewrite(TrivialRewriteEvent),
160 Virtual(VirtualEvent),
162 Postlogd(crate::events::postlogd::PostlogdEvent),
164 Proxymap(crate::events::proxymap::ProxymapEvent),
166 Sendmail(crate::events::sendmail::SendmailEvent),
167 Unknown(UnknownEvent),
169}
170
171impl ComponentEvent {
172 pub fn event_type(&self) -> &'static str {
174 match self {
175 ComponentEvent::Smtpd(event) => event.event_type(),
176 ComponentEvent::Qmgr(event) => event.event_type(),
177 ComponentEvent::Smtp(event) => event.event_type(),
178 ComponentEvent::Cleanup(event) => event.event_type(),
179 ComponentEvent::Error(event) => event.event_type(),
180 ComponentEvent::Relay(_) => "relay",
181 ComponentEvent::Discard(_) => "discard",
182 ComponentEvent::Bounce(event) => event.event_type(),
183 ComponentEvent::PostfixScript(_) => "postfix-script",
184 ComponentEvent::Master(event) => event.event_type(),
185 ComponentEvent::Local(event) => event.event_type(),
186 ComponentEvent::Pickup(_) => "pickup",
187 ComponentEvent::Postmap(_) => "postmap",
188 ComponentEvent::Anvil(_) => "anvil",
189 ComponentEvent::TrivialRewrite(_) => "trivial-rewrite",
190 ComponentEvent::Virtual(event) => event.event_type(),
191 ComponentEvent::Postlogd(_) => "postlogd",
192 ComponentEvent::Proxymap(_) => "proxymap",
193 ComponentEvent::Sendmail(_) => "sendmail",
194 ComponentEvent::Unknown(_) => "unknown",
195 }
196 }
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize)]
202pub struct UnknownEvent {
203 pub component: String,
205 pub message: String,
207}
208
209#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
212pub enum PostfixLogLevel {
213 Debug,
215 Info,
217 Warning,
219 Error,
221 Fatal,
223 Panic,
225}
226
227impl PostfixLogLevel {
228 pub fn severity_level(&self) -> u8 {
230 match self {
231 PostfixLogLevel::Debug => 1,
232 PostfixLogLevel::Info => 2,
233 PostfixLogLevel::Warning => 3,
234 PostfixLogLevel::Error => 4,
235 PostfixLogLevel::Fatal => 5,
236 PostfixLogLevel::Panic => 6,
237 }
238 }
239
240 pub fn is_error_level(&self) -> bool {
242 matches!(
243 self,
244 PostfixLogLevel::Error | PostfixLogLevel::Fatal | PostfixLogLevel::Panic
245 )
246 }
247
248 pub fn is_warning_level(&self) -> bool {
250 matches!(self, PostfixLogLevel::Warning)
251 }
252
253 pub fn is_debug_level(&self) -> bool {
255 matches!(self, PostfixLogLevel::Debug)
256 }
257
258 pub fn as_str(&self) -> &'static str {
260 match self {
261 PostfixLogLevel::Debug => "debug",
262 PostfixLogLevel::Info => "info",
263 PostfixLogLevel::Warning => "warning",
264 PostfixLogLevel::Error => "error",
265 PostfixLogLevel::Fatal => "fatal",
266 PostfixLogLevel::Panic => "panic",
267 }
268 }
269
270 pub fn from_prefix(prefix: &str) -> Option<Self> {
272 match prefix.to_lowercase().as_str() {
273 "debug:" => Some(PostfixLogLevel::Debug),
274 "warning:" => Some(PostfixLogLevel::Warning),
275 "error:" => Some(PostfixLogLevel::Error),
276 "fatal:" => Some(PostfixLogLevel::Fatal),
277 "panic:" => Some(PostfixLogLevel::Panic),
278 _ => None,
279 }
280 }
281}
282
283impl Default for PostfixLogLevel {
284 fn default() -> Self {
286 PostfixLogLevel::Info
287 }
288}
289
290impl std::fmt::Display for PostfixLogLevel {
291 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
292 write!(f, "{}", self.as_str())
293 }
294}