All checks were successful
Build and Deploy Log Center / build-and-deploy (push) Successful in 1m30s
7.2 KiB
7.2 KiB
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)
{
"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)
{
"status": "ok",
"id": 123,
"fingerprint": "a1b2c3d4e5f6",
"is_new": true
}
已存在 (200) - 重复错误自动去重
{
"status": "duplicate",
"id": 123,
"fingerprint": "a1b2c3d4e5f6",
"is_new": false
}
接入示例
Python (Django / FastAPI)
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:
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)
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<string, unknown>;
}
export function reportError(error: Error, context?: Record<string, unknown>) {
// 解析堆栈信息
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:
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 |
修复失败 |
最佳实践
- 设置超时: 上报请求设置 3 秒超时,避免影响主业务
- 静默失败: 上报失败不应影响用户体验
- 异步上报: 使用异步方式上报,不阻塞主流程
- 添加上下文: 尽量添加有用的上下文信息(用户ID、请求URL等)
- 环境区分: 正确设置
environment字段区分开发/生产
环境变量配置
Python 项目
# .env
LOG_CENTER_URL=http://localhost:8002
ENVIRONMENT=development
JavaScript 项目
# .env
VITE_LOG_CENTER_URL=http://localhost:8002
API 文档
完整 API 文档请访问: http://localhost:8002/docs