# 业务接入指南
本文档说明如何将前端/后端业务接入 light-sentry 日志分析系统。
---
## 目录
1. [系统架构](#1-系统架构)
2. [接入方式概览](#2-接入方式概览)
3. [前端接入(Browser SDK)](#3-前端接入browser-sdk)
4. [后端接入(Node.js SDK)](#4-后端接入nodejs-sdk)
5. [Python 接入](#5-python-接入)
6. [容器日志接入](#6-容器日志接入)
7. [项目与容器关联](#7-项目与容器关联)
8. [一键部署业务机](#8-一键部署业务机)
9. [常见问题](#9-常见问题)
---
## 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:**
```bash
# 前端项目
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)
### 安装
```bash
npm install @sentry/browser
# 或
yarn add @sentry/browser
# 或
pnpm add @sentry/browser
```
### 基础接入(HTML 单页)
```html
```
### React / Vue / Next.js 接入
**React(Create React App / Next.js):**
```javascript
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:**
```javascript
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,
});
```
### 手动上报错误
```javascript
// 手动捕获并上报
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' },
});
```
### 添加用户上下文
```javascript
// 登录时设置
Sentry.setUser({
id: 'user_12345',
email: 'user@example.com',
username: 'john_doe',
ip_address: '{{auto}}', // 自动采集 IP
});
// 登出时清除
Sentry.setUser(null);
```
---
## 4. 后端接入(Node.js SDK)
### 安装
```bash
npm install @sentry/node
# 或
yarn add @sentry/node
```
### Express 接入
```javascript
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
```javascript
// 在 Sentry.init() 之后添加
// 捕获未处理的 Promise rejection
process.on('unhandledRejection', (reason, promise) => {
Sentry.captureException(reason);
});
// 捕获未处理的同步异常
process.on('uncaughtException', (err) => {
Sentry.captureException(err);
process.exit(1);
});
```
### 手动上报错误
```javascript
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 接入
### 安装
```bash
pip install sentry-sdk
```
### Django / Flask 接入
**Django:**
```python
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:**
```python
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',
)
```
### 手动上报
```python
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`,修改容器白名单:
```yaml
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 服务器。
**部署步骤:**
1. 打开 `https://log.starseekai.cn/manage/`
2. 编辑项目,填写「关联容器名称」或「容器过滤正则」
3. 点击「一键部署」,填写业务机 SSH 信息
4. 系统自动完成:SSH 连接 → 生成配置 → 部署 Promtail → 重启 Dozzle Agent
### 6.3 Dozzle 容器过滤
Dozzle 默认只显示 `light-sentry-*` 前缀的容器。修改 `.env` 可调整:
```bash
# 格式: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 服务名 |
**查询示例:**
```logql
# 按容器名查询
{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 关联步骤
1. 打开项目管理页面 `https://log.starseekai.cn/manage/`
2. 编辑项目,填写容器信息:
- **关联容器名称**:精确匹配容器名,多个用逗号分隔
- **容器过滤正则**(可选):支持正则表达式,优先级更高
| 关联方式 | 示例 | 说明 |
|---------|------|------|
| 单容器 | `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` | 删除项目 |
**创建项目示例:**
```bash
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 上报后看不到日志
**排查步骤:**
1. 检查浏览器控制台是否有 Sentry 报错
2. 确认 DSN 是否正确:`https://{publicKey}@log.starseekai.cn/{projectId}`
3. 确认 `projectId` 是否是纯数字(如 `1001`)
4. 在 Grafana Explore 中直接查询原始日志:
```logql
{platform="javascript"}
```
### Q: 容器日志没有采集到
**排查步骤:**
1. 确认 Promtail 容器是否在运行:`docker ps | grep promtail`
2. 检查 Promtail 日志:`docker logs light-sentry-promtail`
3. 确认容器名是否在白名单中
4. 检查 Loki 是否收到数据:`curl http://localhost:3100/loki/api/v1/label/container_name/values`
### Q: 一键部署失败
**常见原因:**
1. SSH 密码错误或 IP 无法连接
2. 目标目录权限不足(确保 SSH 用户有 `/opt` 写权限)
3. 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: 如何添加自定义标签?
```javascript
// 设置全局标签(所有事件都会带)
Sentry.setTag('server', 'production');
Sentry.setTag('region', 'cn-hangzhou');
// 设置用户级别标签
Sentry.setContext('order', {
orderId: 'ORD_12345',
amount: 99.9,
currency: 'CNY',
});
```