light-sentry-sdk/docs/ARCHITECTURE.md

16 KiB
Raw Blame History

Light-Sentry 日志分析系统设计文档

1. 项目概述

1.1 背景

基于用户需求,需要构建一个日志分析系统,支持接收 Sentry 前后端 SDK 的上报,并在 2核2G ECS + 阿里云OSS 的资源限制下稳定运行。

1.2 核心目标

  • 兼容性:完全兼容 Sentry SDK 的上报协议DSN、事件格式
  • 轻量级:适配 2核2G 服务器资源
  • 低成本:利用阿里云 OSS 进行冷存储,降低成本
  • 可视化:提供友好的日志查询和可视化界面

2. 系统架构

2.1 整体架构图

┌─────────────────────────────────────────────────────────────────────┐
│                        客户端 SDK 层                                │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐            │
│  │  Browser SDK │  │   Node SDK   │  │   Python SDK │            │
│  │  @sentry/browser │  @sentry/node │  @sentry/python │          │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘            │
│         │                 │                 │                       │
│         └─────────────────┼─────────────────┘                       │
│                           ▼                                         │
│              ┌───────────────────────┐                             │
│              │     Sentry API 网关   │                             │
│              │  /api/{project}/store │                             │
│              └───────────┬───────────┘                             │
└───────────────────────────┼─────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         服务端处理层                                │
│  ┌──────────────────┐  ┌──────────────────┐                       │
│  │   事件处理器     │──▶│   事件转换器     │                       │
│  │  (Event Handler)│   │ (Event Converter)│                       │
│  └──────────────────┘  └──────────┬───────┘                       │
│                                   │                                 │
│           ┌───────────────────────┼───────────────────────┐        │
│           ▼                       ▼                       ▼        │
│  ┌───────────────┐    ┌───────────────┐    ┌───────────────┐      │
│  │   Loki 索引   │    │   Loki 存储   │    │   OSS 持久化  │      │
│  │   (索引元数据) │    │  (近期日志)   │    │  (历史归档)   │      │
│  └───────────────┘    └───────────────┘    └───────────────┘      │
└─────────────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         可视化查询层                                │
│                      ┌───────────────┐                             │
│                      │   Grafana     │                             │
│                      │  (查询/图表)   │                             │
│                      └───────────────┘                             │
└─────────────────────────────────────────────────────────────────────┘

2.2 核心组件说明

组件 技术选型 角色 资源占用
API网关 Express/FastAPI 接收Sentry协议上报 ~100MB
日志存储 Loki 索引和近期日志存储 ~500MB
持久化层 阿里云OSS 历史日志归档 按需扩展
可视化 Grafana 日志查询和图表展示 ~300MB

总内存预估~1GB保留1GB给系统和缓冲


3. 技术方案

3.1 Sentry 协议兼容层

3.1.1 协议说明

Sentry SDK 使用 DSN (Data Source Name) 配置上报地址:

{PROTOCOL}://{PUBLIC_KEY}@{HOST}/{PATH}/{PROJECT_ID}

SDK 向 /api/{PROJECT_ID}/store/ 端点发送 POST 请求,数据格式为 JSON。

3.1.2 事件数据结构(简化版)

{
  "event_id": "abc123...",
  "timestamp": "2024-01-01T00:00:00Z",
  "level": "error",
  "logger": "javascript",
  "platform": "javascript",
  "message": "Uncaught TypeError: Cannot read property",
  "exception": {
    "values": [{
      "type": "TypeError",
      "value": "Cannot read property 'x' of undefined",
      "stacktrace": {
        "frames": [{
          "filename": "app.js",
          "lineno": 42,
          "function": "doSomething"
        }]
      }
    }]
  },
  "tags": {
    "environment": "production",
    "release": "v1.0.0"
  },
  "contexts": {
    "request": {
      "url": "https://example.com/page",
      "method": "GET"
    },
    "user": {
      "id": "12345",
      "email": "user@example.com"
    }
  }
}

3.1.3 API 网关设计

技术选型Node.js + Express轻量级内存占用低

核心端点

端点 方法 功能
/api/:projectId/store/ POST 接收 Sentry SDK 上报事件
/health GET 健康检查

设计要点

  • 支持 Sentry 的 DSN 认证(通过 X-Sentry-Auth 头或查询参数)
  • 异步处理,不阻塞请求响应
  • 事件格式校验和标准化
  • 支持批量上报

