NAC_Blockchain/nac-monitor/src/logging/parser.rs

70 lines
2.0 KiB
Rust

/*!
# 日志解析器
解析各种格式的日志。
*/
use super::{LogEntry, LogLevel, LogSource};
use crate::error::{MonitorError, Result};
use serde_json::Value;
/// 日志解析器
pub struct LogParser;
impl LogParser {
/// 解析JSON格式日志
pub fn parse_json(json_str: &str, node_id: String) -> Result<LogEntry> {
let value: Value = serde_json::from_str(json_str)
.map_err(|e| MonitorError::LogError(format!("解析JSON日志失败: {}", e)))?;
let level = match value.get("level").and_then(|v| v.as_str()) {
Some("error") | Some("ERROR") => LogLevel::Error,
Some("warn") | Some("WARN") | Some("warning") => LogLevel::Warning,
Some("info") | Some("INFO") => LogLevel::Info,
Some("debug") | Some("DEBUG") => LogLevel::Debug,
Some("trace") | Some("TRACE") => LogLevel::Trace,
_ => LogLevel::Info,
};
let message = value.get("message")
.or_else(|| value.get("msg"))
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
Ok(LogEntry::new(level, LogSource::Node, node_id, message))
}
/// 解析纯文本日志
pub fn parse_text(text: &str, node_id: String) -> LogEntry {
let level = if text.contains("ERROR") {
LogLevel::Error
} else if text.contains("WARN") {
LogLevel::Warning
} else {
LogLevel::Info
};
LogEntry::new(level, LogSource::Node, node_id, text.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_json() {
let json = r#"{"level":"error","message":"test error"}"#;
let entry = LogParser::parse_json(json, "node-1".to_string());
assert!(entry.is_ok());
}
#[test]
fn test_parse_text() {
let text = "ERROR: test error";
let entry = LogParser::parse_text(text, "node-1".to_string());
assert_eq!(entry.level, LogLevel::Error);
}
}