postfix_log_parser/events/
local.rs

1//! Local本地投递模块
2//!
3//! 处理Postfix local投递代理的事件,包括本地邮箱投递、外部命令执行和配置警告
4
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9/// 本地投递组件事件
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub enum LocalEvent {
12    ConfigurationWarning(ConfigurationWarning),
13    LocalDelivery(LocalDelivery),
14    ExternalDelivery(ExternalDelivery),
15}
16
17/// 本地投递配置警告
18///
19/// 记录本地投递组件的配置问题和警告信息
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct ConfigurationWarning {
22    /// 警告发生时间戳(UTC时间)
23    pub timestamp: DateTime<Utc>,
24
25    /// 警告类型分类
26    /// 按照问题的性质进行分类,如NIS域、别名、权限等
27    pub warning_type: WarningType,
28
29    /// 警告消息内容
30    /// 具体的警告描述信息
31    pub message: String,
32
33    /// 附加详细信息
34    /// 包含与警告相关的额外上下文信息
35    pub details: HashMap<String, String>,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
39pub enum WarningType {
40    NisDomainNotSet,
41    RequiredAliasNotFound,
42    FilePermission,
43    Configuration,
44    Other,
45}
46
47/// 本地投递事件
48///
49/// 记录邮件到本地邮箱的投递过程和结果
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct LocalDelivery {
52    /// 投递发生时间戳(UTC时间)
53    pub timestamp: DateTime<Utc>,
54
55    /// 队列ID(邮件在系统中的唯一标识符)
56    pub queue_id: String,
57
58    /// 最终收件人地址
59    /// 经过别名解析后的实际投递地址
60    pub recipient: String,
61
62    /// 原始收件人地址(如果有别名转换)
63    /// 邮件最初的目标地址,在别名解析前
64    pub original_recipient: Option<String>,
65
66    /// 中继信息
67    /// 通常为"local"表示本地投递
68    pub relay: String,
69
70    /// 总投递延迟时间(秒)
71    /// 从邮件接收到投递完成的总时间
72    pub delay: f64,
73
74    /// 延迟时间细分(各阶段用时)
75    /// 详细的时间分解,包含队列等待、处理等各阶段
76    pub delays: Vec<f64>,
77
78    /// 投递状态码(DSN格式)
79    /// 符合RFC 3463标准的状态码
80    pub dsn: String,
81
82    /// 投递状态结果
83    pub status: DeliveryStatus,
84
85    /// 投递方法类型
86    pub delivery_method: DeliveryMethod,
87
88    /// 邮件大小(字节数,可选)
89    pub size: Option<u64>,
90
91    /// 收件人数量(可选)
92    pub nrcpt: Option<u32>,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
96pub enum DeliveryStatus {
97    Sent,
98    Bounced,
99    Deferred,
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
103pub enum DeliveryMethod {
104    Mailbox,
105    Discarded,
106    Forwarded,
107    Piped,
108    File,
109}
110
111/// 外部投递事件
112///
113/// 记录通过外部命令或文件进行的邮件投递
114#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct ExternalDelivery {
116    /// 投递发生时间戳(UTC时间)
117    pub timestamp: DateTime<Utc>,
118
119    /// 队列ID(邮件在系统中的唯一标识符)
120    pub queue_id: String,
121
122    /// 收件人地址
123    pub recipient: String,
124
125    /// 原始收件人地址(如果有转换)
126    /// 在别名或转发规则应用前的原始地址
127    pub original_recipient: Option<String>,
128
129    /// 执行的外部命令(如果适用)
130    /// 用于投递邮件的外部程序或脚本
131    pub command: Option<String>,
132
133    /// 投递的文件路径(如果适用)
134    /// 邮件投递到的文件系统路径
135    pub file_path: Option<String>,
136
137    /// 投递状态结果
138    pub status: DeliveryStatus,
139
140    /// 投递延迟时间(秒)
141    /// 从开始投递到完成的耗时
142    pub delay: f64,
143
144    /// 附加详细信息
145    /// 包含投递过程中的额外信息和元数据
146    pub details: HashMap<String, String>,
147}
148
149impl LocalEvent {
150    pub fn timestamp(&self) -> DateTime<Utc> {
151        match self {
152            LocalEvent::ConfigurationWarning(event) => event.timestamp,
153            LocalEvent::LocalDelivery(event) => event.timestamp,
154            LocalEvent::ExternalDelivery(event) => event.timestamp,
155        }
156    }
157
158    pub fn event_type(&self) -> &'static str {
159        match self {
160            LocalEvent::ConfigurationWarning(_) => "configuration_warning",
161            LocalEvent::LocalDelivery(_) => "local_delivery",
162            LocalEvent::ExternalDelivery(_) => "external_delivery",
163        }
164    }
165}
166
167impl WarningType {
168    pub fn as_str(&self) -> &'static str {
169        match self {
170            WarningType::NisDomainNotSet => "nis_domain_not_set",
171            WarningType::RequiredAliasNotFound => "required_alias_not_found",
172            WarningType::FilePermission => "file_permission",
173            WarningType::Configuration => "configuration",
174            WarningType::Other => "other",
175        }
176    }
177}
178
179impl DeliveryStatus {
180    pub fn as_str(&self) -> &'static str {
181        match self {
182            DeliveryStatus::Sent => "sent",
183            DeliveryStatus::Bounced => "bounced",
184            DeliveryStatus::Deferred => "deferred",
185        }
186    }
187}
188
189impl DeliveryMethod {
190    pub fn as_str(&self) -> &'static str {
191        match self {
192            DeliveryMethod::Mailbox => "mailbox",
193            DeliveryMethod::Discarded => "discarded",
194            DeliveryMethod::Forwarded => "forwarded",
195            DeliveryMethod::Piped => "piped",
196            DeliveryMethod::File => "file",
197        }
198    }
199}