postfix-log-parser 0.2.0

高性能模块化Postfix日志解析器,经3.2GB生产数据验证,SMTPD事件100%准确率
Documentation
use postfix_log_parser::{parse_log_line, ComponentEvent, PostfixLogEvent};
use std::collections::HashMap;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("Postfix Log Parser - 高级使用示例");
    println!("{}", "=".repeat(60));

    // 示例:各种组件的日志
    let sample_logs = vec![
        // SMTPD 事件
        ("SMTPD Connect", "Dec 30 12:34:56 mail01 postfix/smtpd[12345]: connect from client.example.com[192.168.1.100]"),
        ("SMTPD Disconnect", "Dec 30 12:34:56 mail01 postfix/smtpd[12345]: disconnect from client.example.com[192.168.1.100] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5"),
        
        // SMTP 事件
        ("SMTP Sent", "Dec 30 12:34:59 mail01 postfix/smtp[12348]: 4bG4VR5z: to=<recipient@example.com>, relay=mx.example.com[1.2.3.4]:25, delay=0.5, status=sent (250 2.0.0 OK)"),
        ("SMTP Bounced", "Dec 30 12:34:59 mail01 postfix/smtp[12348]: 4bG4VR5z: to=<bad@example.com>, relay=mx.example.com[1.2.3.4]:25, delay=0.5, status=bounced (550 5.1.1 User unknown)"),
        
        // QMGR 事件
        ("QMGR Active", "Dec 30 12:34:58 mail01 postfix/qmgr[12347]: 4bG4VR5z: from=<sender@example.com>, size=1234, nrcpt=1 (queue active)"),
        ("QMGR Removed", "Dec 30 12:34:59 mail01 postfix/qmgr[12347]: 4bG4VR5z: removed"),
        
        // CLEANUP 事件
        ("Cleanup Message-ID", "Dec 30 12:34:57 mail01 postfix/cleanup[12346]: 4bG4VR5z: message-id=<test@example.com>"),
        
        // BOUNCE 事件
        ("Bounce Created", "Dec 30 12:35:00 mail01 postfix/bounce[12349]: 4bG4VR5z: sender non-delivery notification: 4bG4VR6z"),
        
        // LOCAL 事件
        ("Local Delivered", "Dec 30 12:35:01 mail01 postfix/local[12350]: 4bG4VR5z: to=<user@localhost>, relay=local, delay=0.1, status=delivered (delivered to mailbox)"),
        
        // ERROR 事件
        ("Error", "Dec 30 12:35:02 mail01 postfix/error[12351]: 4bG4VR5z: to=<nonexistent@example.com>, relay=none, delay=30, status=bounced (mail for example.com loops back to myself)"),
        
        // MASTER 事件
        ("Master Daemon Started", "Dec 30 12:30:00 mail01 postfix/master[1234]: daemon started -- version 3.6.4, configuration /etc/postfix"),
        
        // ANVIL 事件
        ("Anvil Connect Rate", "Dec 30 12:34:56 mail01 postfix/anvil[12352]: statistics: max connection rate 10/60s for (smtp:192.168.1.100) at Dec 30 12:34:56"),
    ];

    // 逐个解析和分析
    for (description, log_line) in sample_logs {
        println!("\n🔍 分析: {}", description);
        println!("原始日志: {}", log_line);
        
        let result = parse_log_line(log_line);
        
        match result.event {
            Some(event) => {
                print_event_details(&event);
                analyze_specific_event(&event);
                println!("置信度: {:.2}", result.confidence);
            }
            None => {
                println!("❌ 解析失败:");
                for error in result.parsing_errors {
                    println!("   错误: {:?}", error);
                }
            }
        }
        println!("{}", "-".repeat(40));
    }

    // 批量统计分析
    println!("\n📊 批量统计分析:");
    batch_analysis();

    Ok(())
}

fn print_event_details(event: &PostfixLogEvent) {
    println!("✅ 解析成功:");
    println!("   时间: {}", event.timestamp.format("%Y-%m-%d %H:%M:%S"));
    println!("   主机: {}", event.hostname);
    println!("   组件: {}", event.component);
    println!("   进程ID: {}", event.process_id);
    println!("   队列ID: {:?}", event.queue_id);
    println!("   事件类型: {}", event.event_type());
}

