logger.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import logging
  2. import json
  3. from datetime import datetime
  4. import os
  5. from typing import Dict, Any
  6. from pathlib import Path
  7. # 确保日志目录存在
  8. LOG_DIR = Path("chat_logs")
  9. LOG_DIR.mkdir(exist_ok=True)
  10. # 详细日志目录结构
  11. DETAILED_LOG_DIR = LOG_DIR / "detailed"
  12. DETAILED_LOG_DIR.mkdir(exist_ok=True)
  13. # 配置日志
  14. def setup_logging():
  15. """配置日志系统"""
  16. # 主日志记录器
  17. logger = logging.getLogger("chat_logger")
  18. logger.setLevel(logging.INFO)
  19. # 避免重复添加handler
  20. if not logger.handlers:
  21. # 文件处理器 - 按天分割
  22. log_file = LOG_DIR / f"chat_{datetime.now().strftime('%Y%m%d')}.log"
  23. file_handler = logging.FileHandler(log_file, encoding="utf-8")
  24. file_handler.setLevel(logging.INFO)
  25. # 控制台处理器
  26. console_handler = logging.StreamHandler()
  27. console_handler.setLevel(logging.INFO)
  28. # 确保控制台输出使用UTF-8编码
  29. import sys
  30. if hasattr(sys.stdout, 'reconfigure'):
  31. sys.stdout.reconfigure(encoding='utf-8')
  32. if hasattr(sys.stderr, 'reconfigure'):
  33. sys.stderr.reconfigure(encoding='utf-8')
  34. # 格式化
  35. formatter = logging.Formatter(
  36. "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
  37. datefmt="%Y-%m-%d %H:%M:%S",
  38. )
  39. file_handler.setFormatter(formatter)
  40. console_handler.setFormatter(formatter)
  41. logger.addHandler(file_handler)
  42. logger.addHandler(console_handler)
  43. return logger
  44. # 初始化日志
  45. chat_logger = setup_logging()
  46. def get_detailed_log_path(user_id: str, timestamp: datetime = None) -> Path:
  47. """
  48. 获取详细日志文件的路径
  49. 格式: chat_logs/detailed/YYYYMMDD/user_id_YYYYMMDD_HHMMSS.json
  50. """
  51. if timestamp is None:
  52. timestamp = datetime.now()
  53. # 按日期创建目录
  54. date_str = timestamp.strftime("%Y%m%d")
  55. date_dir = DETAILED_LOG_DIR / date_str
  56. date_dir.mkdir(exist_ok=True)
  57. # 生成文件名
  58. filename = f"{user_id}_{timestamp.strftime('%Y%m%d_%H%M%S')}.json"
  59. return date_dir / filename
  60. def log_chat_entry(user_id: str, user_message: str, agent_response: Dict[str, Any]):
  61. """记录完整的对话日志"""
  62. try:
  63. timestamp = datetime.now()
  64. log_entry = {
  65. "timestamp": timestamp.isoformat(),
  66. "user_id": user_id,
  67. "user_message": user_message,
  68. "agent_response": {
  69. "final_answer": agent_response.get("final_answer", ""),
  70. "all_ai_messages_count": len(agent_response.get("all_ai_messages", [])),
  71. "all_messages_count": len(agent_response.get("all_messages", [])),
  72. "tool_calls_count": len(agent_response.get("tool_calls", [])),
  73. },
  74. "all_messages": [
  75. {
  76. "type": msg.get("type"),
  77. "content": msg.get("content", "")[:500], # 限制长度
  78. "tool_calls": msg.get("tool_calls"),
  79. "index": msg.get("index"),
  80. }
  81. for msg in agent_response.get("all_messages", [])
  82. ],
  83. "tool_calls": agent_response.get("tool_calls", []),
  84. }
  85. # 记录到日志文件
  86. chat_logger.info(f"对话记录 - Thread: {user_id}")
  87. chat_logger.info(f"用户消息: {user_message}")
  88. chat_logger.info(
  89. f"Agent响应: {agent_response.get('final_answer', '')[:200]}..."
  90. )
  91. # 保存详细日志到单独文件
  92. detailed_log_file = get_detailed_log_path(user_id, timestamp)
  93. with open(detailed_log_file, "w", encoding="utf-8") as f:
  94. json.dump(log_entry, f, ensure_ascii=False, indent=2)
  95. chat_logger.info(f"详细日志已保存到: {detailed_log_file}")
  96. except Exception as e:
  97. chat_logger.error(f"记录日志时出错: {str(e)}")