# Log Center 接入指南 ## 概述 Log Center 是一个集中式错误日志收集平台,提供 REST API 供各项目接入,实现运行时错误的统一收集、去重、追踪和分析。 --- ## 快速开始 ### 服务地址 | 环境 | API 地址 | 仪表盘 | |------|----------|--------| | 本地开发 | `http://localhost:8002` | `http://localhost:8003` | | 生产环境 | `https://log.yourcompany.com` | `https://log.yourcompany.com` | --- ## API 接口 ### 上报错误日志 **POST** `/api/v1/logs/report` #### 请求体 (JSON) ```json { "project_id": "rtc_backend", "environment": "production", "level": "ERROR", "timestamp": "2026-01-30T10:30:00Z", "version": "1.2.3", "commit_hash": "abc1234", "error": { "type": "ValueError", "message": "invalid literal for int() with base 10: 'abc'", "file_path": "apps/users/views.py", "line_number": 42, "stack_trace": [ "Traceback (most recent call last):", " File \"apps/users/views.py\", line 42, in get_user", " user_id = int(request.GET['id'])", "ValueError: invalid literal for int() with base 10: 'abc'" ] }, "context": { "url": "/api/users/123", "method": "GET", "user_id": "u_12345", "request_id": "req_abc123" } } ``` #### 字段说明 | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `project_id` | string | ✅ | 项目标识,如 `rtc_backend`, `rtc_web` | | `environment` | string | ✅ | 环境:`development`, `staging`, `production` | | `level` | string | ✅ | 日志级别:`ERROR`, `WARNING`, `CRITICAL` | | `timestamp` | string | ❌ | ISO 8601 格式,不传则使用服务器时间 | | `version` | string | ❌ | 应用版本号 | | `commit_hash` | string | ❌ | Git commit hash | | `error.type` | string | ✅ | 异常类型,如 `ValueError`, `TypeError` | | `error.message` | string | ✅ | 错误消息 | | `error.file_path` | string | ✅ | 出错文件路径 | | `error.line_number` | int | ✅ | 出错行号 | | `error.stack_trace` | array | ✅ | 堆栈信息(数组或字符串) | | `context` | object | ❌ | 额外上下文信息(URL、用户ID等) | #### 响应 **成功 (200)** ```json { "status": "ok", "id": 123, "fingerprint": "a1b2c3d4e5f6", "is_new": true } ``` **已存在 (200)** - 重复错误自动去重 ```json { "status": "duplicate", "id": 123, "fingerprint": "a1b2c3d4e5f6", "is_new": false } ``` --- ## 接入示例 ### Python (Django / FastAPI) ```python import requests import traceback import os LOG_CENTER_URL = os.getenv("LOG_CENTER_URL", "http://localhost:8002") def report_error(exc, context=None): """上报错误到 Log Center""" tb = traceback.extract_tb(exc.__traceback__) last_frame = tb[-1] if tb else None payload = { "project_id": "rtc_backend", "environment": os.getenv("ENVIRONMENT", "development"), "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) }, "context": context or {} } try: requests.post( f"{LOG_CENTER_URL}/api/v1/logs/report", json=payload, timeout=3 # 快速失败,不影响主业务 ) except Exception: pass # 静默失败,不影响主业务 ``` #### Django 集成位置 修改 `utils/exceptions.py` 的 `custom_exception_handler`: ```python def custom_exception_handler(exc, context): # 上报到 Log Center (异步,不阻塞响应) report_error(exc, { "view": str(context.get("view")), "request_path": context.get("request").path if context.get("request") else None, }) # ... 原有逻辑不变 ... ``` --- ### JavaScript / TypeScript (React / Vue) ```typescript const LOG_CENTER_URL = import.meta.env.VITE_LOG_CENTER_URL || 'http://localhost:8002'; interface ErrorPayload { project_id: string; environment: string; level: string; error: { type: string; message: string; file_path: string; line_number: number; stack_trace: string[]; }; context?: Record; } export function reportError(error: Error, context?: Record) { // 解析堆栈信息 const stackLines = error.stack?.split('\n') || []; const match = stackLines[1]?.match(/at\s+.*\s+\((.+):(\d+):\d+\)/); const payload: ErrorPayload = { project_id: 'rtc_web', environment: import.meta.env.MODE, level: 'ERROR', error: { type: error.name, message: error.message, file_path: match?.[1] || 'unknown', line_number: parseInt(match?.[2] || '0'), stack_trace: stackLines, }, context: { url: window.location.href, userAgent: navigator.userAgent, ...context, }, }; // 使用 sendBeacon 确保页面关闭时也能发送 if (navigator.sendBeacon) { navigator.sendBeacon( `${LOG_CENTER_URL}/api/v1/logs/report`, JSON.stringify(payload) ); } else { fetch(`${LOG_CENTER_URL}/api/v1/logs/report`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), keepalive: true, }).catch(() => {}); } } ``` #### Axios 拦截器集成 修改 `src/api/request.ts`: ```typescript request.interceptors.response.use( (response) => { /* ... */ }, (error: AxiosError) => { // 上报到 Log Center reportError(error, { url: error.config?.url, method: error.config?.method, status: error.response?.status, }); // ... 原有逻辑不变 ... } ); ``` --- ## 错误去重机制 Log Center 使用 **指纹(fingerprint)** 对错误进行去重: ``` fingerprint = MD5(project_id + error_type + file_path + line_number) ``` 相同指纹的错误只会记录一次,后续只更新计数和最后出现时间。 --- ## 错误状态流转 ``` NEW → VERIFYING → PENDING_FIX → FIXING → FIXED → VERIFIED → DEPLOYED ↓ ↓ CANNOT_REPRODUCE FIX_FAILED ``` | 状态 | 说明 | |------|------| | `NEW` | 新上报的错误 | | `VERIFYING` | 正在验证复现 | | `CANNOT_REPRODUCE` | 无法复现 | | `PENDING_FIX` | 等待修复 | | `FIXING` | 正在修复中 | | `FIXED` | 已修复,待验证 | | `VERIFIED` | 已验证修复 | | `DEPLOYED` | 已部署上线 | | `FIX_FAILED` | 修复失败 | --- ## 最佳实践 1. **设置超时**: 上报请求设置 3 秒超时,避免影响主业务 2. **静默失败**: 上报失败不应影响用户体验 3. **异步上报**: 使用异步方式上报,不阻塞主流程 4. **添加上下文**: 尽量添加有用的上下文信息(用户ID、请求URL等) 5. **环境区分**: 正确设置 `environment` 字段区分开发/生产 --- ## 环境变量配置 ### Python 项目 ```bash # .env LOG_CENTER_URL=http://localhost:8002 ENVIRONMENT=development ``` ### JavaScript 项目 ```bash # .env VITE_LOG_CENTER_URL=http://localhost:8002 ``` --- ## API 文档 完整 API 文档请访问: [http://localhost:8002/docs](http://localhost:8002/docs)