# Sentry Self-Hosted - 崩溃收集与错误追踪

100% 自主可控的崩溃收集与错误追踪系统。

## 功能特性

- **崩溃收集**: 自动捕获 Flutter + Android/iOS 原生层崩溃
- **符号化**: 自动解析混淆后的堆栈，定位到源代码
- **设备信息**: 收集设备型号、系统版本、内存等兼容性信息
- **性能监控**: 页面加载、API 响应时间等性能指标
- **Session Replay**: 重放用户操作轨迹（可选）
- **告警通知**: 崩溃告警推送到邮件/钉钉等

## 系统要求

- Docker 20.10+
- Docker Compose v2+
- **最低 4GB 内存，推荐 8GB+**
- 约 20GB 磁盘空间

## 快速开始

### 1. 首次安装

```bash
cd backend/infrastructure/sentry

# 初始化 (会创建管理员账号)
./deploy.sh init
```

按提示输入管理员邮箱和密码。

### 2. 启动服务

```bash
./deploy.sh up
```

### 3. 访问 Web UI

打开浏览器访问: http://localhost:9000

使用初始化时创建的管理员账号登录。

### 4. 创建项目

1. 登录后点击 "Create Project"
2. 选择平台: **Flutter**
3. 记录生成的 **DSN** (Data Source Name)

DSN 格式示例:
```
http://your_public_key@localhost:9000/project_id
```

## 目录结构

```
sentry/
├── docker-compose.yml      # Docker 编排
├── deploy.sh               # 部署脚本
├── .env.example            # 环境变量模板
├── sentry.conf.py          # Sentry 配置
├── README.md               # 本文档
│
├── clickhouse/
│   └── config.xml          # ClickHouse 配置
│
├── relay/
│   ├── config.yml          # Relay 配置
│   └── credentials.json    # Relay 凭证
│
└── symbolicator/
    └── config.yml          # Symbolicator 配置
```

## 常用命令

```bash
# 启动
./deploy.sh up

# 停止
./deploy.sh down

# 查看状态
./deploy.sh status

# 查看日志
./deploy.sh logs
./deploy.sh logs sentry-web

# 升级
./deploy.sh upgrade
```

## 架构说明

```
                                    ┌─────────────────┐
                                    │   Flutter App   │
                                    │  sentry_flutter │
                                    └────────┬────────┘
                                             │
                                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                            Sentry Relay                              │
│                         (事件接收网关 :3000)                          │
└────────────────────────────────┬────────────────────────────────────┘
                                 │
         ┌───────────────────────┼───────────────────────┐
         │                       │                       │
         ▼                       ▼                       ▼
┌─────────────────┐   ┌─────────────────┐   ┌─────────────────┐
│      Kafka      │   │   Sentry Web    │   │  Symbolicator   │
│   (事件队列)     │   │  (Web UI :9000) │   │   (符号化服务)   │
└────────┬────────┘   └────────┬────────┘   └─────────────────┘
         │                     │
         │            ┌────────┴────────┐
         │            │                 │
         ▼            ▼                 ▼
┌─────────────────┐   ┌─────────────────┐
│    ClickHouse   │   │   PostgreSQL    │
│   (事件存储)     │   │   (元数据)       │
└─────────────────┘   └─────────────────┘
```

## 生产环境配置

### 1. 修改密钥

编辑 `.env` 文件:

```bash
# 生成强密钥
SENTRY_SECRET_KEY=$(openssl rand -hex 32)
SENTRY_DB_PASSWORD=$(openssl rand -hex 16)
```

### 2. 配置域名

如果需要公网访问，配置反向代理:

```nginx
# /etc/nginx/conf.d/sentry.conf
server {
    listen 443 ssl;
    server_name sentry.your-domain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://localhost:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# Relay 端口 (SDK 上报)
server {
    listen 443 ssl;
    server_name sentry-relay.your-domain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

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

### 3. 配置邮件告警

编辑 `.env` 文件:

```bash
SENTRY_EMAIL_HOST=smtp.example.com
SENTRY_EMAIL_PORT=587
SENTRY_EMAIL_USER=your-email@example.com
SENTRY_EMAIL_PASSWORD=your-password
SENTRY_EMAIL_USE_TLS=true
SENTRY_SERVER_EMAIL=sentry@your-domain.com
```

### 4. 数据保留策略

编辑 `sentry.conf.py`:

```python
# 事件保留天数 (默认 90 天)
SENTRY_OPTIONS["system.event-retention-days"] = 30
```

## Flutter 端集成

详见 `frontend/mobile-app` 目录下的集成代码。

简要步骤:

1. 添加依赖:
```yaml
dependencies:
  sentry_flutter: ^8.0.0
```

2. 初始化:
```dart
await SentryFlutter.init(
  (options) {
    options.dsn = 'http://your_key@your-server:9000/project_id';
  },
  appRunner: () => runApp(MyApp()),
);
```

## 故障排查

### 服务无法启动

检查内存是否足够:
```bash
free -h
docker stats
```

### 事件未上报

1. 检查 DSN 是否正确
2. 检查网络连通性
3. 查看 Relay 日志: `./deploy.sh logs sentry-relay`

### 符号化失败

1. 确保上传了符号文件 (Android: mapping.txt, iOS: dSYM)
2. 检查 Symbolicator 日志: `./deploy.sh logs sentry-symbolicator`

## 参考链接

- [Sentry 官方文档](https://docs.sentry.io/)
- [Self-Hosted 安装指南](https://develop.sentry.dev/self-hosted/)
- [sentry_flutter SDK](https://pub.dev/packages/sentry_flutter)
