Merge pull request #24 from korjavin/main

Refactor error logging in main.py to structured JSON format with backward compatibility
This commit is contained in:
Eugene Evstafev 2025-10-19 17:16:57 +01:00 committed by GitHub
commit 97884fd1c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 26 additions and 12 deletions

36
main.py
View file

@ -14,6 +14,7 @@ from typing import List, Dict, Optional, Union, Any
import nest_asyncio import nest_asyncio
from dotenv import load_dotenv from dotenv import load_dotenv
from mcp.server.fastmcp import FastMCP from mcp.server.fastmcp import FastMCP
from pythonjsonlogger import jsonlogger
from telethon import TelegramClient, functions, utils from telethon import TelegramClient, functions, utils
from telethon.sessions import StringSession from telethon.sessions import StringSession
from telethon.tl.types import ( from telethon.tl.types import (
@ -78,12 +79,17 @@ try:
file_handler = logging.FileHandler(log_file_path, mode="a") # Append mode file_handler = logging.FileHandler(log_file_path, mode="a") # Append mode
file_handler.setLevel(logging.ERROR) file_handler.setLevel(logging.ERROR)
# Create formatter and add to handlers # Create formatters
formatter = logging.Formatter( # Console formatter remains in the old format
"%(asctime)s [%(levelname)s] %(name)s - %(message)s - %(filename)s:%(lineno)d" console_formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(name)s - %(message)s")
console_handler.setFormatter(console_formatter)
# File formatter is now JSON
json_formatter = jsonlogger.JsonFormatter(
"%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%dT%H:%M:%S%z",
) )
console_handler.setFormatter(formatter) file_handler.setFormatter(json_formatter)
file_handler.setFormatter(formatter)
# Add handlers to logger # Add handlers to logger
logger.addHandler(console_handler) logger.addHandler(console_handler)
@ -140,17 +146,23 @@ def log_and_format_error(
break break
prefix_str = prefix.value if prefix else "GEN" prefix_str = prefix.value if prefix else "GEN"
error_code = f"{prefix_str}-ERR-{abs(hash(function_name)) % 1000:03d}" error_code = f"{prefix_str}-ERR-{abs(hash(function_name)) % 1000:03d}"
# Format the additional context parameters # Log the structured error
context = ", ".join(f"{k}={v}" for k, v in kwargs.items()) log_context = {
"function_name": function_name,
# Log the full technical error "error_code": error_code,
logger.exception(f"{function_name} failed ({context}): {error}") "error_message": str(error),
"parameters": kwargs,
}
logger.error(
f"Error in {function_name}",
extra=log_context,
exc_info=(type(error), error, error.__traceback__),
)
# Return a user-friendly message # Return a user-friendly message
return f"An error occurred (code: {error_code}). " f"Check mcp_errors.log for details." return f"An error occurred (code: {error_code}). Check mcp_errors.log for details."
def format_entity(entity) -> Dict[str, Any]: def format_entity(entity) -> Dict[str, Any]:

View file

@ -29,6 +29,7 @@ dependencies = [
"mcp[cli]>=1.4.1", "mcp[cli]>=1.4.1",
"nest-asyncio>=1.6.0", "nest-asyncio>=1.6.0",
"python-dotenv>=1.1.0", "python-dotenv>=1.1.0",
"python-json-logger>=3.3.0",
"telethon>=1.39.0" "telethon>=1.39.0"
] ]

View file

@ -3,4 +3,5 @@ httpx>=0.28.1
mcp[cli]>=1.4.1 mcp[cli]>=1.4.1
nest-asyncio>=1.6.0 nest-asyncio>=1.6.0
python-dotenv>=1.1.0 python-dotenv>=1.1.0
python-json-logger>=3.3.0
telethon>=1.39.0 telethon>=1.39.0