From d908558f01fd1facfafde10f05bd5d23a86b5836 Mon Sep 17 00:00:00 2001 From: zyc <1439655764@qq.com> Date: Fri, 30 Jan 2026 13:16:37 +0800 Subject: [PATCH] feat: integrate log center error reporting --- utils/exceptions.py | 65 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/utils/exceptions.py b/utils/exceptions.py index 8ba7aaa..dc4a446 100644 --- a/utils/exceptions.py +++ b/utils/exceptions.py @@ -1,11 +1,72 @@ """ 自定义异常处理 """ +import os +import traceback +import threading +import requests from rest_framework.views import exception_handler from rest_framework import status from utils.response import APIResponse +# Log Center 配置 +LOG_CENTER_URL = os.environ.get('LOG_CENTER_URL', 'https://qiyuan-log-center-api.airlabs.art') +LOG_CENTER_ENABLED = os.environ.get('LOG_CENTER_ENABLED', 'true').lower() == 'true' + + +def report_to_log_center(exc, context): + """异步上报错误到 Log Center""" + if not LOG_CENTER_ENABLED: + return + + try: + # 提取堆栈信息 + tb = traceback.extract_tb(exc.__traceback__) if exc.__traceback__ else [] + last_frame = tb[-1] if tb else None + + # 获取请求信息 + request = context.get('request') + request_path = request.path if request else 'unknown' + request_method = request.method if request else 'unknown' + + payload = { + "project_id": "rtc_backend", + "environment": os.environ.get('ENVIRONMENT', 'production'), + "level": "ERROR", + "error": { + "type": type(exc).__name__, + "message": str(exc), + "file_path": last_frame.filename if last_frame else "unknown", + "line_number": last_frame.lineno if last_frame else 0, + "stack_trace": traceback.format_exception(exc) if exc.__traceback__ else [str(exc)] + }, + "context": { + "url": request_path, + "method": request_method, + "view": str(context.get('view', '')), + } + } + + # 异步发送,不阻塞响应 + def send_async(): + try: + requests.post( + f"{LOG_CENTER_URL}/api/v1/logs/report", + json=payload, + timeout=3 + ) + except Exception: + pass # 静默失败 + + thread = threading.Thread(target=send_async) + thread.daemon = True + thread.start() + + except Exception: + pass # 上报失败不影响主业务 + + class BusinessException(Exception): """业务异常""" def __init__(self, code=1, message='业务错误', status_code=status.HTTP_400_BAD_REQUEST): @@ -48,6 +109,10 @@ class ErrorCode: def custom_exception_handler(exc, context): """自定义异常处理器""" + # 上报到 Log Center (仅上报非业务异常) + if not isinstance(exc, BusinessException): + report_to_log_center(exc, context) + # 处理业务异常 if isinstance(exc, BusinessException): return APIResponse(