|
|
import logging |
|
|
import os |
|
|
from datetime import datetime |
|
|
from typing import Optional, Dict, Any, List |
|
|
import json |
|
|
|
|
|
|
|
|
class ChatLogger: |
|
|
""" |
|
|
聊天应用的关键日志记录器 |
|
|
""" |
|
|
|
|
|
def __init__(self, log_dir: str = "logs"): |
|
|
self.log_dir = log_dir |
|
|
self._ensure_log_dir() |
|
|
self._setup_loggers() |
|
|
|
|
|
def _ensure_log_dir(self): |
|
|
"""确保日志目录存在""" |
|
|
if not os.path.exists(self.log_dir): |
|
|
os.makedirs(self.log_dir) |
|
|
|
|
|
def _setup_loggers(self): |
|
|
"""设置不同类型的日志记录器""" |
|
|
|
|
|
self.user_logger = logging.getLogger('user_actions') |
|
|
self.user_logger.setLevel(logging.INFO) |
|
|
|
|
|
self.user_logger.handlers.clear() |
|
|
|
|
|
user_handler = logging.FileHandler( |
|
|
os.path.join(self.log_dir, 'user_actions.log'), |
|
|
encoding='utf-8' |
|
|
) |
|
|
user_formatter = logging.Formatter( |
|
|
'📝 %(asctime)s - %(levelname)s - %(message)s' |
|
|
) |
|
|
user_handler.setFormatter(user_formatter) |
|
|
self.user_logger.addHandler(user_handler) |
|
|
|
|
|
|
|
|
console_handler = logging.StreamHandler() |
|
|
console_handler.setFormatter(user_formatter) |
|
|
self.user_logger.addHandler(console_handler) |
|
|
|
|
|
|
|
|
self.mcp_logger = logging.getLogger('mcp_services') |
|
|
self.mcp_logger.setLevel(logging.INFO) |
|
|
|
|
|
self.mcp_logger.handlers.clear() |
|
|
|
|
|
mcp_handler = logging.FileHandler( |
|
|
os.path.join(self.log_dir, 'mcp_services.log'), |
|
|
encoding='utf-8' |
|
|
) |
|
|
mcp_formatter = logging.Formatter( |
|
|
'🔧 %(asctime)s - %(levelname)s - %(message)s' |
|
|
) |
|
|
mcp_handler.setFormatter(mcp_formatter) |
|
|
self.mcp_logger.addHandler(mcp_handler) |
|
|
|
|
|
|
|
|
mcp_console_handler = logging.StreamHandler() |
|
|
mcp_console_handler.setFormatter(mcp_formatter) |
|
|
self.mcp_logger.addHandler(mcp_console_handler) |
|
|
|
|
|
|
|
|
self.system_logger = logging.getLogger('system_status') |
|
|
self.system_logger.setLevel(logging.INFO) |
|
|
|
|
|
self.system_logger.handlers.clear() |
|
|
|
|
|
system_handler = logging.FileHandler( |
|
|
os.path.join(self.log_dir, 'system_status.log'), |
|
|
encoding='utf-8' |
|
|
) |
|
|
system_formatter = logging.Formatter( |
|
|
'🏥 %(asctime)s - %(levelname)s - %(message)s' |
|
|
) |
|
|
system_handler.setFormatter(system_formatter) |
|
|
self.system_logger.addHandler(system_handler) |
|
|
|
|
|
|
|
|
system_console_handler = logging.StreamHandler() |
|
|
system_console_handler.setFormatter(system_formatter) |
|
|
self.system_logger.addHandler(system_console_handler) |
|
|
|
|
|
|
|
|
self.error_logger = logging.getLogger('errors') |
|
|
self.error_logger.setLevel(logging.ERROR) |
|
|
|
|
|
self.error_logger.handlers.clear() |
|
|
|
|
|
error_handler = logging.FileHandler( |
|
|
os.path.join(self.log_dir, 'errors.log'), |
|
|
encoding='utf-8' |
|
|
) |
|
|
error_formatter = logging.Formatter( |
|
|
'❌ %(asctime)s - %(levelname)s - %(message)s' |
|
|
) |
|
|
error_handler.setFormatter(error_formatter) |
|
|
self.error_logger.addHandler(error_handler) |
|
|
|
|
|
|
|
|
error_console_handler = logging.StreamHandler() |
|
|
error_console_handler.setFormatter(error_formatter) |
|
|
self.error_logger.addHandler(error_console_handler) |
|
|
|
|
|
def log_user_action(self, action: str, details: Optional[Dict[str, Any]] = None): |
|
|
"""记录用户行为""" |
|
|
message = f"USER_ACTION: {action}" |
|
|
if details: |
|
|
message += f" - Details: {json.dumps(details, ensure_ascii=False)}" |
|
|
self.user_logger.info(message) |
|
|
|
|
|
def log_mcp_connection(self, server_name: str, server_url: str, success: bool, error: Optional[str] = None): |
|
|
"""记录MCP服务器连接""" |
|
|
status = "SUCCESS" if success else "FAILED" |
|
|
message = f"MCP_CONNECTION: {server_name} ({server_url}) - {status}" |
|
|
if error: |
|
|
message += f" - Error: {error}" |
|
|
self.mcp_logger.info(message) |
|
|
|
|
|
def log_mcp_tool_call(self, tool_name: str, input_data: Dict[str, Any], chat_id: Optional[str] = None): |
|
|
"""记录MCP工具调用""" |
|
|
message = f"MCP_TOOL_CALL: {tool_name}" |
|
|
if chat_id: |
|
|
message += f" - ChatID: {chat_id}" |
|
|
message += f" - Input: {json.dumps(input_data, ensure_ascii=False)}" |
|
|
self.mcp_logger.info(message) |
|
|
|
|
|
def log_mcp_tool_response(self, tool_name: str, response_data: Any, chat_id: Optional[str] = None): |
|
|
"""记录MCP工具响应""" |
|
|
message = f"MCP_TOOL_RESPONSE: {tool_name}" |
|
|
if chat_id: |
|
|
message += f" - ChatID: {chat_id}" |
|
|
|
|
|
|
|
|
if isinstance(response_data, str) and len(response_data) > 1000: |
|
|
message += f" - Response: {response_data[:500]}... (truncated, total length: {len(response_data)})" |
|
|
else: |
|
|
message += f" - Response: {json.dumps(response_data, ensure_ascii=False)}" |
|
|
|
|
|
self.mcp_logger.info(message) |
|
|
|
|
|
def log_mcp_agent_usage(self, agent_type: str, tools_used: List[str], chat_id: Optional[str] = None): |
|
|
"""记录MCP代理使用情况""" |
|
|
if agent_type == "ReactAgent": |
|
|
message = f"MCP_AGENT_AVAILABLE: {agent_type}" |
|
|
if chat_id: |
|
|
message += f" - ChatID: {chat_id}" |
|
|
message += f" - Available Tools: {', '.join(tools_used)}" |
|
|
else: |
|
|
message = f"MCP_AGENT_USAGE: {agent_type}" |
|
|
if chat_id: |
|
|
message += f" - ChatID: {chat_id}" |
|
|
message += f" - Tools Used: {', '.join(tools_used)}" |
|
|
self.mcp_logger.info(message) |
|
|
|
|
|
def log_chat_message(self, role: str, content: str, chat_id: Optional[str] = None, has_tool: bool = False): |
|
|
"""记录聊天消息""" |
|
|
message = f"CHAT_MESSAGE: {role.upper()}" |
|
|
if chat_id: |
|
|
message += f" - ChatID: {chat_id}" |
|
|
if has_tool: |
|
|
message += " - HasTool: True" |
|
|
|
|
|
|
|
|
if len(content) > 500: |
|
|
message += f" - Content: {content[:200]}... (truncated, total length: {len(content)})" |
|
|
else: |
|
|
message += f" - Content: {content}" |
|
|
|
|
|
self.user_logger.info(message) |
|
|
|
|
|
def log_llm_test(self, provider: str, success: bool, error: Optional[str] = None): |
|
|
"""记录LLM连接测试""" |
|
|
status = "SUCCESS" if success else "FAILED" |
|
|
message = f"LLM_TEST: {provider} - {status}" |
|
|
if error: |
|
|
message += f" - Error: {error}" |
|
|
self.system_logger.info(message) |
|
|
|
|
|
def log_system_status(self, status: str, details: Optional[Dict[str, Any]] = None): |
|
|
"""记录系统状态""" |
|
|
message = f"SYSTEM_STATUS: {status}" |
|
|
if details: |
|
|
message += f" - Details: {json.dumps(details, ensure_ascii=False)}" |
|
|
self.system_logger.info(message) |
|
|
|
|
|
def log_error(self, error_type: str, error_message: str, context: Optional[Dict[str, Any]] = None): |
|
|
"""记录错误""" |
|
|
message = f"ERROR: {error_type} - {error_message}" |
|
|
if context: |
|
|
message += f" - Context: {json.dumps(context, ensure_ascii=False)}" |
|
|
self.error_logger.error(message) |
|
|
|
|
|
def log_long_running_task(self, task_name: str, duration_seconds: float, chat_id: Optional[str] = None): |
|
|
"""记录长时间运行的任务""" |
|
|
message = f"LONG_RUNNING_TASK: {task_name} - Duration: {duration_seconds:.2f}s" |
|
|
if chat_id: |
|
|
message += f" - ChatID: {chat_id}" |
|
|
self.system_logger.info(message) |
|
|
|
|
|
|
|
|
|
|
|
chat_logger = ChatLogger() |
|
|
|
|
|
|
|
|
def get_logger(): |
|
|
"""获取全局日志记录器""" |
|
|
return chat_logger |