postfix_log_parser/events/
error.rs

1//! ERROR组件事件类型定义
2//!
3//! 基于676万+条真实生产数据分析,ERROR组件占34.0%的日志
4//! 主要处理邮件投递错误和系统故障信息
5
6use serde::{Deserialize, Serialize};
7
8/// ERROR事件类型枚举
9///
10/// 覆盖Postfix error组件的各种错误处理事件
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
12#[serde(tag = "event_type")]
13pub enum ErrorEvent {
14    /// 投递延迟错误 - 最常见的错误类型
15    DeliveryDeferred {
16        queue_id: String,
17        to: String,
18        relay: String,
19        delay: f64,
20        delays: String,
21        dsn: String,
22        status: String,
23        reason: String,
24        error_type: ErrorType,
25    },
26
27    /// 投递永久失败错误
28    DeliveryFailed {
29        queue_id: String,
30        to: String,
31        relay: String,
32        delay: f64,
33        delays: String,
34        dsn: String,
35        status: String,
36        reason: String,
37        error_type: ErrorType,
38    },
39
40    /// 系统配置错误
41    SystemError {
42        queue_id: Option<String>,
43        error_type: ErrorType,
44        message: String,
45    },
46
47    /// 网络连接错误
48    ConnectionError {
49        queue_id: String,
50        to: String,
51        relay: String,
52        delay: f64,
53        delays: String,
54        dsn: String,
55        reason: String,
56        error_type: ErrorType,
57    },
58
59    /// 其他未分类错误
60    Other {
61        queue_id: Option<String>,
62        error_type: String,
63        message: String,
64    },
65}
66
67impl ErrorEvent {
68    /// 获取事件类型描述
69    pub fn event_type(&self) -> &'static str {
70        match self {
71            ErrorEvent::DeliveryDeferred { .. } => "delivery_deferred",
72            ErrorEvent::DeliveryFailed { .. } => "delivery_failed",
73            ErrorEvent::SystemError { .. } => "system_error",
74            ErrorEvent::ConnectionError { .. } => "connection_error",
75            ErrorEvent::Other { .. } => "error_other",
76        }
77    }
78
79    /// 获取队列ID
80    pub fn queue_id(&self) -> Option<&str> {
81        match self {
82            ErrorEvent::DeliveryDeferred { queue_id, .. } => Some(queue_id),
83            ErrorEvent::DeliveryFailed { queue_id, .. } => Some(queue_id),
84            ErrorEvent::SystemError { queue_id, .. } => queue_id.as_deref(),
85            ErrorEvent::ConnectionError { queue_id, .. } => Some(queue_id),
86            ErrorEvent::Other { queue_id, .. } => queue_id.as_deref(),
87        }
88    }
89
90    /// 获取错误严重性级别
91    pub fn severity(&self) -> u8 {
92        match self {
93            ErrorEvent::DeliveryDeferred { error_type, .. } => error_type.severity().level(),
94            ErrorEvent::DeliveryFailed { error_type, .. } => error_type.severity().level() + 1, // 永久失败更严重
95            ErrorEvent::SystemError { error_type, .. } => error_type.severity().level(),
96            ErrorEvent::ConnectionError { error_type, .. } => error_type.severity().level(),
97            ErrorEvent::Other { .. } => 2, // 默认中等严重性
98        }
99    }
100}
101
102/// 错误类型分类
103///
104/// 基于真实数据分析的错误类型分类
105#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
106pub enum ErrorType {
107    /// DNS解析错误 - 最常见
108    #[serde(rename = "dns_resolution")]
109    DnsResolution,
110
111    /// 连接被拒绝
112    #[serde(rename = "connection_refused")]
113    ConnectionRefused,
114
115    /// 连接丢失
116    #[serde(rename = "connection_lost")]
117    ConnectionLost,
118
119    /// 连接超时
120    #[serde(rename = "connection_timeout")]
121    ConnectionTimeout,
122
123    /// 主机不可达
124    #[serde(rename = "host_unreachable")]
125    HostUnreachable,
126
127    /// 邮箱不存在
128    #[serde(rename = "mailbox_not_found")]
129    MailboxNotFound,
130
131    /// 邮箱已满
132    #[serde(rename = "mailbox_full")]
133    MailboxFull,
134
135    /// 认证失败
136    #[serde(rename = "authentication_failed")]
137    AuthenticationFailed,
138
139    /// 速率限制
140    #[serde(rename = "rate_limited")]
141    RateLimited,
142
143    /// 垃圾邮件拒绝
144    #[serde(rename = "spam_rejected")]
145    SpamRejected,
146
147    /// 策略拒绝
148    #[serde(rename = "policy_rejected")]
149    PolicyRejected,
150
151    /// 系统配置错误
152    #[serde(rename = "system_config")]
153    SystemConfig,
154
155    /// 资源不足
156    #[serde(rename = "resource_shortage")]
157    ResourceShortage,
158
159    /// 协议错误
160    #[serde(rename = "protocol_error")]
161    ProtocolError,
162
163    /// TLS/SSL错误
164    #[serde(rename = "tls_error")]
165    TlsError,
166
167    /// 其他未分类错误
168    #[serde(rename = "other")]
169    Other,
170}
171
172impl ErrorType {
173    /// 从错误原因字符串推断错误类型
174    pub fn from_reason(reason: &str) -> Self {
175        let reason_lower = reason.to_lowercase();
176
177        if reason_lower.contains("host or domain name not found")
178            || reason_lower.contains("name service error")
179            || reason_lower.contains("host not found")
180        {
181            Self::DnsResolution
182        } else if reason_lower.contains("connection refused") {
183            Self::ConnectionRefused
184        } else if reason_lower.contains("lost connection") {
185            Self::ConnectionLost
186        } else if reason_lower.contains("connection timed out") || reason_lower.contains("timeout")
187        {
188            Self::ConnectionTimeout
189        } else if reason_lower.contains("host unreachable")
190            || reason_lower.contains("network unreachable")
191        {
192            Self::HostUnreachable
193        } else if reason_lower.contains("user unknown")
194            || reason_lower.contains("recipient address rejected")
195            || reason_lower.contains("mailbox unavailable")
196        {
197            Self::MailboxNotFound
198        } else if reason_lower.contains("mailbox full")
199            || reason_lower.contains("quota exceeded")
200            || reason_lower.contains("insufficient storage")
201        {
202            Self::MailboxFull
203        } else if reason_lower.contains("authentication") || reason_lower.contains("auth") {
204            Self::AuthenticationFailed
205        } else if reason_lower.contains("rate limit")
206            || reason_lower.contains("too many")
207            || reason_lower.contains("throttl")
208        {
209            Self::RateLimited
210        } else if reason_lower.contains("spam")
211            || reason_lower.contains("blacklist")
212            || reason_lower.contains("blocked")
213        {
214            Self::SpamRejected
215        } else if reason_lower.contains("policy") || reason_lower.contains("rejected") {
216            Self::PolicyRejected
217        } else if reason_lower.contains("tls")
218            || reason_lower.contains("ssl")
219            || reason_lower.contains("certificate")
220        {
221            Self::TlsError
222        } else if reason_lower.contains("protocol") {
223            Self::ProtocolError
224        } else if reason_lower.contains("config") || reason_lower.contains("permission") {
225            Self::SystemConfig
226        } else if reason_lower.contains("resource")
227            || reason_lower.contains("memory")
228            || reason_lower.contains("disk")
229        {
230            Self::ResourceShortage
231        } else {
232            Self::Other
233        }
234    }
235
236    /// 获取错误类型的描述
237    pub fn description(&self) -> &'static str {
238        match self {
239            Self::DnsResolution => "DNS解析错误",
240            Self::ConnectionRefused => "连接被拒绝",
241            Self::ConnectionLost => "连接丢失",
242            Self::ConnectionTimeout => "连接超时",
243            Self::HostUnreachable => "主机不可达",
244            Self::MailboxNotFound => "邮箱不存在",
245            Self::MailboxFull => "邮箱已满",
246            Self::AuthenticationFailed => "认证失败",
247            Self::RateLimited => "速率限制",
248            Self::SpamRejected => "垃圾邮件拒绝",
249            Self::PolicyRejected => "策略拒绝",
250            Self::SystemConfig => "系统配置错误",
251            Self::ResourceShortage => "资源不足",
252            Self::ProtocolError => "协议错误",
253            Self::TlsError => "TLS/SSL错误",
254            Self::Other => "其他错误",
255        }
256    }
257
258    /// 获取错误严重性级别
259    pub fn severity(&self) -> ErrorSeverity {
260        match self {
261            Self::DnsResolution | Self::ConnectionTimeout | Self::ConnectionLost => {
262                ErrorSeverity::Temporary
263            }
264            Self::ConnectionRefused | Self::HostUnreachable => ErrorSeverity::Network,
265            Self::MailboxNotFound | Self::MailboxFull => ErrorSeverity::RecipientIssue,
266            Self::AuthenticationFailed | Self::PolicyRejected | Self::SpamRejected => {
267                ErrorSeverity::PolicyIssue
268            }
269            Self::SystemConfig | Self::ResourceShortage => ErrorSeverity::SystemIssue,
270            Self::TlsError | Self::ProtocolError => ErrorSeverity::ProtocolIssue,
271            Self::RateLimited => ErrorSeverity::Temporary,
272            Self::Other => ErrorSeverity::Unknown,
273        }
274    }
275}
276
277/// 错误严重性级别
278#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
279pub enum ErrorSeverity {
280    /// 临时性错误,可重试
281    #[serde(rename = "temporary")]
282    Temporary,
283
284    /// 网络相关错误
285    #[serde(rename = "network")]
286    Network,
287
288    /// 收件人相关问题
289    #[serde(rename = "recipient_issue")]
290    RecipientIssue,
291
292    /// 策略或安全问题
293    #[serde(rename = "policy_issue")]
294    PolicyIssue,
295
296    /// 系统问题
297    #[serde(rename = "system_issue")]
298    SystemIssue,
299
300    /// 协议问题
301    #[serde(rename = "protocol_issue")]
302    ProtocolIssue,
303
304    /// 未知错误
305    #[serde(rename = "unknown")]
306    Unknown,
307}
308
309impl ErrorSeverity {
310    /// 获取严重性级别的数值表示 (1-5)
311    pub fn level(&self) -> u8 {
312        match self {
313            Self::Temporary => 1,
314            Self::Network => 2,
315            Self::RecipientIssue => 3,
316            Self::PolicyIssue => 3,
317            Self::ProtocolIssue => 4,
318            Self::SystemIssue => 5,
319            Self::Unknown => 2,
320        }
321    }
322
323    /// 获取严重性级别的描述
324    pub fn description(&self) -> &'static str {
325        match self {
326            Self::Temporary => "临时性错误,通常可重试",
327            Self::Network => "网络连接问题",
328            Self::RecipientIssue => "收件人相关问题",
329            Self::PolicyIssue => "策略或安全问题",
330            Self::ProtocolIssue => "协议层面问题",
331            Self::SystemIssue => "系统级别问题",
332            Self::Unknown => "未知类型错误",
333        }
334    }
335}