""" 日志工具模块 - 记录多智能体对话历史和系统事件 """ 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