request_logger.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. """
  2. 请求日志记录器 - 记录每个语音对话请求的详细信息
  3. """
  4. import os
  5. import time
  6. from datetime import datetime
  7. from threading import Lock
  8. from typing import Optional
  9. class RequestLogger:
  10. """请求日志记录器(线程安全)"""
  11. def __init__(self, log_file: str = "conversation_log.txt"):
  12. """
  13. 初始化日志记录器
  14. Args:
  15. log_file: 日志文件路径
  16. """
  17. self.log_file = log_file
  18. self.lock = Lock()
  19. # 如果文件不存在,创建并写入表头
  20. if not os.path.exists(log_file):
  21. self._write_header()
  22. def _write_header(self):
  23. """写入日志文件表头"""
  24. with open(self.log_file, 'w', encoding='utf-8') as f:
  25. f.write("=" * 120 + "\n")
  26. f.write("Tolan AI 对话日志\n")
  27. f.write("格式: 时间 | 用户语音文本 | 录音结束→首个音频时间(ms) | AI输出文本\n")
  28. f.write("=" * 120 + "\n\n")
  29. def log_request(
  30. self,
  31. user_text: str,
  32. ai_response: str,
  33. first_audio_latency: Optional[float] = None,
  34. request_id: Optional[str] = None
  35. ):
  36. """
  37. 记录一条对话请求
  38. Args:
  39. user_text: 用户语音识别的文本
  40. ai_response: AI的完整回复文本
  41. first_audio_latency: 录音结束到首个音频的延迟(毫秒)
  42. request_id: 请求ID(可选)
  43. """
  44. with self.lock:
  45. # 获取当前时间
  46. timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  47. # 处理延迟信息
  48. latency_str = f"{first_audio_latency:.0f}ms" if first_audio_latency else "N/A"
  49. # 清理文本(移除换行符,保持单行)
  50. user_text_clean = user_text.replace('\n', ' ').replace('\r', ' ').strip()
  51. ai_response_clean = ai_response.replace('\n', ' ').replace('\r', ' ').strip()
  52. # 构建日志行
  53. log_line = f"{timestamp} | {user_text_clean} | {latency_str} | {ai_response_clean}\n"
  54. # 写入文件
  55. try:
  56. with open(self.log_file, 'a', encoding='utf-8') as f:
  57. f.write(log_line)
  58. print(f"📝 已记录对话日志 [{request_id or 'unknown'}]: {user_text_clean[:20]}... → {ai_response_clean[:20]}...")
  59. except Exception as e:
  60. print(f"⚠️ 写入日志失败: {e}")
  61. def log_error(self, user_text: str, error_message: str, request_id: Optional[str] = None):
  62. """
  63. 记录错误请求
  64. Args:
  65. user_text: 用户语音识别的文本
  66. error_message: 错误信息
  67. request_id: 请求ID(可选)
  68. """
  69. with self.lock:
  70. timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  71. user_text_clean = user_text.replace('\n', ' ').replace('\r', ' ').strip()
  72. error_clean = error_message.replace('\n', ' ').replace('\r', ' ').strip()
  73. log_line = f"{timestamp} | {user_text_clean} | ERROR | {error_clean}\n"
  74. try:
  75. with open(self.log_file, 'a', encoding='utf-8') as f:
  76. f.write(log_line)
  77. print(f"📝 已记录错误日志 [{request_id or 'unknown'}]: {error_clean}")
  78. except Exception as e:
  79. print(f"⚠️ 写入错误日志失败: {e}")
  80. # 全局单例
  81. request_logger = RequestLogger()