postfix-log-parser 0.2.0

高性能模块化Postfix日志解析器,经3.2GB生产数据验证,SMTPD事件100%准确率
Documentation
//! Qmgr队列管理器模块
//!
//! 处理Postfix qmgr队列管理器的事件,包括邮件队列管理、投递调度和状态跟踪

use serde::{Deserialize, Serialize};

/// 队列管理器组件事件
/// 基于1,987万行真实生产数据分析,qmgr组件出现8,554,899次 (43.1%)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum QmgrEvent {
    /// 队列配置警告 - 最常见的qmgr日志类型
    ConfigurationWarning {
        warning_type: String,
        message: String,
    },

    /// 邮件进入活动队列 - 核心业务事件
    MessageActive {
        queue_id: String,
        from: String,
        size: u64,
        nrcpt: u32,
    },

    /// 邮件从队列中移除
    MessageRemoved {
        queue_id: String,
        /// 移除原因(如果有的话)
        reason: Option<String>,
    },

    /// 邮件跳过 - 仍在投递中
    MessageSkipped {
        queue_id: String,
        /// 跳过原因
        reason: String,
        /// 额外状态信息
        status_details: Option<String>,
    },

    /// 延迟投递信息
    /// 包含延迟时间、DSN状态码等详细信息
    MessageDeferred {
        queue_id: String,
        from: String,
        to: Option<String>,
        relay: Option<String>,
        delay: String,
        delays: Option<String>,
        dsn: Option<String>,
        status: String,
    },

    /// 邮件投递成功
    MessageSent {
        queue_id: String,
        from: String,
        to: String,
        relay: String,
        delay: String,
        delays: Option<String>,
        dsn: Option<String>,
        status: String,
    },

    /// 邮件投递失败(退信)
    MessageBounced {
        queue_id: String,
        from: String,
        to: String,
        reason: String,
        dsn: Option<String>,
    },

    /// 队列统计信息
    /// qmgr会定期报告队列状态统计
    QueueStats {
        active: Option<u32>,
        deferred: Option<u32>,
        hold: Option<u32>,
        incoming: Option<u32>,
        maildrop: Option<u32>,
    },

    /// 传输代理状态
    /// 报告各种传输代理的状态
    TransportStatus {
        transport: String,
        status: String,
        details: Option<String>,
    },

    /// 资源限制警告
    /// 当达到或接近资源限制时的警告
    ResourceLimit {
        resource_type: String,
        current_value: Option<u32>,
        limit_value: Option<u32>,
        message: String,
    },

    /// 队列刷新操作
    /// 手动或自动队列刷新事件
    QueueFlush {
        queue_name: Option<String>,
        message_count: Option<u32>,
    },

    /// 其他qmgr相关事件
    /// 用于处理暂时无法分类的qmgr事件
    Other {
        event_type: String,
        message: String,
        queue_id: Option<String>,
    },
}

impl QmgrEvent {
    pub fn event_type(&self) -> &'static str {
        match self {
            QmgrEvent::ConfigurationWarning { .. } => "configuration_warning",
            QmgrEvent::MessageActive { .. } => "message_active",
            QmgrEvent::MessageRemoved { .. } => "message_removed",
            QmgrEvent::MessageSkipped { .. } => "message_skipped",
            QmgrEvent::MessageDeferred { .. } => "message_deferred",
            QmgrEvent::MessageSent { .. } => "message_sent",
            QmgrEvent::MessageBounced { .. } => "message_bounced",
            QmgrEvent::QueueStats { .. } => "queue_stats",
            QmgrEvent::TransportStatus { .. } => "transport_status",
            QmgrEvent::ResourceLimit { .. } => "resource_limit",
            QmgrEvent::QueueFlush { .. } => "queue_flush",
            QmgrEvent::Other { .. } => "other",
        }
    }

    /// 获取队列ID(如果存在)
    pub fn queue_id(&self) -> Option<&str> {
        match self {
            QmgrEvent::MessageActive { queue_id, .. } => Some(queue_id),
            QmgrEvent::MessageRemoved { queue_id, .. } => Some(queue_id),
            QmgrEvent::MessageSkipped { queue_id, .. } => Some(queue_id),
            QmgrEvent::MessageDeferred { queue_id, .. } => Some(queue_id),
            QmgrEvent::MessageSent { queue_id, .. } => Some(queue_id),
            QmgrEvent::MessageBounced { queue_id, .. } => Some(queue_id),
            QmgrEvent::Other { queue_id, .. } => queue_id.as_deref(),
            _ => None,
        }
    }

    /// 检查是否为错误级别事件
    pub fn is_error_event(&self) -> bool {
        matches!(
            self,
            QmgrEvent::MessageBounced { .. } | QmgrEvent::ResourceLimit { .. }
        )
    }

    /// 检查是否为警告级别事件
    pub fn is_warning_event(&self) -> bool {
        matches!(
            self,
            QmgrEvent::ConfigurationWarning { .. } | QmgrEvent::MessageDeferred { .. }
        )
    }
}