39 lines
1.4 KiB
Python
39 lines
1.4 KiB
Python
import json
|
|
import logging
|
|
import traceback
|
|
from typing import Optional, Dict, Any
|
|
from db.database import get_db_pool
|
|
from core.metrics import ERRORS_TOTAL
|
|
|
|
logger = logging.getLogger("copykar.errors")
|
|
|
|
async def log_exception(service_name: str, error: Exception, context: Optional[Dict[str, Any]] = None):
|
|
"""Log an exception to Database, Prometheus metrics, and Python logs."""
|
|
error_type = type(error).__name__
|
|
error_msg = str(error)
|
|
tb_str = traceback.format_exc()
|
|
ctx_json = json.dumps(context or {}, default=str)
|
|
|
|
# 1. Prometheus Metric
|
|
try:
|
|
ERRORS_TOTAL.labels(service=service_name, error_type=error_type).inc()
|
|
except Exception as e:
|
|
logger.debug(f"Failed to increment error metric: {e}")
|
|
|
|
# 2. Python standard logger
|
|
logger.error(f"[{service_name}] {error_type}: {error_msg}\nContext: {ctx_json}\n{tb_str}")
|
|
|
|
# 3. PostgreSQL Database
|
|
try:
|
|
pool = await get_db_pool()
|
|
async with pool.acquire() as conn:
|
|
await conn.execute(
|
|
"""
|
|
INSERT INTO error_logs (service_name, error_type, error_message, traceback, context)
|
|
VALUES ($1, $2, $3, $4, $5::jsonb);
|
|
""",
|
|
service_name, error_type, error_msg, tb_str, ctx_json
|
|
)
|
|
except Exception as db_err:
|
|
logger.critical(f"Failed to write error to database: {db_err}")
|