# 业务接入指南 本文档说明如何将前端/后端业务接入 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', }); ```