postfix-log-parser 0.2.0

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

/// 格式化Postsuper事件为JSON
pub fn format_postsuper_event(event: &PostsuperEvent) -> Value {
    let mut event_data = Map::new();

    // 根据事件类型设置字段
    match event.event_type {
        PostsuperEventType::MessageRemoved => {
            event_data.insert(
                "event_type".to_string(),
                Value::String("message_removed".to_string()),
            );

            if let Some(queue_id) = &event.queue_id {
                event_data.insert("queue_id".to_string(), Value::String(queue_id.clone()));
            }

            if let Some(description) = &event.description {
                event_data.insert("action".to_string(), Value::String(description.clone()));
            }
        }
        PostsuperEventType::BulkDeleted => {
            event_data.insert(
                "event_type".to_string(),
                Value::String("bulk_deleted".to_string()),
            );

            if let Some(count) = event.message_count {
                event_data.insert(
                    "message_count".to_string(),
                    Value::Number(serde_json::Number::from(count)),
                );
            }

            if let Some(description) = &event.description {
                event_data.insert("summary".to_string(), Value::String(description.clone()));
            }
        }
    }

    // 添加通用字段
    event_data.insert(
        "component".to_string(),
        Value::String("postsuper".to_string()),
    );
    event_data.insert(
        "timestamp".to_string(),
        Value::String(event.timestamp.to_rfc3339()),
    );

    Value::Object(event_data)
}

#[cfg(test)]
mod tests {
    use super::*;
    use chrono::Utc;

    #[test]
    fn test_format_message_removed_event() {
        let event = PostsuperEvent::message_removed(Utc::now(), "61563640322461696".to_string());

        let formatted = format_postsuper_event(&event);

        if let Value::Object(map) = formatted {
            assert_eq!(map.get("event_type").unwrap(), "message_removed");
            assert_eq!(map.get("queue_id").unwrap(), "61563640322461696");
            assert_eq!(map.get("action").unwrap(), "removed");
            assert_eq!(map.get("component").unwrap(), "postsuper");
            assert!(map.contains_key("timestamp"));
        } else {
            panic!("Expected JSON object");
        }
    }

    #[test]
    fn test_format_bulk_deleted_event() {
        let event = PostsuperEvent::bulk_deleted(Utc::now(), 5);

        let formatted = format_postsuper_event(&event);

        if let Value::Object(map) = formatted {
            assert_eq!(map.get("event_type").unwrap(), "bulk_deleted");
            assert_eq!(map.get("message_count").unwrap(), 5);
            assert_eq!(map.get("summary").unwrap(), "Deleted: 5 messages");
            assert_eq!(map.get("component").unwrap(), "postsuper");
            assert!(map.contains_key("timestamp"));
        } else {
            panic!("Expected JSON object");
        }
    }
}