19 KiB
业务接入指南
本文档说明如何将前端/后端业务接入 light-sentry 日志分析系统。
目录
1. 系统架构
┌─────────────────────────────────────────────────────────────┐
│ log.starseekai.cn │
│ │
│ ┌──────────┐ ┌────────────┐ ┌──────────────┐ │
│ │ /manage/ │ │ /grafana/ │ │ /dozzle/ │ │
│ │ 项目管理 │ │ 仪表盘 │ │ 容器日志查看 │ │
│ └────┬─────┘ └─────┬──────┘ └──────┬───────┘ │
│ │ │ │ │
│ ┌────▼────────────────▼────────────────▼───────┐ │
│ │ Nginx 反向代理 │ │
│ │ /api/* → API 服务 (9000) │ │
│ │ /loki/* → Loki (3100) │ │
│ └────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌────────────────▼───────────────────────┐ │
│ │ Light-Sentry API 服务 │ │
│ │ - Sentry SDK 兼容网关 │ │
│ │ - 项目管理 API │ │
│ │ - 一键部署 Agent │ │
│ └────────┬──────────────┬─────────────────┘ │
│ │ │ │
│ ┌────────▼───┐ ┌───────▼──────┐ ┌─────────────┐ │
│ │ Loki │ │ Promtail │ │ Dozzle │ │
│ │ 日志存储 │ │ 中心日志采集 │ │ 容器日志查看 │ │
│ └─────────────┘ └──────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
业务机部署:
┌─────────────────────────────────────────────────┐
│ 业务 ECS 服务器 │
│ │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ Promtail │───►│ 中心 Loki │ │
│ │ (采集容器日志) │ │ log.starseekai.cn│ │
│ └──────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────┐ │
│ │ Dozzle │───► 远程连接中心 Dozzle Agent │
│ │ (本地容器日志) │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────┘
服务入口
| 服务 | 地址 | 说明 |
|---|---|---|
| 项目管理 | https://log.starseekai.cn/manage/ |
可视化管理项目、容器关联、一键部署 |
| Grafana 仪表盘 | https://log.starseekai.cn/grafana/ |
查询 Sentry 日志、容器日志、链路追踪 |
| Dozzle 容器日志 | https://log.starseekai.cn/dozzle/ |
实时查看业务机 Docker 容器日志 |
| Loki 查询 API | https://log.starseekai.cn/loki/loki/api/v1/ |
Loki 原生查询 API |
| SDK 上报地址 | https://log.starseekai.cn/api/{projectId}/store/ |
Sentry SDK 上报端点 |
2. 接入方式概览
light-sentry 完全兼容 Sentry SDK 协议,只需将 SDK 的 DSN(Data Source Name) 指向本系统即可。
接入矩阵
| 场景 | 推荐 SDK | 支持协议 |
|---|---|---|
| 前端浏览器 | Sentry Browser SDK | Store API + Envelope |
| Node.js 后端服务 | Sentry Node SDK | Store API + Envelope |
| Python 后端服务 | Sentry Python SDK | Store API + Envelope |
| Java Spring Boot | Sentry Java SDK | Store API + Envelope |
| Go 服务 | Sentry Go SDK | Store API + Envelope |
DSN 格式
Sentry SDK 要求 DSN 格式为:
https://{public_key}@{host}/{projectId}
| 参数 | 说明 | 示例 |
|---|---|---|
public_key |
认证公钥(可自定义,建议用项目名) | order-frontend、backend-api |
host |
本系统的入口地址 | log.starseekai.cn |
projectId |
必须是纯数字 | 1001、1002、1003 |
重要: Sentry SDK 要求 projectId 必须是纯数字,不支持字母或字符串 ID。
示例 DSN:
# 前端项目
https://order-frontend@log.starseekai.cn/1001
# 后端项目
https://order-backend@log.starseekai.cn/1002
# Python 服务
https://payment-service@log.starseekai.cn/1003
接入流程
1. 在项目管理页面 (https://log.starseekai.cn/manage/) 创建项目
2. 填写纯数字项目 ID(如 1001)
3. 填写 Public Key(可自定义,或留空自动生成)
4. 获取生成的 DSN
5. 在业务代码中配置 SDK
6. 容器日志:通过一键部署或手动配置 Promtail
7. 在 Grafana 仪表盘查看日志
接入建议:前后端分开
建议将前端和后端作为两个独立项目接入:
业务系统
├── 前端项目 → projectId: 1001, publicKey: myapp-frontend
└── 后端项目 → projectId: 1002, publicKey: myapp-backend
分开的好处:
| 维度 | 说明 |
|---|---|
| 日志区分 | 前后端错误分开,一目了然 |
| 采样率 | 前端可设置更高采样(用户行为重要),后端可更低(日志量大) |
| 告警规则 | 前端错误率 > 1% 告警,后端 > 5% 告警 |
| 链路追踪 | 通过 trace_id 仍能串联前后端日志 |
3. 前端接入(Browser SDK)
安装
npm install @sentry/browser
# 或
yarn add @sentry/browser
# 或
pnpm add @sentry/browser
基础接入(HTML 单页)
<script src="https://browser.sentry-cdn.com/7.x.x/bundle.min.js" crossorigin="anonymous"></script>
<script>
Sentry.init({
dsn: 'https://frontend@log.starseekai.cn/1001',
// 推荐采样率:生产环境 10%~50%
tracesSampleRate: 0.1,
// 生产环境关闭调试
debug: false,
// 环境
environment: 'production',
// 版本(用于按版本筛选错误)
release: 'v1.2.3',
});
</script>
React / Vue / Next.js 接入
React(Create React App / Next.js):
import * as Sentry from '@sentry/browser';
import { BrowserTracing } from '@sentry/tracing';
Sentry.init({
dsn: 'https://frontend@log.starseekai.cn/1001',
integrations: [new BrowserTracing()],
tracesSampleRate: 0.1,
environment: process.env.NODE_ENV,
release: process.env.npm_package_version,
});
Vue 3:
import { createApp } from 'vue';
import * as Sentry from '@sentry/browser';
import { VueIntegration } from '@sentry/integrations';
Sentry.init({
dsn: 'https://frontend@log.starseekai.cn/1001',
integrations: [new VueIntegration({ app })],
tracesSampleRate: 0.1,
environment: process.env.NODE_ENV,
});
手动上报错误
// 手动捕获并上报
try {
// 业务代码
JSON.parse('not valid json');
} catch (err) {
Sentry.captureException(err, {
// 自定义额外数据
extra: {
userId: currentUser.id,
action: 'checkout',
},
});
}
// 上报自定义消息
Sentry.captureMessage('用户注册成功', {
level: 'info',
extra: { userId: 12345, plan: 'pro' },
});
添加用户上下文
// 登录时设置
Sentry.setUser({
id: 'user_12345',
email: 'user@example.com',
username: 'john_doe',
ip_address: '{{auto}}', // 自动采集 IP
});
// 登出时清除
Sentry.setUser(null);
4. 后端接入(Node.js SDK)
安装
npm install @sentry/node
# 或
yarn add @sentry/node
Express 接入
const express = require('express');
const Sentry = require('@sentry/node');
const { ExpressIntegration } = require('@sentry/integrations');
const app = express();
// Sentry 必须在其他中间件之前初始化
Sentry.init({
dsn: 'https://backend@log.starseekai.cn/1002',
integrations: [new ExpressIntegration({ app })],
tracesSampleRate: 0.1,
environment: process.env.NODE_ENV,
release: process.env.npm_package_version,
});
// 请求处理中间件(必须)
app.use(Sentry.Handlers.requestHandler());
// 你的业务路由
app.get('/api/order', (req, res) => {
// 业务代码
res.json({ orderId: 'ORD_12345' });
});
// 错误处理中间件(必须)
app.use(Sentry.Handlers.errorHandler());
app.listen(3000);
自动捕获未处理错误和 Promise rejections
// 在 Sentry.init() 之后添加
// 捕获未处理的 Promise rejection
process.on('unhandledRejection', (reason, promise) => {
Sentry.captureException(reason);
});
// 捕获未处理的同步异常
process.on('uncaughtException', (err) => {
Sentry.captureException(err);
process.exit(1);
});
手动上报错误
const Sentry = require('@sentry/node');
async function createOrder(req, res) {
try {
const order = await db.orders.create(req.body);
Sentry.addBreadcrumb({
category: 'db',
message: 'Order created',
data: { orderId: order.id },
});
res.json(order);
} catch (err) {
Sentry.captureException(err, {
// 附加请求上下文
contexts: {
request: {
method: req.method,
url: req.url,
headers: req.headers,
},
},
});
throw err; // 仍需抛出,让 Express 错误中间件处理
}
}
5. Python 接入
安装
pip install sentry-sdk
Django / Flask 接入
Django:
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
dsn='https://python-service@log.starseekai.cn/1003',
integrations=[DjangoIntegration()],
traces_sample_rate=0.1,
environment='production',
release='v1.2.3',
)
Flask:
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
sentry_sdk.init(
dsn='https://python-service@log.starseekai.cn/1003',
integrations=[FlaskIntegration()],
traces_sample_rate=0.1,
environment='production',
)
手动上报
from sentry_sdk import capture_exception, capture_message
try:
1 / 0
except Exception as e:
capture_exception(e)
capture_message('用户登录成功', level='info', extra={'user_id': 12345})
6. 容器日志接入
容器日志通过 Promtail 采集,存储到 Loki,可在 Grafana 和 Dozzle 中查看。
6.1 中心 Promtail(采集本机日志)
适用于日志分析系统所在的 ECS 服务器。
编辑 promtail/promtail-config.yml,修改容器白名单:
scrape_configs:
- docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
# 白名单:只收集以下前缀的容器(多个用 | 分隔)
- source_labels: ['__meta_docker_container_name']
regex: '/(light-sentry-.+|myapp-.+|nginx)'
action: keep
6.2 业务机 Promtail(一键部署)
通过项目管理页面的「一键部署」功能,自动将 Promtail Agent 部署到业务 ECS 服务器。
部署步骤:
- 打开
https://log.starseekai.cn/manage/ - 编辑项目,填写「关联容器名称」或「容器过滤正则」
- 点击「一键部署」,填写业务机 SSH 信息
- 系统自动完成:SSH 连接 → 生成配置 → 部署 Promtail → 重启 Dozzle Agent
6.3 Dozzle 容器过滤
Dozzle 默认只显示 light-sentry-* 前缀的容器。修改 .env 可调整:
# 格式:key=value,支持正则,多个用逗号分隔
DOZZLE_FILTER=name=light-sentry-.+|myapp-.+|nginx
6.4 Grafana 中查询容器日志
Promtail 采集的日志带以下标签:
| 标签 | 说明 |
|---|---|
host |
主机名 |
source |
container 标识为容器日志 |
container_name |
Docker 容器名称 |
container_image |
Docker 镜像名称 |
composed_project |
Docker Compose 项目名 |
docker_service |
Docker Compose 服务名 |
查询示例:
# 按容器名查询
{container_name="myapp-web"}
# 按镜像名查询
{container_image=~"nginx.*"}
# 组合 Sentry 项目 + 容器日志
{container_name=~"myapp-.*", host="prod-ecs"}
# 查看该容器最近 1 小时的日志
{container_name="myapp-web"} |= "ERROR" | __error__!="JSONErr"
7. 项目与容器关联
7.1 关联步骤
- 打开项目管理页面
https://log.starseekai.cn/manage/ - 编辑项目,填写容器信息:
- 关联容器名称:精确匹配容器名,多个用逗号分隔
- 容器过滤正则(可选):支持正则表达式,优先级更高
| 关联方式 | 示例 | 说明 |
|---|---|---|
| 单容器 | myapp-web |
只采集指定容器 |
| 多容器 | myapp-web, myapp-api |
逗号分隔 |
| 正则匹配 | myapp-.* |
匹配所有 myapp- 开头的容器 |
7.2 接入声明
项目管理页面提供一键复制功能,包含:
- SDK 接入代码片段
- 完整的 DSN 地址
- Grafana 仪表盘跳转链接
- Dozzle 容器日志跳转链接
7.3 项目管理 API
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/api/projects/ |
列出所有项目 |
GET |
/api/projects/:id |
获取单个项目详情 |
POST |
/api/projects/ |
创建新项目 |
PUT |
/api/projects/:id |
更新项目信息 |
DELETE |
/api/projects/:id |
删除项目 |
创建项目示例:
curl -X POST https://log.starseekai.cn/api/projects/ \
-H "Content-Type: application/json" \
-d '{
"id": "order-service",
"name": "订单服务",
"platform": "node",
"environment": "production",
"description": "处理订单创建和支付",
"containerName": "order-service-web, order-service-worker"
}'
8. 一键部署业务机
通过项目管理页面的「一键部署」功能,将 Promtail Agent 和 Dozzle Agent 自动部署到业务 ECS 服务器。
8.1 部署流程
1. 用户在页面填写业务机 SSH 信息(IP、用户名、密码)
2. 后端启动异步部署任务
3. SSH 连接业务机
4. 创建部署目录、生成 Promtail/Dozzle 配置
5. SCP 上传配置文件和 docker-compose.yml
6. 启动容器
7. 同步 Agent 信息到中心 Dozzle
8. 实时 SSE 推送部署日志到前端
8.2 部署配置说明
Loki Push 地址:由项目管理页面的「中心 Loki 地址」配置,默认为 https://log.starseekai.cn/loki/loki/api/v1/push
部署目录:默认 /opt/light-sentry-agent,可在部署时自定义
容器过滤:根据项目关联的容器名自动生成 Promtail 过滤正则
8.3 部署目录结构
/opt/light-sentry-agent/
├── docker-compose.yml # Dozzle Agent
├── promtail/
│ └── promtail-config.yml # Promtail 配置
└── .env # 环境变量(DOZZLE_REMOTE_AGENT)
8.4 查看部署历史
部署历史可在项目管理页面查看,包含:
- 部署时间、目标主机
- 部署状态(成功/失败)
- 实时部署日志
- 容器过滤配置
9. 常见问题
Q: SDK 上报后看不到日志
排查步骤:
- 检查浏览器控制台是否有 Sentry 报错
- 确认 DSN 是否正确:
https://{publicKey}@log.starseekai.cn/{projectId} - 确认
projectId是否是纯数字(如1001) - 在 Grafana Explore 中直接查询原始日志:
{platform="javascript"}
Q: 容器日志没有采集到
排查步骤:
- 确认 Promtail 容器是否在运行:
docker ps | grep promtail - 检查 Promtail 日志:
docker logs light-sentry-promtail - 确认容器名是否在白名单中
- 检查 Loki 是否收到数据:
curl http://localhost:3100/loki/api/v1/label/container_name/values
Q: 一键部署失败
常见原因:
- SSH 密码错误或 IP 无法连接
- 目标目录权限不足(确保 SSH 用户有
/opt写权限) - Docker 未安装或未启动
解决方案:
- 手动检查 SSH 连接:
ssh user@host - 检查目标目录权限:
ls -la /opt/ - 查看部署日志中的详细错误信息
Q: 生产环境建议采样率是多少?
| 环境 | tracesSampleRate | 说明 |
|---|---|---|
| 开发/测试 | 1.0 |
全量采集,方便调试 |
| 预发/灰度 | 0.5 |
采集一半 |
| 生产 | 0.05 ~ 0.2 |
5%~20%,平衡性能和数据量 |
Q: 如何在 Grafana 中切换项目查看?
在 Grafana 仪表盘顶部有 项目 下拉框,选择后可按项目过滤日志。仪表盘地址格式:
https://log.starseekai.cn/grafana/d/light-sentry-logs?var-project=1
其中 var-project 参数值为项目 ID。
Q: 日志量会不会太大?
假设:
- 每小时 10000 次 API 请求
- tracesSampleRate = 0.1(10%)
- 每条 trace 上报 3~5 条日志
- 每条日志约 2KB
月流量 ≈ 10000 × 0.1 × 4 × 2KB × 24h × 30d ≈ 57 MB
非常轻量,2核2G 完全没压力。
Q: 如何添加自定义标签?
// 设置全局标签(所有事件都会带)
Sentry.setTag('server', 'production');
Sentry.setTag('region', 'cn-hangzhou');
// 设置用户级别标签
Sentry.setContext('order', {
orderId: 'ORD_12345',
amount: 99.9,
currency: 'CNY',
});