postfix-log-parser 0.2.0

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

#[test]
fn test_warning_log_parsing_from_real_logs() {
    // 读取真实的测试日志文件
    let log_content = fs::read_to_string("logs/test1.log").expect("无法读取测试日志文件");

    let mut warning_count = 0;
    let mut info_count = 0;
    let mut total_parsed = 0;

    for (line_num, line) in log_content.lines().enumerate() {
        if line.trim().is_empty() {
            continue;
        }

        // 特别关注包含warning的行
        if line.contains("warning") {
            println!("处理警告行 {}: {}", line_num + 1, line);
        }

        let result = parse_log_line(line);

        // 只统计成功解析或部分解析的日志
        if result.confidence > 0.0 {
            total_parsed += 1;

            if let Some(event) = &result.event {
                if line.contains("warning") {
                    println!(
                        "  解析结果: log_level={:?}, component={}, message='{}'",
                        event.log_level,
                        event.component,
                        match &event.event {
                            postfix_log_parser::events::base::ComponentEvent::Unknown(u) =>
                                &u.message,
                            _ => "非Unknown事件",
                        }
                    );
                }

                match event.log_level {
                    PostfixLogLevel::Warning => {
                        warning_count += 1;
                        println!("发现警告日志 (行{}): {}", line_num + 1, line);

                        // 验证警告日志的便利方法
                        assert!(event.is_warning_level());
                        assert!(!event.is_error_level());
                        assert!(!event.is_debug_level());
                        assert_eq!(event.severity_level(), 3);
                    }
                    PostfixLogLevel::Info => {
                        info_count += 1;
                    }
                    _ => {
                        // 其他等级暂时不统计
                    }
                }
            }
        } else if line.contains("warning") {
            println!("  警告行解析失败: {:?}", result);
        }
    }

    println!("日志等级统计:");
    println!("  总解析成功: {}", total_parsed);
    println!("  Info级别: {}", info_count);
    println!("  Warning级别: {}", warning_count);

    // 验证我们找到了预期的警告日志数量
    assert!(warning_count >= 16, "应该找到至少16个警告日志");
    assert!(info_count >= 383, "应该有至少383个Info级别的日志");
    assert!(total_parsed >= 399, "应该解析至少399个日志(100%成功率)");
}

#[test]
fn test_log_level_enum_functionality() {
    // 测试PostfixLogLevel枚举的各种功能

    // 测试严重程度排序
    assert!(PostfixLogLevel::Debug.severity_level() < PostfixLogLevel::Info.severity_level());
    assert!(PostfixLogLevel::Info.severity_level() < PostfixLogLevel::Warning.severity_level());
    assert!(PostfixLogLevel::Warning.severity_level() < PostfixLogLevel::Error.severity_level());
    assert!(PostfixLogLevel::Error.severity_level() < PostfixLogLevel::Fatal.severity_level());
    assert!(PostfixLogLevel::Fatal.severity_level() < PostfixLogLevel::Panic.severity_level());

    // 测试字符串表示
    assert_eq!(PostfixLogLevel::Warning.as_str(), "warning");
    assert_eq!(PostfixLogLevel::Error.as_str(), "error");
    assert_eq!(PostfixLogLevel::Info.as_str(), "info");

    // 测试Display trait
    assert_eq!(format!("{}", PostfixLogLevel::Warning), "warning");

    // 测试from_prefix方法
    assert_eq!(
        PostfixLogLevel::from_prefix("warning:"),
        Some(PostfixLogLevel::Warning)
    );
    assert_eq!(
        PostfixLogLevel::from_prefix("error:"),
        Some(PostfixLogLevel::Error)
    );
    assert_eq!(PostfixLogLevel::from_prefix("info:"), None); // info没有前缀
    assert_eq!(PostfixLogLevel::from_prefix("unknown:"), None);

    // 测试默认值
    assert_eq!(PostfixLogLevel::default(), PostfixLogLevel::Info);

    // 测试便利方法
    assert!(PostfixLogLevel::Warning.is_warning_level());
    assert!(PostfixLogLevel::Error.is_error_level());
    assert!(PostfixLogLevel::Fatal.is_error_level());
    assert!(PostfixLogLevel::Panic.is_error_level());
    assert!(PostfixLogLevel::Debug.is_debug_level());

    assert!(!PostfixLogLevel::Info.is_warning_level());
    assert!(!PostfixLogLevel::Info.is_error_level());
    assert!(!PostfixLogLevel::Info.is_debug_level());
}

#[test]
fn test_specific_warning_log_parsing() {
    // 测试具体的警告日志解析
    let warning_log = "Jun 05 17:32:54 m01 postfix/smtpd[149]: warning: dict_nis_init: NIS domain name not set - NIS lookups disabled";

    let result = parse_log_line(warning_log);

    // 这应该创建一个Unknown事件(因为smtpd解析器不处理警告消息)
    // 但仍然应该正确识别日志等级
    assert!(result.confidence > 0.0, "应该至少部分解析成功");

    let event = result.event.expect("应该有解析结果");

    // 验证日志等级
    assert_eq!(event.log_level, PostfixLogLevel::Warning);
    assert!(event.is_warning_level());

    // 验证基础信息
    assert_eq!(event.hostname, "m01");
    assert_eq!(event.component, "smtpd");
    assert_eq!(event.process_id, 149);

    // 验证这是一个SystemWarning事件(SMTPD解析器现在可以处理系统警告)
    match &event.event {
        postfix_log_parser::events::base::ComponentEvent::Smtpd(smtpd_event) => {
            use postfix_log_parser::events::smtpd::SmtpdEvent;
            match smtpd_event {
                SmtpdEvent::SystemWarning {
                    warning_type,
                    message,
                    client_info,
                } => {
                    assert_eq!(warning_type, "nis_config");
                    assert_eq!(
                        message,
                        "dict_nis_init: NIS domain name not set - NIS lookups disabled"
                    );
                    assert!(client_info.is_none()); // 系统警告通常没有客户端信息
                }
                _ => panic!("应该是SystemWarning事件"),
            }
        }
        _ => panic!("应该是SMTPD SystemWarning事件"),
    }
}