fn analyze_specific_event(event: &PostfixLogEvent) {
    match &event.event {
        ComponentEvent::Smtpd(smtpd_event) => {
            println!("   SMTPD事件详情: {:?}", smtpd_event);
        }
        ComponentEvent::Smtp(smtp_event) => {
            println!("   SMTP事件详情: {:?}", smtp_event);
        }
        ComponentEvent::Qmgr(qmgr_event) => {
            println!("   QMGR事件详情: {:?}", qmgr_event);
        }
        ComponentEvent::Cleanup(cleanup_event) => {
            println!("   CLEANUP事件详情: {:?}", cleanup_event);
        }
        ComponentEvent::Bounce(bounce_event) => {
            println!("   BOUNCE事件详情: {:?}", bounce_event);
        }
        ComponentEvent::Local(local_event) => {
            println!("   LOCAL事件详情: {:?}", local_event);
        }
        ComponentEvent::Error(error_event) => {
            println!("   ERROR事件详情: {:?}", error_event);
        }
        ComponentEvent::Master(master_event) => {
            println!("   MASTER事件详情: {:?}", master_event);
        }
        ComponentEvent::Anvil(anvil_event) => {
            println!("   ANVIL事件详情: {:?}", anvil_event);
        }
        _ => {
            println!("   其他组件事件: {:?}", event.event);
        }
    }
}

fn batch_analysis() {
    // 模拟大量日志数据
    let log_data = vec![
        "Dec 30 12:34:56 mail01 postfix/smtpd[12345]: connect from client1[192.168.1.100]",
        "Dec 30 12:34:56 mail01 postfix/smtpd[12345]: connect from client2[192.168.1.101]",
        "Dec 30 12:34:57 mail01 postfix/cleanup[12346]: 4bG4VR5z1: message-id=<test1@example.com>",
        "Dec 30 12:34:57 mail01 postfix/cleanup[12346]: 4bG4VR5z2: message-id=<test2@example.com>",
        "Dec 30 12:34:58 mail01 postfix/qmgr[12347]: 4bG4VR5z1: from=<sender1@example.com>, size=1234, nrcpt=1",
        "Dec 30 12:34:58 mail01 postfix/qmgr[12347]: 4bG4VR5z2: from=<sender2@example.com>, size=2345, nrcpt=2",
        "Dec 30 12:34:59 mail01 postfix/smtp[12348]: 4bG4VR5z1: to=<recipient1@example.com>, status=sent",
        "Dec 30 12:34:59 mail01 postfix/smtp[12348]: 4bG4VR5z2: to=<recipient2@example.com>, status=sent",
        "Dec 30 12:35:00 mail01 postfix/qmgr[12347]: 4bG4VR5z1: removed",
        "Dec 30 12:35:00 mail01 postfix/qmgr[12347]: 4bG4VR5z2: removed",
    ];

    let results = postfix_log_parser::parse_log_lines(log_data);
    
    let mut component_stats: HashMap<String, u32> = HashMap::new();
    let mut event_type_stats: HashMap<String, u32> = HashMap::new();
    let mut success_count = 0;
    let mut total_confidence = 0.0f32;

    for result in results {
        if let Some(event) = result.event {
            success_count += 1;
            total_confidence += result.confidence;
            
            // 统计组件
            *component_stats.entry(event.component.clone()).or_insert(0) += 1;
            
            // 统计事件类型
            *event_type_stats.entry(event.event_type().to_string()).or_insert(0) += 1;
        }
    }

    println!("📈 统计结果:");
    println!("   成功解析: {}", success_count);
    println!("   平均置信度: {:.2}", total_confidence / success_count as f32);
    
    println!("\n🏷️  组件统计:");
    for (component, count) in component_stats {
        println!("   {}: {}", component, count);
    }
    
    println!("\n🎯 事件类型统计:");
    for (event_type, count) in event_type_stats {
        println!("   {}: {}", event_type, count);
    }
}