Files
personal-experiment/logger.py
T
2026-03-06 11:26:35 +08:00

168 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
日志记录器模块
负责记录网络监控的历史数据和异常事件
"""
import os
import json
from datetime import datetime
from typing import List, Dict, Any
from pathlib import Path
class Logger:
"""日志记录器类"""
def __init__(self, log_dir: str = "logs", max_log_files: int = 10):
"""
初始化日志记录器
Args:
log_dir: 日志文件存储目录
max_log_files: 最大保留的日志文件数量
"""
self.log_dir = Path(log_dir)
self.max_log_files = max_log_files
self.current_session_data: List[Dict[str, Any]] = []
self.session_start_time = datetime.now()
# 创建日志目录
self.log_dir.mkdir(parents=True, exist_ok=True)
# 清理旧日志文件
self._cleanup_old_logs()
def _get_log_filename(self) -> str:
"""生成日志文件名"""
timestamp = self.session_start_time.strftime("%Y%m%d_%H%M%S")
return f"network_monitor_{timestamp}.log"
def _cleanup_old_logs(self):
"""清理旧的日志文件,保留最近的max_log_files个"""
log_files = sorted(
self.log_dir.glob("network_monitor_*.log"),
key=lambda x: x.stat().st_mtime,
reverse=True
)
# 删除超出数量限制的旧日志文件
for old_log in log_files[self.max_log_files:]:
old_log.unlink()
def log_event(self, event_type: str, message: str, **kwargs):
"""
记录事件
Args:
event_type: 事件类型(ping, status_change, error等)
message: 事件描述
**kwargs: 额外的键值对数据
"""
event = {
"timestamp": datetime.now().isoformat(),
"type": event_type,
"message": message,
**kwargs
}
self.current_session_data.append(event)
def log_ping(self, success: bool, latency: float = 0.0):
"""
记录ping结果
Args:
success: ping是否成功
latency: 延迟时间(毫秒)
"""
self.log_event(
"ping",
"Ping操作完成" if success else "Ping操作失败",
success=success,
latency_ms=latency
)
def log_status_change(self, status: str, duration: float = None):
"""
记录状态变化
Args:
status: 状态(connected, disconnected
duration: 持续时间(秒)
"""
message = f"网络状态变化: {status}"
if duration is not None:
message += f" (持续{duration:.1f}秒)"
self.log_event(
"status_change",
message,
status=status,
duration_seconds=duration
)
def log_error(self, error_type: str, error_message: str):
"""
记录错误
Args:
error_type: 错误类型
error_message: 错误信息
"""
self.log_event(
"error",
f"{error_type}: {error_message}",
error_type=error_type
)
def log_shutdown(self, reason: str):
"""
记录关机事件
Args:
reason: 关机原因
"""
self.log_event(
"shutdown",
f"系统关机: {reason}",
reason=reason
)
def save_session(self):
"""保存当前会话的日志到文件"""
log_file = self.log_dir / self._get_log_filename()
session_summary = {
"session_start": self.session_start_time.isoformat(),
"session_end": datetime.now().isoformat(),
"total_events": len(self.current_session_data),
"events": self.current_session_data
}
with open(log_file, 'w', encoding='utf-8') as f:
json.dump(session_summary, f, ensure_ascii=False, indent=2)
return log_file
def get_statistics(self) -> Dict[str, Any]:
"""
获取当前会话的统计信息
Returns:
统计数据字典
"""
total_pings = sum(1 for event in self.current_session_data if event["type"] == "ping")
successful_pings = sum(
1 for event in self.current_session_data
if event["type"] == "ping" and event["success"]
)
return {
"total_pings": total_pings,
"successful_pings": successful_pings,
"failed_pings": total_pings - successful_pings,
"success_rate": f"{(successful_pings / total_pings * 100):.2f}%" if total_pings > 0 else "0%",
"session_duration": (datetime.now() - self.session_start_time).total_seconds()
}