3.2 日志存储方案

3.2.1 Loki 配置

为什么选择 Loki

  • 轻量级,内存占用远低于 ELKElasticsearch 需要至少 4GB
  • 基于标签索引,查询效率高
  • 与 Grafana 无缝集成
  • 支持 OSS 作为后端存储

关键配置

auth_enabled: false

server:
  http_listen_port: 3100

ingester:
  lifecycler:
    address: 127.0.0.1
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1
    final_sleep: 0s
  chunk_idle_period: 1h
  chunk_retain_period: 30s
  max_transfer_retries: 0

schema_config:
  configs:
    - from: 2024-01-01
      store: boltdb-shipper
      object_store: aws
      schema: v11
      index:
        prefix: loki_index_
        period: 24h

storage_config:
  aws:
    s3: s3://{AK}:{SK}@{REGION}/{BUCKET}
    s3forcepathstyle: true
  boltdb_shipper:
    active_index_directory: /data/loki/index
    cache_location: /data/loki/cache
    shared_store: s3

limits_config:
  reject_old_samples: true
  reject_old_samples_max_age: 168h

chunk_store_config:
  max_look_back_period: 0s

table_manager:
  retention_deletes_enabled: true
  retention_period: 30d

3.2.2 OSS 存储策略

存储层级

层级 用途 存储类型 成本
标准存储 近期日志30天内 OSS标准 0.12元/GB/月
低频存储 中期日志30-90天 OSS低频 0.07元/GB/月
归档存储 历史日志90天以上 OSS归档 0.014元/GB/月

生命周期管理

<LifecycleConfiguration>
  <Rule>
    <ID>transition-to-infrequent-access</ID>
    <Filter>
      <Prefix>loki/</Prefix>
    </Filter>
    <Status>Enabled</Status>
    <Transition>
      <Days>30</Days>
      <StorageClass>IA</StorageClass>
    </Transition>
    <Transition>
      <Days>90</Days>
      <StorageClass>Archive</StorageClass>
    </Transition>
    <Expiration>
      <Days>365</Days>
    </Expiration>
  </Rule>
</LifecycleConfiguration>

3.3 事件处理流程

SDK上报 → API网关 → 格式校验 → 标签提取 → Loki写入 → OSS持久化
                                      ↓
                               索引元数据存储

标签提取策略(用于 Loki 查询):

标签名 来源字段 用途
project project_id 项目隔离
environment tags.environment 环境区分
level level 日志级别过滤
platform platform 平台分类
release tags.release 版本追踪
logger logger 日志来源

3.4 可视化方案

3.4.1 Grafana 配置

数据源配置

  • 类型Loki
  • URLhttp://localhost:3100
  • 认证:无

查询示例

// 查询所有 error 级别日志
{level="error"} |= "error"

// 查询特定项目的日志
{project="my-project", environment="production"}

// 查询包含特定错误信息的日志
{level="error"} |= "TypeError"

// 统计错误数量
count_over_time({level="error"}[1m])

仪表盘设计

