210 lines
4.4 KiB
Rust
210 lines
4.4 KiB
Rust
/*!
|
|
# 日志聚合模块
|
|
|
|
实现NAC链的日志收集、解析、存储和查询功能。
|
|
*/
|
|
|
|
pub mod collector;
|
|
pub mod parser;
|
|
pub mod storage;
|
|
pub mod query;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use chrono::{DateTime, Utc};
|
|
use std::collections::HashMap;
|
|
|
|
/// 日志级别
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
|
pub enum LogLevel {
|
|
Trace,
|
|
Debug,
|
|
Info,
|
|
Warning,
|
|
Error,
|
|
Fatal,
|
|
}
|
|
|
|
/// 日志来源
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
pub enum LogSource {
|
|
/// 节点日志
|
|
Node,
|
|
/// 共识日志
|
|
Consensus,
|
|
/// 网络日志
|
|
Network,
|
|
/// 交易日志
|
|
Transaction,
|
|
/// 合约日志
|
|
Contract,
|
|
/// 系统日志
|
|
System,
|
|
}
|
|
|
|
/// 日志条目
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct LogEntry {
|
|
/// 日志ID
|
|
pub id: String,
|
|
|
|
/// 时间戳
|
|
pub timestamp: DateTime<Utc>,
|
|
|
|
/// 日志级别
|
|
pub level: LogLevel,
|
|
|
|
/// 日志来源
|
|
pub source: LogSource,
|
|
|
|
/// 节点ID
|
|
pub node_id: String,
|
|
|
|
/// 日志消息
|
|
pub message: String,
|
|
|
|
/// 字段
|
|
pub fields: HashMap<String, String>,
|
|
|
|
/// 标签
|
|
pub tags: Vec<String>,
|
|
}
|
|
|
|
impl LogEntry {
|
|
/// 创建新日志条目
|
|
pub fn new(
|
|
level: LogLevel,
|
|
source: LogSource,
|
|
node_id: String,
|
|
message: String,
|
|
) -> Self {
|
|
Self {
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
timestamp: Utc::now(),
|
|
level,
|
|
source,
|
|
node_id,
|
|
message,
|
|
fields: HashMap::new(),
|
|
tags: Vec::new(),
|
|
}
|
|
}
|
|
|
|
/// 添加字段
|
|
pub fn with_field(mut self, key: String, value: String) -> Self {
|
|
self.fields.insert(key, value);
|
|
self
|
|
}
|
|
|
|
/// 添加标签
|
|
pub fn with_tag(mut self, tag: String) -> Self {
|
|
self.tags.push(tag);
|
|
self
|
|
}
|
|
}
|
|
|
|
/// 日志查询条件
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct LogQuery {
|
|
/// 开始时间
|
|
pub start_time: Option<DateTime<Utc>>,
|
|
|
|
/// 结束时间
|
|
pub end_time: Option<DateTime<Utc>>,
|
|
|
|
/// 日志级别
|
|
pub levels: Option<Vec<LogLevel>>,
|
|
|
|
/// 日志来源
|
|
pub sources: Option<Vec<LogSource>>,
|
|
|
|
/// 节点ID
|
|
pub node_ids: Option<Vec<String>>,
|
|
|
|
/// 关键词搜索
|
|
pub keywords: Option<Vec<String>>,
|
|
|
|
/// 标签过滤
|
|
pub tags: Option<Vec<String>>,
|
|
|
|
/// 限制数量
|
|
pub limit: Option<usize>,
|
|
|
|
/// 偏移量
|
|
pub offset: Option<usize>,
|
|
}
|
|
|
|
impl Default for LogQuery {
|
|
fn default() -> Self {
|
|
Self {
|
|
start_time: None,
|
|
end_time: None,
|
|
levels: None,
|
|
sources: None,
|
|
node_ids: None,
|
|
keywords: None,
|
|
tags: None,
|
|
limit: Some(100),
|
|
offset: Some(0),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 日志统计
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct LogStats {
|
|
/// 总日志数
|
|
pub total_count: usize,
|
|
|
|
/// 按级别统计
|
|
pub by_level: HashMap<LogLevel, usize>,
|
|
|
|
/// 按来源统计
|
|
pub by_source: HashMap<String, usize>,
|
|
|
|
/// 按节点统计
|
|
pub by_node: HashMap<String, usize>,
|
|
|
|
/// 时间范围
|
|
pub time_range: (DateTime<Utc>, DateTime<Utc>),
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_log_entry_creation() {
|
|
let entry = LogEntry::new(
|
|
LogLevel::Info,
|
|
LogSource::Node,
|
|
"node-1".to_string(),
|
|
"测试日志".to_string(),
|
|
);
|
|
|
|
assert_eq!(entry.level, LogLevel::Info);
|
|
assert_eq!(entry.source, LogSource::Node);
|
|
}
|
|
|
|
#[test]
|
|
fn test_log_entry_with_fields() {
|
|
let entry = LogEntry::new(
|
|
LogLevel::Info,
|
|
LogSource::Node,
|
|
"node-1".to_string(),
|
|
"测试日志".to_string(),
|
|
)
|
|
.with_field("key1".to_string(), "value1".to_string())
|
|
.with_tag("tag1".to_string());
|
|
|
|
assert_eq!(entry.fields.get("key1"), Some(&"value1".to_string()));
|
|
assert!(entry.tags.contains(&"tag1".to_string()));
|
|
}
|
|
|
|
#[test]
|
|
fn test_log_query_default() {
|
|
let query = LogQuery::default();
|
|
assert_eq!(query.limit, Some(100));
|
|
assert_eq!(query.offset, Some(0));
|
|
}
|
|
}
|