193 lines
6.0 KiB
Python
193 lines
6.0 KiB
Python
"""
|
||
日志工具模块 - 记录多智能体对话历史和系统事件
|
||
"""
|
||
import os
|
||
import json
|
||
import logging
|
||
from datetime import datetime
|
||
from typing import Dict, List, Any, Optional
|
||
from pathlib import Path
|
||
|
||
|
||
class ConversationLogger:
|
||
"""对话历史日志记录器"""
|
||
|
||
def __init__(self, log_dir: str = "logs"):
|
||
"""
|
||
初始化日志记录器
|
||
|
||
Args:
|
||
log_dir: 日志目录
|
||
"""
|
||
self.log_dir = Path(log_dir)
|
||
self.log_dir.mkdir(parents=True, exist_ok=True)
|
||
|
||
# 创建会话 ID
|
||
self.session_id = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||
self.log_file = self.log_dir / f"session_{self.session_id}.jsonl"
|
||
|
||
# 配置日志
|
||
self.logger = logging.getLogger(f"autogen_sdls_{self.session_id}")
|
||
self.logger.setLevel(logging.INFO)
|
||
|
||
# 文件处理器
|
||
file_handler = logging.FileHandler(self.log_file, encoding='utf-8')
|
||
file_handler.setLevel(logging.INFO)
|
||
|
||
# 控制台处理器
|
||
console_handler = logging.StreamHandler()
|
||
console_handler.setLevel(logging.INFO)
|
||
|
||
# 格式化器
|
||
formatter = logging.Formatter(
|
||
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||
datefmt='%Y-%m-%d %H:%M:%S'
|
||
)
|
||
file_handler.setFormatter(formatter)
|
||
console_handler.setFormatter(formatter)
|
||
|
||
self.logger.addHandler(file_handler)
|
||
self.logger.addHandler(console_handler)
|
||
|
||
# 对话历史
|
||
self.conversation_history: List[Dict[str, Any]] = []
|
||
|
||
def log_message(
|
||
self,
|
||
agent_name: str,
|
||
message: str,
|
||
role: str = "assistant",
|
||
metadata: Optional[Dict] = None
|
||
):
|
||
"""
|
||
记录单条消息
|
||
|
||
Args:
|
||
agent_name: Agent 名称
|
||
message: 消息内容
|
||
role: 角色(user/assistant/system)
|
||
metadata: 额外元数据
|
||
"""
|
||
entry = {
|
||
"timestamp": datetime.now().isoformat(),
|
||
"session_id": self.session_id,
|
||
"agent_name": agent_name,
|
||
"role": role,
|
||
"message": message,
|
||
"metadata": metadata or {}
|
||
}
|
||
|
||
self.conversation_history.append(entry)
|
||
|
||
# 写入 JSONL 文件
|
||
with open(self.log_file, 'a', encoding='utf-8') as f:
|
||
f.write(json.dumps(entry, ensure_ascii=False) + '\n')
|
||
|
||
self.logger.info(f"[{agent_name}] {message[:100]}...")
|
||
|
||
def log_event(self, event_type: str, description: str, data: Optional[Dict] = None):
|
||
"""
|
||
记录系统事件
|
||
|
||
Args:
|
||
event_type: 事件类型
|
||
description: 事件描述
|
||
data: 相关数据
|
||
"""
|
||
entry = {
|
||
"timestamp": datetime.now().isoformat(),
|
||
"session_id": self.session_id,
|
||
"event_type": event_type,
|
||
"description": description,
|
||
"data": data or {}
|
||
}
|
||
|
||
with open(self.log_file, 'a', encoding='utf-8') as f:
|
||
f.write(json.dumps(entry, ensure_ascii=False) + '\n')
|
||
|
||
self.logger.info(f"[EVENT] {event_type}: {description}")
|
||
|
||
def get_conversation_history(self) -> List[Dict[str, Any]]:
|
||
"""获取完整的对话历史"""
|
||
return self.conversation_history
|
||
|
||
def export_to_json(self, output_path: Optional[str] = None) -> str:
|
||
"""
|
||
导出对话历史为 JSON 格式
|
||
|
||
Args:
|
||
output_path: 输出路径,默认在 logs 目录下
|
||
|
||
Returns:
|
||
导出文件的路径
|
||
"""
|
||
if output_path is None:
|
||
output_path = self.log_dir / f"conversation_{self.session_id}.json"
|
||
else:
|
||
output_path = Path(output_path)
|
||
|
||
export_data = {
|
||
"session_id": self.session_id,
|
||
"created_at": datetime.now().isoformat(),
|
||
"total_messages": len(self.conversation_history),
|
||
"conversation": self.conversation_history
|
||
}
|
||
|
||
with open(output_path, 'w', encoding='utf-8') as f:
|
||
json.dump(export_data, f, ensure_ascii=False, indent=2)
|
||
|
||
self.logger.info(f"对话历史已导出到:{output_path}")
|
||
return str(output_path)
|
||
|
||
def export_to_markdown(self, output_path: Optional[str] = None) -> str:
|
||
"""
|
||
导出对话历史为 Markdown 格式
|
||
|
||
Args:
|
||
output_path: 输出路径
|
||
|
||
Returns:
|
||
导出文件的路径
|
||
"""
|
||
if output_path is None:
|
||
output_path = self.log_dir / f"conversation_{self.session_id}.md"
|
||
else:
|
||
output_path = Path(output_path)
|
||
|
||
with open(output_path, 'w', encoding='utf-8') as f:
|
||
f.write(f"# AutoGen SDLC 对话历史\n\n")
|
||
f.write(f"**会话 ID**: {self.session_id}\n")
|
||
f.write(f"**创建时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||
f.write(f"**总消息数**: {len(self.conversation_history)}\n\n")
|
||
f.write("---\n\n")
|
||
|
||
for entry in self.conversation_history:
|
||
timestamp = entry["timestamp"][:19].replace('T', ' ')
|
||
agent = entry["agent_name"]
|
||
message = entry["message"]
|
||
|
||
f.write(f"### [{timestamp}] {agent}\n\n")
|
||
f.write(f"{message}\n\n")
|
||
f.write("---\n\n")
|
||
|
||
self.logger.info(f"对话历史已导出为 Markdown: {output_path}")
|
||
return str(output_path)
|
||
|
||
|
||
# 全局日志实例
|
||
_global_logger: Optional[ConversationLogger] = None
|
||
|
||
|
||
def get_logger(log_dir: str = "logs") -> ConversationLogger:
|
||
"""获取或创建全局日志记录器"""
|
||
global _global_logger
|
||
if _global_logger is None:
|
||
_global_logger = ConversationLogger(log_dir)
|
||
return _global_logger
|
||
|
||
|
||
def reset_logger():
|
||
"""重置全局日志记录器"""
|
||
global _global_logger
|
||
_global_logger = None
|