面板 功能 查询
错误趋势 实时错误数量折线图 count_over_time({level="error"}[1m])
环境分布 各环境错误占比饼图 sum(count_over_time({level="error"}[1h])) by (environment)
平台分布 各平台错误占比饼图 sum(count_over_time({level="error"}[1h])) by (platform)
最新错误 最近错误列表 `{level="error"}
Top错误类型 错误类型排名 topk(5, count by (exception_type) (count_over_time({level="error"}[1h])))

4. 部署方案

4.1 服务器配置

ECS 规格2核2G阿里云 ecs.g6.large 或同等规格)

操作系统Ubuntu 22.04 LTS

磁盘配置

  • 系统盘40GB SSD
  • 数据盘20GB SSD用于 Loki 索引缓存)

4.2 资源分配

组件 CPU 内存
系统预留 0.5核 512MB
API网关 (Node.js) 0.5核 256MB
Loki 1核 768MB
Grafana 0.5核 512MB

4.3 Docker Compose 部署

version: '3.8'

services:
  light-sentry-api:
    image: light-sentry/api:latest
    ports:
      - "9000:9000"
    environment:
      - LOKI_URL=http://loki:3100
      - OSS_ENDPOINT=${OSS_ENDPOINT}
      - OSS_ACCESS_KEY=${OSS_ACCESS_KEY}
      - OSS_SECRET_KEY=${OSS_SECRET_KEY}
      - OSS_BUCKET=${OSS_BUCKET}
    depends_on:
      - loki
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 256M

  loki:
    image: grafana/loki:2.9.0
    ports:
      - "3100:3100"
    volumes:
      - ./loki/config:/etc/loki
      - ./loki/data:/data/loki
    environment:
      - AWS_ACCESS_KEY_ID=${OSS_ACCESS_KEY}
      - AWS_SECRET_ACCESS_KEY=${OSS_SECRET_KEY}
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 768M

  grafana:
    image: grafana/grafana:10.2.0
    ports:
      - "3000:3000"
    volumes:
      - ./grafana/data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
    depends_on:
      - loki
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

4.4 Nginx 反向代理

server {
    listen 80;
    server_name logs.example.com;

    location /api/ {
        proxy_pass http://localhost:9000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        client_max_body_size 10m;
    }

    location /grafana/ {
        proxy_pass http://localhost:3000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

5. SDK 接入指南

5.1 前端 SDK 配置

import * as Sentry from '@sentry/browser';

Sentry.init({
  dsn: 'https://public_key@logs.example.com/api/1/store/',
  environment: 'production',
  release: 'v1.0.0',
  tracesSampleRate: 1.0,
});

5.2 后端 SDK 配置Node.js

import * as Sentry from '@sentry/node';

Sentry.init({
  dsn: 'https://public_key@logs.example.com/api/2/store/',
  environment: 'production',
  release: 'v1.0.0',
  tracesSampleRate: 1.0,
});

5.3 后端 SDK 配置Python

import sentry_sdk

sentry_sdk.init(
    dsn="https://public_key@logs.example.com/api/3/store/",
    environment="production",
    release="v1.0.0",
    traces_sample_rate=1.0,
)

6. 性能优化策略

6.1 内存优化

策略 说明
Loki 使用 OSS 作为后端 减少本地磁盘和内存占用
API网关使用流处理 避免一次性加载大请求
限制并发连接数 使用 Nginx 限流

6.2 存储优化

策略 说明
OSS 生命周期管理 自动降级存储类型
Loki 压缩 启用 Snappy 压缩
日志采样 高频日志采样处理

6.3 查询优化

策略 说明
标签索引 使用标签过滤而非全文搜索
查询缓存 Grafana 缓存查询结果
时间范围限制 默认查询最近24小时

7. 监控与告警

7.1 健康检查

检查项 端点 频率
API网关 /health 30秒
Loki /ready 30秒
Grafana /api/health 30秒

7.2 告警规则

告警项 条件 通知方式
API错误率 错误率 > 5% 钉钉/邮件
服务不可用 健康检查失败 钉钉/邮件
内存使用率 内存 > 85% 钉钉/邮件
OSS存储告警 存储 > 80% 阿里云告警

8. 安全策略

8.1 认证授权

  • API 网关支持 Sentry DSN 认证
  • Grafana 启用基础认证
  • Nginx 配置访问控制列表

8.2 数据加密

  • 传输层HTTPS/TLS 1.2+
  • 存储层OSS 服务端加密SSE-KMS

8.3 访问日志

  • Nginx 访问日志记录
  • API 网关请求日志

9. 成本预估

9.1 服务器成本

资源 规格 月费用
ECS 2核2G ~80元
数据盘 20GB SSD ~10元
合计 - ~90元/月

9.2 OSS 存储成本

假设日日志量1GB

存储类型 容量 月费用
标准存储 30GB ~3.6元
低频存储 60GB ~4.2元
归档存储 275GB ~3.85元
合计 - ~11.65元/月

9.3 总成本

~100元/月(含服务器和存储)


10. 扩展规划

10.1 短期3个月内

  • 完成核心功能开发
  • 集成 Sentry 协议
  • 部署上线

10.2 中期6个月内

  • 增加日志采样功能
  • 优化查询性能
  • 增加告警功能

10.3 长期1年内

  • 支持更多日志来源
  • 增加分布式追踪
  • 考虑升级到更强配置

附录:组件版本建议

组件 推荐版本 备注
Node.js 20.x LTS API网关运行环境
Express 4.x API框架
Loki 2.9.x 日志存储
Grafana 10.x 可视化
Docker 24.x 容器化部署

文档版本: v1.0
创建日期: 2026-06-16
适用场景: 2核2G ECS + 阿里云OSS 资源受限环境