postfix-log-parser 0.2.0

高性能模块化Postfix日志解析器,经3.2GB生产数据验证,SMTPD事件100%准确率
Documentation
use crate::events::SmtpdEvent;
use serde_json;

/// 将SMTPD事件转换为JSON对象
pub fn format_smtpd_event(smtpd_event: &SmtpdEvent) -> serde_json::Map<String, serde_json::Value> {
    let mut event_data = serde_json::Map::new();

    match smtpd_event {
        SmtpdEvent::Connect {
            client_ip,
            client_hostname,
            port,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("connect".to_string()),
            );
            event_data.insert(
                "client_ip".to_string(),
                serde_json::Value::String(client_ip.clone()),
            );
            event_data.insert(
                "client_hostname".to_string(),
                serde_json::Value::String(client_hostname.clone()),
            );
            if let Some(port_num) = port {
                event_data.insert(
                    "port".to_string(),
                    serde_json::Value::Number(serde_json::Number::from(*port_num)),
                );
            }
        }
        SmtpdEvent::Disconnect {
            client_ip,
            client_hostname,
            port,
            command_stats,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("disconnect".to_string()),
            );
            event_data.insert(
                "client_ip".to_string(),
                serde_json::Value::String(client_ip.clone()),
            );
            event_data.insert(
                "client_hostname".to_string(),
                serde_json::Value::String(client_hostname.clone()),
            );
            if let Some(port_num) = port {
                event_data.insert(
                    "port".to_string(),
                    serde_json::Value::Number(serde_json::Number::from(*port_num)),
                );
            }
            if let Some(stats) = command_stats {
                let mut stats_obj = serde_json::Map::new();
                if let Some(ehlo) = stats.ehlo {
                    stats_obj.insert(
                        "ehlo".to_string(),
                        serde_json::Value::Number(serde_json::Number::from(ehlo)),
                    );
                }
                if let Some(mail) = stats.mail {
                    stats_obj.insert(
                        "mail".to_string(),
                        serde_json::Value::Number(serde_json::Number::from(mail)),
                    );
                }
                if let Some(rcpt) = stats.rcpt {
                    stats_obj.insert(
                        "rcpt".to_string(),
                        serde_json::Value::Number(serde_json::Number::from(rcpt)),
                    );
                }
                if let Some(commands) = stats.commands {
                    stats_obj.insert(
                        "commands".to_string(),
                        serde_json::Value::Number(serde_json::Number::from(commands)),
                    );
                }
                event_data.insert(
                    "command_stats".to_string(),
                    serde_json::Value::Object(stats_obj),
                );
            }
        }
        SmtpdEvent::ClientAssignment {
            queue_id,
            client_ip,
            client_hostname,
            port,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("client_assignment".to_string()),
            );
            event_data.insert(
                "queue_id".to_string(),
                serde_json::Value::String(queue_id.clone()),
            );
            event_data.insert(
                "client_ip".to_string(),
                serde_json::Value::String(client_ip.clone()),
            );
            event_data.insert(
                "client_hostname".to_string(),
                serde_json::Value::String(client_hostname.clone()),
            );
            if let Some(port_num) = port {
                event_data.insert(
                    "port".to_string(),
                    serde_json::Value::Number(serde_json::Number::from(*port_num)),
                );
            }
        }
        SmtpdEvent::LostConnection {
            client_ip,
            client_hostname,
            last_command,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("lost_connection".to_string()),
            );
            event_data.insert(
                "client_ip".to_string(),
                serde_json::Value::String(client_ip.clone()),
            );
            event_data.insert(
                "client_hostname".to_string(),
                serde_json::Value::String(client_hostname.clone()),
            );
            if let Some(cmd) = last_command {
                event_data.insert(
                    "last_command".to_string(),
                    serde_json::Value::String(cmd.clone()),
                );
            }
        }
        SmtpdEvent::Timeout {
            client_ip,
            client_hostname,
            last_command,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("timeout".to_string()),
            );
            event_data.insert(
                "client_ip".to_string(),
                serde_json::Value::String(client_ip.clone()),
            );
            event_data.insert(
                "client_hostname".to_string(),
                serde_json::Value::String(client_hostname.clone()),
            );
            if let Some(cmd) = last_command {
                event_data.insert(
                    "last_command".to_string(),
                    serde_json::Value::String(cmd.clone()),
                );
            }
        }
        SmtpdEvent::NoQueueFilter {
            client_ip,
            client_hostname,
            filter_info,
            filter_target,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("noqueue_filter".to_string()),
            );
            event_data.insert(
                "client_ip".to_string(),
                serde_json::Value::String(client_ip.clone()),
            );
            event_data.insert(
                "client_hostname".to_string(),
                serde_json::Value::String(client_hostname.clone()),
            );
            event_data.insert(
                "filter_info".to_string(),
                serde_json::Value::String(filter_info.clone()),
            );
            event_data.insert(
                "filter_target".to_string(),
                serde_json::Value::String(filter_target.clone()),
            );
        }
        SmtpdEvent::SystemWarning {
            warning_type,
            message,
            client_info: _,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("system_warning".to_string()),
            );
            event_data.insert(
                "warning_type".to_string(),
                serde_json::Value::String(warning_type.clone()),
            );
            event_data.insert(
                "message".to_string(),
                serde_json::Value::String(message.clone()),
            );
        }
        SmtpdEvent::Reject {
            reason,
            code,
            reject_type,
            from,
            to,
            client_ip,
            client_hostname,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("reject".to_string()),
            );
            event_data.insert(
                "reason".to_string(),
                serde_json::Value::String(reason.clone()),
            );
            event_data.insert(
                "reject_type".to_string(),
                serde_json::Value::String(format!("{:?}", reject_type)),
            );
            if let Some(code_num) = code {
                event_data.insert(
                    "code".to_string(),
                    serde_json::Value::Number(serde_json::Number::from(*code_num)),
                );
            }
            if let Some(from_addr) = from {
                event_data.insert(
                    "from".to_string(),
                    serde_json::Value::String(from_addr.clone()),
                );
            }
            if let Some(to_addr) = to {
                event_data.insert("to".to_string(), serde_json::Value::String(to_addr.clone()));
            }
            if let Some(ip) = client_ip {
                event_data.insert(
                    "client_ip".to_string(),
                    serde_json::Value::String(ip.clone()),
                );
            }
            if let Some(hostname) = client_hostname {
                event_data.insert(
                    "client_hostname".to_string(),
                    serde_json::Value::String(hostname.clone()),
                );
            }
        }
        SmtpdEvent::Helo {
            hostname,
            client_ip,
            client_hostname,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("helo".to_string()),
            );
            event_data.insert(
                "helo_hostname".to_string(),
                serde_json::Value::String(hostname.clone()),
            );
            if let Some(ip) = client_ip {
                event_data.insert(
                    "client_ip".to_string(),
                    serde_json::Value::String(ip.clone()),
                );
            }
            if let Some(hostname) = client_hostname {
                event_data.insert(
                    "client_hostname".to_string(),
                    serde_json::Value::String(hostname.clone()),
                );
            }
        }
        SmtpdEvent::Auth {
            method,
            username,
            success,
            failure_reason,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("auth".to_string()),
            );
            event_data.insert(
                "auth_method".to_string(),
                serde_json::Value::String(method.clone()),
            );
            event_data.insert(
                "username".to_string(),
                serde_json::Value::String(username.clone()),
            );
            event_data.insert("success".to_string(), serde_json::Value::Bool(*success));
            if let Some(reason) = failure_reason {
                event_data.insert(
                    "failure_reason".to_string(),
                    serde_json::Value::String(reason.clone()),
                );
            }
        }
        SmtpdEvent::Accept {
            from,
            to,
            size,
            queue_id,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("accept".to_string()),
            );
            if let Some(from_addr) = from {
                event_data.insert(
                    "from".to_string(),
                    serde_json::Value::String(from_addr.clone()),
                );
            }
            if !to.is_empty() {
                let to_array: Vec<serde_json::Value> = to
                    .iter()
                    .map(|addr| serde_json::Value::String(addr.clone()))
                    .collect();
                event_data.insert("to".to_string(), serde_json::Value::Array(to_array));
            }
            if let Some(message_size) = size {
                event_data.insert(
                    "size".to_string(),
                    serde_json::Value::Number(serde_json::Number::from(*message_size)),
                );
            }
            if let Some(qid) = queue_id {
                event_data.insert(
                    "queue_id".to_string(),
                    serde_json::Value::String(qid.clone()),
                );
            }
        }
        SmtpdEvent::ProtocolViolation {
            client_ip,
            client_hostname,
            violation_type,
            details,
        } => {
            event_data.insert(
                "event_type".to_string(),
                serde_json::Value::String("protocol_violation".to_string()),
            );
            event_data.insert(
                "client_ip".to_string(),
                serde_json::Value::String(client_ip.clone()),
            );
            event_data.insert(
                "client_hostname".to_string(),
                serde_json::Value::String(client_hostname.clone()),
            );
            event_data.insert(
                "violation_type".to_string(),
                serde_json::Value::String(violation_type.clone()),
            );
            event_data.insert(
                "details".to_string(),
                serde_json::Value::String(details.clone()),
            );
        }
    }

    event_data
}