- 4.1 环境要求
- 4.2 克隆代码与项目结构总览
- 4.3 Python 环境配置
- 4.4 前端环境配置
- 4.5 开发服务启动
- 4.6 运行 Sentry 开发服务器
- 4.7 开发模式与调试技巧
- 4.8 常用开发命令
- 4.9 常见问题排错
第四章:Sentry 开发环境搭建
Sentry 是一个拥有超过 17 年历史的复杂项目,其开发环境集成了 Python(Django)、TypeScript(React)、PostgreSQL、Redis、Kafka、ClickHouse 等多语言多服务的生态系统。本章基于 Sentry 主仓库的实际代码,提供一份详尽的开发环境搭建指南。
版本说明:本章内容基于 Sentry 代码库在写作时的最新版本(
setup.cfg显示26.8.0.dev0)。Sentry 的基础设施工具(devenv、devservices、prek 等)持续迭代,如果某个命令的行为与本章描述不符,请以仓库中的AGENTS.md和Makefile为准。
4.1 环境要求
4.1.1 操作系统与硬件
Sentry 的开发环境官方支持 macOS 和 Linux(基于 apt 的发行版)。Windows 不在官方支持范围内,但可以通过 WSL2 使用 Linux 环境进行开发。
硬件建议:
| 资源 | 最低配置 | 推荐配置 |
|---|---|---|
| 内存 | 16 GB | 32 GB 或更高 |
| CPU | 4 核 | 8 核或更高 |
| 磁盘 | 50 GB 可用空间 | 100 GB 可用空间(SSD) |
开发环境启动后,Docker 容器中会运行 PostgreSQL、Redis、Kafka、ClickHouse(通过 Snuba)、Relay 等多个服务,对内存和 CPU 的需求较高。在 macOS 上,建议为 Docker 分配至少 8 GB 内存。
4.1.2 Python 与 Node.js 版本
Sentry 对 Python 和 Node.js 有精确的版本要求。这些版本由仓库根目录下的 .python-version 和 .node-version 文件定义:
.python-version 内容:
3.13.1
.node-version 内容:
24.14.0
这意味着:
- Python 需要 3.13.1 及以上(
setup.cfg中声明了python_requires = >=3.13)。Sentry 使用 Python 3.13 的新特性,包括msgspec等现代库。 - Node.js 需要 24.14.0。这是 Sentry 当前使用的 Node.js 版本,由 devenv 自动下载和管理(见
devenv/config.ini中的预编译二进制下载地址)。
需要特别注意的是,Sentry 要求的 Python 3.13 是较新的版本。在通过 devenv 管理环境之前,确保系统中已安装 CPython 3.13,否则
uv创建虚拟环境时会失败。
4.1.3 系统依赖
macOS 依赖(由 Brewfile 定义):
brew install uv docker docker-buildx watchman
这些依赖的作用:
| 包名 | 用途 |
|---|---|
uv |
Python 包管理器和虚拟环境工具,替代 pip + virtualenv + pip-tools |
docker |
Docker CLI,用于构建镜像和与 devservices 通信 |
docker-buildx |
Docker 增强构建工具 |
watchman |
文件监视服务,pnpm 测试的快照更新功能需要 |
Linux 依赖(由 devenv/post_fetch.py 定义):
sudo apt install watchman chromium-chromedriver
此外,devenv 工具自身也需要安装。Sentry 使用一个名为 devenv 的内部工具来协调整个开发环境的初始化。安装方法如下:
# macOS
brew install getsentry/tools/devenv
# Linux (需要 Go 工具链)
go install github.com/getsentry/devenv@latest
或参考官方安装指南:https://github.com/getsentry/devenv#install
4.1.4 Docker 环境
Sentry 的开发服务(数据库、缓存、消息队列等)全部通过 Docker 容器运行,由 devservices 工具(一个基于 Docker Compose 的服务编排器)管理。
macOS:推荐使用 Colima 或 OrbStack 作为 Docker 运行时(devenv/post_fetch.py 中提及了 colima 相关逻辑)。如果使用 Docker Desktop,确保分配足够的内存(至少 8 GB)。
Linux:直接安装 Docker Engine,确保当前用户在 docker 组中或配置了 rootless Docker。
验证 Docker 安装:
docker run --rm hello-world
4.2 克隆代码与项目结构总览
4.2.1 克隆仓库
Sentry 主仓库托管在 GitHub 上:
git clone https://github.com/getsentry/sentry.git
cd sentry
克隆完成后,仓库根目录下的 .envrc 文件会被 direnv 检测到。如果已安装 direnv,运行:
direnv allow
direnv 会验证 Python 虚拟环境、Node.js、pnpm 依赖等是否就绪,如果不完整会给出需要执行的命令提示。
关于 direnv:direnv 不是必需的,但它极大地提高了开发体验 —— 每次进入项目目录时自动激活虚拟环境、设置环境变量(如
PYTHONUNBUFFERED=1、NODE_OPTIONS="--max-old-space-size=5120"、SENTRY_UI_HOT_RELOAD=1)。不使用 direnv 则需要手动执行source .venv/bin/activate和设置环境变量。
4.2.2 顶层目录结构
Sentry 仓库的顶层结构如下:
sentry/
├── .agents/ # AI agent 技能文件(AGENTS.md 的辅助目录)
├── .github/ # GitHub Actions CI/CD 工作流
├── api-docs/ # OpenAPI 文档生成脚本
├── bin/ # Shell 辅助脚本(迁移合并、目录操作)
├── build-utils/ # 构建工具脚本(gettext 提取等)
├── config/ # 开发服务配置(commit-template、hooks)
├── devenv/ # 开发环境引导器
│ ├── config.ini # devenv 配置(Node.js 二进制地址)
│ ├── post_fetch.py # git clone 后执行的钩子
│ └── sync.py # 核心同步逻辑(env 初始化)
├── devservices/ # Docker 服务定义
│ ├── config.yml # 主配置文件(服务定义、模式)
│ └── config/ # 各服务的补充配置文件
├── fixtures/ # 测试夹具
├── scripts/ # 开发辅助脚本
│ ├── do.sh # Makefile 目标的分发脚本
│ ├── test.js # Jest 测试启动器
│ ├── lib.sh # .envrc 公用函数库
│ └── dev-ui-server.ts # 仅前端开发服务器
├── self-hosted/ # 自托管部署配置
├── src/ # 后端 Python 源代码
│ ├── sentry/ # 核心 Django 应用
│ ├── social_auth/ # 第三方认证模块
│ └── sudo/ # Sudo 模式模块
├── static/ # 前端 TypeScript/React 源代码
│ ├── app/ # 主前端应用
│ └── ...
├── tests/ # Python 测试套件
├── tools/ # 开发工具
│ ├── fast_editable.py # 快速可编辑安装
│ ├── flake8_plugin.py # 自定义 flake8 规则
│ └── migrations/ # 迁移辅助工具
├── Brewfile # macOS Homebrew 依赖声明
├── Makefile # 顶层构建目标
├── pyproject.toml # Python 项目元数据 + uv + ruff 配置
├── setup.cfg # Python 打包元数据(版本、入口点等)
├── package.json # Node.js 项目配置(pnpm workspaces)
├── pnpm-lock.yaml # pnpm 锁定文件
├── pnpm-workspace.yaml # pnpm monorepo 工作区配置
├── tsconfig.json # TypeScript 主配置
├── rspack.config.ts # Rspack 打包器配置
├── uv.lock # uv 锁定文件(Python 依赖)
├── .python-version # Python 版本声明
├── .node-version # Node.js 版本声明
├── .envrc # direnv 配置
├── .pre-commit-config.yaml # pre-commit 钩子
└── AGENTS.md # AI 代理开发指南
4.2.3 后端源码结构
后端代码集中在 src/sentry/ 目录下,这是一个典型的 Django 应用结构:
src/sentry/
├── __main__.py # CLI 入口点(sentry 命令)
├── api/ # REST API 端点
├── auth/ # 认证系统(SSO、2FA、OAuth)
├── conf/ # Django 设置和配置
├── features/ # 功能标志(FlagPole)
├── ingest/ # 事件摄入管道
├── integrations/ # 第三方集成(GitHub、Slack、Jira 等)
├── issues/ # 问题(Issues)核心逻辑
├── models/ # Django 数据模型
├── migrations/ # 数据库迁移文件
├── monitors/ # Cron 监控
├── plugins/ # 插件系统
├── relay/ # Relay 接口
├── search/ # 搜索引擎后端
├── snuba/ # Snuba(ClickHouse)查询抽象
├── tasks/ # 后台任务(Celery 替代)
├── templates/ # Django 模板
├── testutils/ # 测试工具函数
└── utils/ # 通用工具函数
Sentry 的入口点定义在 setup.cfg 中:
[options.entry_points]
console_scripts =
sentry = sentry.__main__:main
这意味着安装后可以直接使用 sentry 命令来执行 Django 管理命令、运行开发服务器等。
4.2.4 前端源码结构
前端代码集中在 static/app/ 目录下,使用 React 19 + TypeScript + Rspack 构建:
static/app/
├── components/ # 可复用 UI 组件
├── views/ # 页面视图(路由对应的组件)
├── data/ # 数据层(API 客户端、状态管理)
├── utils/ # 工具函数
├── actionCreators/ # Redux action creators
├── stores/ # 状态存储
├── bootstrap/ # 应用初始化
├── serviceWorker/ # Service Worker(有独立 tsconfig)
└── index.tsx # 应用入口
前端使用了丰富的自定义依赖生态:@sentry/browser(Sentry 自身 SDK)、@sentry-internal/rrweb(会话回放)、@emotion/react(CSS-in-JS)、@tanstack/react-query(数据获取)等。
4.3 Python 环境配置
4.3.1 uv 包管理器
Sentry 使用 uv 作为 Python 包管理器,取代了传统的 pip + virtualenv + pip-tools 组合。uv 是一个由 Rust 编写的高性能 Python 包管理器,提供依赖解析、虚拟环境管理和锁定文件等功能。
验证 uv 是否安装:
uv --version
devenv/sync.py 在同步开始时检查 uv 是否在 PATH 中:
if not shutil.which("uv"):
print("\n\n\ndevenv is no longer managing uv; please run `brew install uv`.\n\n\n")
return 1
4.3.2 pyproject.toml 与依赖管理
Sentry 的 pyproject.toml 承担了多种角色:
项目元数据:
[project]
name = "sentry"
version = "0.0.0"
dependencies = [
"django>=5.2.14",
"djangorestframework>=3.16.1",
"confluent-kafka>=2.8.0",
"redis>=3.4.1",
"celery[redis]",
...
]
uv 配置:
[tool.uv]
environments = ["sys_platform == 'darwin' or sys_platform == 'linux'"]
[[tool.uv.index]]
url = "https://pypi.devinfra.sentry.io/simple"
default = true
这里有两个关键配置:
- 平台限制:仅支持 macOS 和 Linux。这是因为某些依赖(如
symbolic)在这两个平台之外没有预编译的 wheel。 - 私有 PyPI 镜像:Sentry 不使用公共 PyPI,而是通过
https://pypi.devinfra.sentry.io/simple获取依赖。这确保依赖版本的一致性和供应链安全。
ruff 代码风格配置:
[tool.ruff]
line-length = 100
target-version = "py313"
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
[tool.ruff.lint]
select = ["E", "W", "F", "B", "LOG", "I", "T20", "UP"]
Sentry 使用 ruff 替代了 isort、flake8 等工具的大部分规则,仅保留自定义的 S* 规则(tools/flake8_plugin.py)给 flake8 处理。
4.3.3 虚拟环境与 devenv 同步
Sentry 使用 devenv sync 命令来初始化整个开发环境。该命令在 devenv/sync.py 中定义,执行以下步骤:
步骤 1:安装系统依赖(macOS)
if constants.DARWIN:
brew.install()
proc.run((f"{constants.homebrew_bin}/brew", "bundle"), cwd=reporoot)
步骤 2:安装 Node.js
node.install(cfg["node"]["version"], ...)
devenv 从 devenv/config.ini 中读取 Node.js 的预编译二进制地址,不同架构和平台有不同的下载源。例如 darwin_arm64 的二进制来自 https://storage.googleapis.com/sentry-dev-infra-assets/node/node-v24.14.0-darwin-arm64.tar.xz。
步骤 3:安装 pnpm
pnpm_version = package_json["packageManager"].split("@")[-1]
install_pnpm(pnpm_version, reporoot)
pnpm 版本由 package.json 中的 packageManager 字段定义(当前为 pnpm@10.30.2)。安装后,pnpm 被放在 .devenv/bin/node-env/bin/pnpm。
步骤 4:安装 JavaScript 依赖
("javascript dependencies", ("pnpm", "install", "--frozen-lockfile", ...), ...)
步骤 5:同步 Python 依赖
("python dependencies", ("uv", "sync", "--frozen", "--inexact", "--quiet", "--active", ...), ...)
uv sync --frozen 使用 uv.lock 锁定文件安装精确版本,保证所有开发者使用一致的依赖。
步骤 6:安装开发工具链
("prek dependencies", ("prek", "install", "--prepare-hooks", "-f"), {})
("fast editable", ("python3", "-m", "tools.fast_editable", "--path", "."), {})
完整同步命令:
# 完整同步(包括迁移和用户创建)
devenv sync
# 仅同步依赖和前端,跳过数据库迁移(适合只需要运行测试的场景)
SENTRY_DEVENV_FRONTEND_ONLY=1 devenv sync
# 跳过前端依赖安装
SENTRY_DEVENV_SKIP_FRONTEND=1 devenv sync
4.3.4 direnv 自动激活
Sentry 仓库根目录下的 .envrc 文件负责自动激活开发环境。它执行以下检查:
- 验证 devenv 是否安装
- 验证 Python 虚拟环境是否存在(
.venv/目录) - 验证 Node.js 版本(与
.node-version对比) - 验证 pnpm 依赖(
node_modules/目录是否存在) - 验证 prek、agent skills 是否就绪
- 添加虚拟环境和工具到 PATH
- 设置环境变量:
VIRTUAL_ENV="${PWD}/.venv"PYTHONUNBUFFERED=1NODE_OPTIONS="--max-old-space-size=5120"SENTRY_UI_HOT_RELOAD=1(默认开启前端热模块替换)
direnv 允许后,每次进入 sentry 目录都会自动完成上述检查和激活:
# 首次使用
direnv allow
# 如果 .envrc 有改动,重新允许
direnv allow
4.3.5 Sentry 配置文件生成
devenv sync 完成后会自动检查 ~/.sentry/ 目录下是否存在配置文件。如果没有,会执行:
proc.run((f"{venv_dir}/bin/sentry", "init", "--dev"))
这会在 ~/.sentry/ 下生成两个核心配置文件:
~/.sentry/config.yml:Sentry 的 YAML 格式配置(数据库连接、Redis 地址、Kafka broker 等)~/.sentry/sentry.conf.py:Python 格式的 Django 设置覆盖文件
手动生成配置的方法:
sentry init --dev
--dev 标志告诉 Sentry 使用开发环境友好的默认值,例如连接 localhost 上的 devservices。
4.3.6 快速可编辑安装
传统的 pip install -e . 方式在 Sentry 这样的大型项目中会非常慢。Sentry 使用了一个自定义的 tools/fast_editable.py 脚本来加速可编辑安装。这个脚本通过在 site-packages 中创建精确的 .pth 文件和 shim 来让 Python 能够找到 src/sentry 模块,而不需要运行完整的构建系统(setup.py/pyproject.toml build)。
devenv/sync.py 中的注释说明了设计意图:
# Note: instead of using a build system, we use tools/fast_editable.py
# to install sentry editably as well as console scripts.
# Otherwise, you need to define a build system (uv_build)
# and console scripts here, and call uv sync then uv pip install -e .
这保证了每次 devenv sync 后,源代码修改立即可用,无需重新安装。
4.4 前端环境配置
4.4.1 pnpm 工作区
Sentry 前端使用 pnpm 作为包管理器。package.json 中声明了包管理器的版本:
"packageManager": "pnpm@10.30.2"
pnpm 的版本由 devenv/sync.py 自动管理 —— 它读取 packageManager 字段,通过 npm 全局安装对应版本的 pnpm 到 .devenv/bin/node-env/bin/pnpm。
工作区配置(pnpm-workspace.yaml)定义了 monorepo 中的子包位置。pnpm-lock.yaml 锁定所有依赖的精确版本。
包安装命令:
# 按锁定文件安装(开发时标准用法)
pnpm install --frozen-lockfile
# 修改依赖后更新锁定文件
pnpm install
关键依赖概览:
| 类别 | 核心包 |
|---|---|
| UI 框架 | react 19.2.3, react-dom 19.2.3, react-router-dom 6.30.3 |
| 构建工具 | rspack 2.1.3, @rspack/core 2.1.3, @rspack/cli 2.1.3 |
| CSS 方案 | @emotion/react 11.14.0, @emotion/css 11.13.5 |
| 数据管理 | @tanstack/react-query 5.96.0, mobx 6.13.7 |
| Sentry SDK | @sentry/browser 10.69.0, @sentry/react 10.69.0 |
| 类型检查 | typescript 6.0.2(通过 npm alias 安装) |
| 测试 | jest 30.4.2, @testing-library/react 16.3.2 |
| 代码质量 | eslint 9.34.0, oxfmt 0.58.0, stylelint 16.10.0 |
4.4.2 Rspack 构建系统
Sentry 在 2024 年从 Webpack 迁移到了 Rspack,这是一个基于 Rust 的高性能 JavaScript 打包器,提供与 Webpack 兼容的 API 但构建速度快 5-10 倍。
配置文件:rspack.config.ts
关键构建脚本(来自 package.json):
{
"dev": "pnpm install --frozen-lockfile && sentry devserver",
"dev-ui": "SENTRY_UI_DEV_ONLY=1 SENTRY_UI_HOT_RELOAD=1 node scripts/dev-ui-server.ts",
"dev-acceptance": "NO_DEV_SERVER=1 NODE_ENV=development rspack --watch",
"build": "NODE_OPTIONS='--max-old-space-size=4096' rspack --config ./rspack.config.ts",
"build-production": "NODE_ENV=production rspack --mode production --config ./rspack.config.ts",
"build-acceptance": "IS_ACCEPTANCE_TEST=1 NODE_ENV=production pnpm run build"
}
Rspack 支持开发模式下的 HMR(Hot Module Replacement),由 @rspack/plugin-react-refresh 插件提供。
4.4.3 TypeScript 配置
Sentry 前端的 TypeScript 配置分布在多个文件中:
tsconfig.json:主配置,定义编译选项、路径映射和包含的文件tsconfig.mdx.json:MDX 文件(Markdown + JSX)的编译配置static/app/serviceWorker/worker/tsconfig.json:Service Worker 专用配置
类型检查命令:
# 完整类型检查(检查主项目和 Service Worker)
pnpm run typecheck
# 等价于:tsc --build tsconfig.json static/app/serviceWorker/worker/tsconfig.json --builders 2
# 类型覆盖率统计
pnpm run type-coverage
# 类型覆盖率差异(与基准对比)
pnpm run type-coverage-diff
注意:不要直接使用
tsc命令,应通过pnpm typecheck运行。AGENTS.md 明确指示了这一点。
4.4.4 前端开发模式
Sentry 提供了三种前端开发模式:
模式 1:完整开发服务器
pnpm run dev
启动完整的开发环境(等价于先安装依赖再执行 sentry devserver)。后端 API 和前端资源都由本地服务器提供,访问 http://dev.getsentry.net:8000。
模式 2:仅前端 UI 开发(推荐前端开发者使用)
pnpm run dev-ui
设置 SENTRY_UI_DEV_ONLY=1 和 SENTRY_UI_HOT_RELOAD=1,启动一个独立的 UI 开发服务器,它将 API 请求代理到生产环境的 sentry.io。访问 https://sentry.dev.getsentry.net:7999/。
这个模式的优势是不需要运行 devservices(跳过数据库、Redis、Kafka 等),因此资源消耗极低。适合纯前端 UI 改动。
模式 3:验收测试构建
pnpm run dev-acceptance
以 watch 模式编译前端资源,供验收测试使用。
前端口令与 HTTPS:
# 生成本地 SSL 证书(dev-ui 模式需要 HTTPS)
pnpm run mkcert-localhost
4.5 开发服务启动
4.5.1 devservices 概述
devservices 是 Sentry 自研的 Docker 服务编排工具,定义在 devservices/config.yml 中。它比 Docker Compose 更轻量,专为本地开发场景设计,支持”模式”(mode)概念,可以按需启动不同的服务子集。
核心命令:
# 以默认模式启动服务
devservices up
# 指定模式启动
devservices up --mode <mode>
# 停止所有服务
devservices down
# 查看运行中的服务状态
devservices status
devservices/config.yml 定义了三种类型的组件:
- 远程依赖服务(Remote Dependencies):从其他 Sentry 仓库(如 snuba、relay)拉取的容器化服务
- Docker Compose 服务(Services):直接在 YAML 中定义的 Docker 容器(如 bigtable、redis-cluster)
- Supervisor 程序(Programs):由
sentry devserver内部启动的本地进程(如 kafka consumers、taskworker)
4.5.2 核心基础服务
PostgreSQL
PostgreSQL 是 Sentry 的主数据库,存储用户、组织、项目、事件元数据等。在 devservices 中,PostgreSQL 是一个远程依赖,来自 getsentry/sentry-shared-postgres 仓库:
postgres:
description: Shared instance of postgres used by sentry services
remote:
repo_name: sentry-shared-postgres
branch: main
repo_link: https://github.com/getsentry/sentry-shared-postgres.git
多个 Sentry 子仓库共享同一个 PostgreSQL 实例,避免在每个仓库中启动独立的数据库容器。
Redis
Redis 用作缓存和消息代理。与 PostgreSQL 类似,它也是一个共享服务:
redis:
description: Shared instance of redis used by sentry services
remote:
repo_name: sentry-shared-redis
branch: main
repo_link: https://github.com/getsentry/sentry-shared-redis.git
4.5.3 数据存储服务
Snuba / ClickHouse
Snuba 是 Sentry 的事件搜索引擎,底层使用 ClickHouse 列式数据库。Snuba 提供三种容器化模式:
snuba:
description: Service that provides fast aggregation and query capabilities on top of Clickhouse
remote:
repo_name: snuba
branch: master
repo_link: https://github.com/getsentry/snuba.git
mode: containerized
snuba-profiling:
mode: containerized-profiles # 包含 profiling consumer
snuba-metrics:
mode: containerized-metrics-dev # 包含 metrics consumer
Snuba 负责事件的快速聚合查询和发现(Discover)功能。没有 Snuba,Sentry 的事件搜索将无法工作。
Bigtable 模拟器(仅 CI/测试):
bigtable:
description: Bigtable emulator
image: 'ghcr.io/getsentry/cbtemulator:d28ad6b63e461e8c05084b8c83f1c06627068c04'
ports:
- '127.0.0.1:8086:8086'
用于测试 Google Cloud Bigtable 相关功能。
Redis Cluster(仅测试):
redis-cluster:
description: Redis cluster used for testing
image: ghcr.io/getsentry/docker-redis-cluster:7.0.10
ports:
- '127.0.0.1:7000:7000'
- '127.0.0.1:7001:7001'
# ... 6 个节点
Memcached:
memcached:
description: Memcached used for caching
image: ghcr.io/getsentry/image-mirror-library-memcached:1.5-alpine
ports:
- '127.0.0.1:11211:11211'
用于替代 Redis 作为缓存后端(特定模式启用)。
Objectstore:
objectstore:
description: Storage for files and blobs
remote:
repo_name: objectstore
branch: main
repo_link: https://github.com/getsentry/objectstore.git
mode: containerized
模拟 Google Cloud Storage 的对象存储服务,用于存储文件附件和事件载荷。
4.5.4 消息队列与流处理
Relay
Relay 是 Sentry 的事件接收和转发网关。所有 SDK 上报的事件首先到达 Relay,由其进行过滤、采样、速率限制和数据脱敏,然后再转发给 Sentry 后端处理。
relay:
description: Service event forwarding and ingestion service
remote:
repo_name: relay
branch: master
repo_link: https://github.com/getsentry/relay.git
mode: containerized
Taskbroker
Taskbroker 是 Sentry 的异步任务系统,基于 gRPC 通信,取代了传统的 Celery:
taskbroker:
description: Service used to process asynchronous tasks
remote:
repo_name: taskbroker
branch: main
repo_link: https://github.com/getsentry/taskbroker.git
mode: containerized
taskbroker-sentry:
description: Sentry's own taskbroker for tasks internal to Sentry
taskbroker-sentry 是 Sentry 专用的 taskbroker 实例(端口 50052),处理 raw-mode 主题(如 ingest-profiles、subscription results、replay recordings)。
Kafka
Kafka 本身由 Snuba 的容器化模式自带,不需要在 devservices 中单独声明。Kafka 是 Sentry 事件管道中连接各个处理阶段的纽带。
4.5.5 事件处理管道
Sentry 的事件处理由多个 Kafka Consumer 分工协作。这些 Consumer 在 devservices 中定义为 programs(由 sentry devserver 内部的 honcho 启动和管理),而非独立容器:
x-programs:
ingest-events:
command: sentry run consumer ingest-events --consumer-group=sentry-consumer --auto-offset-reset=latest --no-strict-offset-reset
ingest-attachments:
command: sentry run consumer ingest-attachments --consumer-group=sentry-consumer --auto-offset-reset=latest --no-strict-offset-reset
ingest-transactions:
command: sentry run consumer ingest-transactions --consumer-group=sentry-consumer --auto-offset-reset=latest --no-strict-offset-reset
ingest-monitors:
command: sentry run consumer ingest-monitors --consumer-group=sentry-consumer --auto-offset-reset=latest --no-strict-offset-reset
# ... 更多 consumer
关键 Consumer 列表:
| Consumer 名称 | 用途 |
|---|---|
ingest-events |
处理错误事件摄入 |
ingest-transactions |
处理性能事务摄入 |
ingest-attachments |
处理附件摄入 |
ingest-metrics |
处理指标摄入 |
ingest-generic-metrics |
处理通用指标摄入 |
ingest-monitors |
处理 Cron 监控签到摄入 |
ingest-occurrences |
处理问题出现次数摄入 |
ingest-feedback-events |
处理用户反馈摄入 |
process-spans |
处理 Span 数据 |
process-segments |
处理性能段数据 |
post-process-forwarder-errors |
错误事件后处理转发 |
post-process-forwarder-transactions |
事务事件后处理转发 |
post-process-forwarder-issue-platform |
Issue Platform 后处理转发 |
monitors-clock-tick |
监控时钟 tick 消费者 |
monitors-clock-tasks |
监控时钟任务消费者 |
monitors-incident-occurrences |
监控告警事件消费者 |
billing-metrics-consumer |
计费指标消费者 |
uptime-results |
正常运行时间监控结果消费者 |
Taskworker 负责消费 taskbroker 分发的异步任务:
taskworker:
command: sentry run taskworker
taskworker-sentry:
command: sentry run taskworker --rpc-host localhost:50052
taskworker-scheduler:
command: sentry run taskworker-scheduler
4.5.6 启动模式选择
devservices/config.yml 定义了多种启动模式,可以精确控制启动哪些服务:
modes:
default: [snuba, postgres, relay, spotlight, objectstore]
migrations: [postgres, redis]
minimal: [postgres, snuba]
backend-ci: [snuba, postgres, redis, bigtable, redis-cluster, symbolicator, objectstore]
symbolicator-tests: [postgres, snuba, objectstore]
# ... 更多模式
使用情景参考:
| 情景 | 推荐模式命令 | 启动的服务 |
|---|---|---|
| 日常开发 | devservices up |
snuba, postgres, relay, spotlight, objectstore |
| 仅运行数据库迁移 | devservices up --mode migrations |
postgres, redis |
| 仅运行测试(最少量) | devservices up --mode minimal |
postgres, snuba |
| 运行后端 CI 测试 | devservices up --mode backend-ci |
snuba, postgres, redis, bigtable, redis-cluster, symbolicator, objectstore |
| 调试事件摄入管道 | devservices up --mode ingest |
snuba, postgres, relay, spotlight, objectstore, taskbroker, taskworker, 多个 kafka consumers |
| 调试 Tracing 相关功能 | devservices up --mode tracing |
postgres, snuba-metrics, relay, spotlight, 多个 kafka consumers |
| 调试 Cron 监控 | devservices up --mode crons |
postgres, snuba, relay, spotlight, ingest-monitors, monitors-* |
| 调试 Profiling | devservices up --mode profiling |
postgres, snuba-profiling, relay, vroom, spotlight |
| 全部服务(高资源消耗) | devservices up --mode full |
所有可用服务 |
4.5.7 常见服务组合
仅后端测试的最小化设置:
# 1. 仅安装依赖(跳过迁移)
SENTRY_DEVENV_FRONTEND_ONLY=1 devenv sync
# 2. 启动最小化服务
devservices up --mode minimal
# 3. 直接运行测试
pytest tests/sentry/api/test_base.py --reuse-db
完整开发环境:
# 1. 完整同步(依赖 + 迁移 + 创建用户)
devenv sync
# 2. 启动默认模式服务
devservices up
# 3. 启动开发服务器
sentry devserver
4.6 运行 Sentry 开发服务器
4.6.1 sentry devserver 命令
Sentry 开发服务器的入口是 sentry devserver 命令。它不是简单的 Django runserver,而是一个集成多个进程的编排管理器。
启动命令:
sentry devserver
等效方式:
pnpm run dev
pnpm run dev 的定义是:
"dev": "pnpm install --frozen-lockfile && sentry devserver"
4.6.2 honcho 进程管理
sentry devserver 内部使用 honcho(一个 Python 实现的 Procfile 运行器,类似于 Foreman)来管理多个并发进程。这些进程包括:
- granian web server:Sentry 使用 granian(一个 Rust 编写的 ASGI/WSGI 服务器)替代了 Gunicorn,支持 pname(进程命名)、reload(自动重载)和 uvloop(高性能事件循环)。
pyproject.toml中的依赖为"granian[pname,reload,uvloop]>=2.7"。 - rspack dev server:前端资源编译和 HMR 服务
- taskworker:异步任务消费者
- kafka consumers:事件管道中的各个 Consumer 进程(根据启动模式加载)
- taskworker-scheduler:定时任务调度器
这些进程的位置和配置由 devservices/config.yml 的 x-programs 段定义。
4.6.3 开发日志文件
当 devserver 运行时,所有进程的完整控制台输出(包括 server、taskworker、kafka consumers、webpack/watchers 等)被同时写入 .artifacts/dev.log 文件中。这是 ANSI 去除后的纯文本文件,且被 gitignore,不用担心提交到仓库。
查看运行状态:
# 实时跟踪日志输出
tail -f .artifacts/dev.log
# 搜索特定的日志条目
grep "ERROR" .artifacts/dev.log
grep "WARNING" .artifacts/dev.log
# 查看启动过程
head -n 100 .artifacts/dev.log
日志文件在每次 devserver 进程启动时被截断(--workers 模式的重载会持续追加)。可以通过环境变量 SENTRY_DEV_LOG_FILE 自定义日志文件的路径。
4.6.4 访问地址
| 模式 | URL | 说明 |
|---|---|---|
| 完整开发 | http://dev.getsentry.net:8000 |
后端 API + 前端 UI |
| 仅前端 UI | https://sentry.dev.getsentry.net:7999/ |
仅前端,API 代理到生产环境 |
4.6.5 创建管理员用户
devenv sync 在完成迁移后会自动检查数据库中是否已存在 admin@sentry.io 用户,如果不存在则自动创建:
proc.run((
f"{venv_dir}/bin/sentry", "createuser",
"--superuser", "--email", "admin@sentry.io",
"--password", "admin", "--no-input",
))
手动创建用户:
sentry createuser --superuser --email admin@sentry.io --password admin --no-input
登录时使用:
- 邮箱:
admin@sentry.io - 密码:
admin
4.7 开发模式与调试技巧
4.7.1 仅前端开发模式
对于纯前端改动,使用仅 UI 模式可以大幅降低资源消耗:
pnpm run dev-ui
该模式设置的环境变量:
SENTRY_UI_DEV_ONLY=1:跳过所有后端初始化SENTRY_UI_HOT_RELOAD=1:启用 React Fast Refresh
此模式下,所有 API 请求被代理到生产环境的 sentry.io。因此不需要本地 devservices,也不需要数据库。
对应的访问地址是 https://sentry.dev.getsentry.net:7999/。首次使用需要生成本地 SSL 证书:
pnpm run mkcert-localhost
4.7.2 仅后端开发模式
当只需要修改后端代码时,可以跳过前端构建:
SENTRY_DEVENV_SKIP_FRONTEND=1 devenv sync
devservices up
sentry devserver
或者设置环境变量 SENTRY_DEVENV_FRONTEND_ONLY 的逆逻辑,通过跳过前端编译来加速启动。更简单的做法是预先构建前端资源一次,之后直接启动 Django(虽然不推荐,但在调试简单 API 时可行):
# 启动 devservices
devservices up
# 直接使用 Django runserver(注意:不会启动 kafka consumers 等)
sentry run web --reload
4.7.3 前端热模块替换
Sentry 使用 @rspack/plugin-react-refresh(版本 2.0.2)实现 React 组件的热模块替换。在开发模式下(SENTRY_UI_HOT_RELOAD=1),修改组件后浏览器会立即反映变化,无需手动刷新。
环境变量 SENTRY_UI_HOT_RELOAD 在 .envrc 中默认开启:
export SENTRY_UI_HOT_RELOAD=1
4.7.4 granian 服务器与自动重载
Sentry 使用 granian 作为 WSGI/ASGI 服务器。granian 支持 reload 功能,在 Python 文件改动后自动重启 worker 进程。在 devserver 模式下,granian 以 --reload 参数启动。
granian 的 pname 扩展允许给 worker 进程命名,便于在进程列表中识别。
4.7.5 数据库调试
连接到 PostgreSQL:
# 通过 Docker exec 直接连接
docker exec -it postgres-postgres-1 psql sentry postgres
# 查看所有表
\dt
# 查看表结构
\d sentry_project
# 执行查询
SELECT id, slug, name FROM sentry_project LIMIT 10;
查看迁移状态:
sentry django showmigrations
Django Shell:
sentry django shell
重置数据库(清除所有数据并重新迁移):
make reset-db
make reset-db 会调用 ./scripts/do.sh reset-db,依次执行 drop-db、create-db 和 apply-migrations。
4.7.6 Git 工作树并行开发
当需要同时开发多个分支时,Git 工作树(worktree)是一个优雅的解决方案。每个工作树拥有独立的 .venv 目录。
创建新工作树:
# 创建一个新的工作树
git worktree add ../sentry-feature-branch feature-branch
# 进入新工作树
cd ../sentry-feature-branch
post-checkout 钩子会自动在新工作树中运行 devenv sync。如果没有自动运行,手动执行:
devenv sync
direnv allow
每个工作树拥有独立的虚拟环境、node_modules 和配置文件,互不干扰。
4.8 常用开发命令
4.8.1 Python 代码质量检查
Sentry 使用 prek 作为所有 lint、format 和 type-checking 工具的统一入口。
运行所有检查:
.venv/bin/prek run -q
prek 自动检测变更文件,只运行相关的检查。-q 标志表示安静模式,只输出错误信息。
运行特定检查:
# 对指定文件运行 mypy 类型检查
SENTRY_MYPY_PRE_PUSH=1 .venv/bin/prek run -q mypy --files src/sentry/foo/bar.py --stage pre-push
# 对指定文件运行 ruff 代码风格检查
.venv/bin/prek run -q ruff --files src/sentry/foo/bar.py
直接使用底层工具:
# ruff 代码风格检查
ruff check src/sentry/foo/bar.py
# ruff 自动修复
ruff check --fix src/sentry/foo/bar.py
# mypy 类型检查
mypy src/sentry/foo/bar.py
# flake8(仅 S* 规则,不处理 E/W/F/B 等已由 ruff 覆盖的规则)
flake8 src/sentry/foo/bar.py
4.8.2 前端代码质量检查
JavaScript/TypeScript 代码检查:
# 完整 lint(包括格式、JS、CSS)
pnpm run lint
# JavaScript/TypeScript linting
pnpm run lint:js
# 对特定文件 lint
pnpm run lint:js components/avatar.tsx
# 自动修复
pnpm run fix
# 仅修复 ESLint 问题
pnpm run fix:eslint
# 仅修复格式(使用 oxfmt)
pnpm run fix:format
# CSS/样式检查
pnpm run lint:css
类型检查:
# 全项目类型检查
pnpm run typecheck
# 查看类型覆盖率
pnpm run type-coverage
4.8.3 测试命令
Python 测试:
# 运行所有测试(不推荐,需要很长时间)
pytest
# 运行特定测试文件(推荐)
.venv/bin/pytest -n3 -svv --reuse-db tests/sentry/api/test_base.py
# 运行特定测试函数
.venv/bin/pytest tests/sentry/api/test_base.py::SomeTest::test_something --reuse-db
# 使用 -n 指定并行 worker 数量(-n3 表示 3 个并行线程)
.venv/bin/pytest -n4 --reuse-db tests/sentry/
# 标记(marker)筛选
.venv/bin/pytest -m symbolicator --reuse-db tests/sentry/
# Acceptance 测试
make test-acceptance
# CI 风格的测试
make test-python-ci
关键参数说明:
| 参数 | 说明 |
|---|---|
--reuse-db |
复用测试数据库,避免每次测试都执行迁移(首次运行或迁移变更后仍需重建) |
-n3 |
使用 pytest-xdist 并行运行测试,3 个 worker |
-svv |
显示测试输出和详细失败信息 |
-m |
按标记筛选测试 |
JavaScript 测试:
# 运行所有 JS 测试(CI 模式)
pnpm test-ci
# 运行特定文件
pnpm test-ci components/avatar.spec.tsx
# 交互式 watch 模式
pnpm test
# pre-commit 模式(仅运行关联的测试)
pnpm test-precommit
# 仅运行暂存文件相关的测试
pnpm test-staged
选择性测试(基于变更文件):
make test-selective
该命令使用覆盖率数据,仅运行与当前分支变更相关的测试,大幅缩短测试时间。
4.8.4 数据库迁移命令
# 应用所有待执行的迁移
sentry django migrate
# 创建新迁移文件
sentry django makemigrations
# 查看迁移状态
sentry django showmigrations
# 处理 rebase 冲突后的迁移
./bin/update-migration <migration_name_or_number> <app_label>
# 示例:
./bin/update-migration 0101_workflow_when_condition_group_unique workflow_engine
./bin/update-migration 脚本处理迁移文件的重命名、依赖关系更新和 migrations_lockfile.txt 的更新。在 rebase 后与主分支的迁移发生冲突时非常有用。
# 重置数据库
make reset-db
4.8.5 环境维护命令
# 刷新依赖(不重新安装,仅检查是否有更新)
devenv sync
# 更新 uv 锁定文件(添加/升级依赖后)
uv lock
# 或使用 Makefile 目标:
make freeze-requirements
# 构建前端生产资源
pnpm run build-production
# 清除构建产物
make clean
# 生成 API 文档
make build-api-docs
# 构建国际化翻译文件
make compile-locale
4.9 常见问题排错
4.9.1 devenv sync 失败
症状:devenv sync 报告错误,无法完成环境初始化。
排查步骤:
- 检查 uv 是否安装:
devenv sync要求uv在 PATH 中。
which uv
uv --version
如未安装:
brew install uv
- 检查 Python 版本:确保系统中有 Python 3.13.1。
python3 --version
如果版本不符,使用 pyenv 或直接从 python.org 安装正确版本。
- 检查网络连接:Sentry 使用私有 PyPI 镜像
https://pypi.devinfra.sentry.io/simple。如果在公司网络或 VPN 中,可能需要配置代理。
# 测试连接
curl -I https://pypi.devinfra.sentry.io/simple
- 使用 verbose 模式获取详细错误:
SENTRY_DEVENV_VERBOSE=1 devenv sync
- 清除缓存重试:
rm -rf .venv node_modules .devenv
devenv sync
4.9.2 开发服务无法启动
症状:devservices up 失败或服务启动后立即退出。
排查步骤:
- 确认 Docker 正在运行:
docker info
- 检查端口占用:
# 查看哪些端口被占用
lsof -i :5432 # PostgreSQL
lsof -i :6379 # Redis
lsof -i :9092 # Kafka
lsof -i :8000 # Sentry web
- 查看特定服务日志:
docker logs postgres-postgres-1
docker logs sentry-relay-1
- 清理 Docker 资源:
# 停止所有 devservices 容器
devservices down
# 清理未使用的镜像和卷
docker system prune -a
- 内存不足:macOS 用户检查 Docker Desktop 或 Colima 的内存分配。建议至少 8 GB。
4.9.3 Python 导入错误
症状:ModuleNotFoundError: No module named 'sentry' 或类似的导入错误。
排查步骤:
- 确认虚拟环境已激活:
# 检查是否在虚拟环境中
echo $VIRTUAL_ENV
# 应输出类似 /path/to/sentry/.venv
# 检查 sentry 模块是否可导入
python -c "import sentry; print(sentry.__file__)"
- 重新运行 devenv sync:
devenv sync
- 检查 fast_editable 安装:
# 查看 site-packages 中的 .pth 文件
ls .venv/lib/python3.13/site-packages/*.pth
# 应包含指向 src/ 目录的路径
- 验证 sentry 入口点:
which sentry
# 应输出 .venv/bin/sentry
4.9.4 数据库连接问题
症状:django.db.utils.OperationalError: could not connect to server 或迁移失败。
排查步骤:
- 确认 PostgreSQL 容器在运行:
docker ps | grep postgres
- 测试连接:
docker exec postgres-postgres-1 psql -U postgres -c "SELECT 1"
- 检查配置文件:
查看 ~/.sentry/config.yml 中数据库连接配置是否正确。开发环境默认应指向 localhost:5432。
- 重建数据库:
make reset-db
- 检查 /etc/hosts:
确保 127.0.0.1 localhost 存在。
4.9.5 前端编译错误
症状:Rspack 构建失败、TypeScript 类型错误、模块未找到。
排查步骤:
- 重新安装依赖:
rm -rf node_modules
devenv sync
- 检查 Node.js 版本:
node --version
# 应输出 v24.14.0
- 清除 Rspack 缓存:
rm -rf node_modules/.cache
- 运行完整类型检查:
pnpm run typecheck
- 检查 pnpm 版本:
pnpm --version
# 应输出 10.30.2
4.9.6 端口冲突
症状:Address already in use 或服务绑定端口失败。
Sentry 使用的关键端口:
| 端口 | 服务 |
|---|---|
| 8000 | Sentry web 服务器 |
| 7899 | Relay edge(cell-routing) |
| 7900 | Relay cell |
| 7999 | 前端 dev-ui 服务器 |
| 8969 | Spotlight 调试工具 |
| 50052 | taskbroker-sentry (gRPC) |
| 5432 | PostgreSQL |
| 6379 | Redis |
| 7000-7005 | Redis Cluster |
| 8086 | Bigtable 模拟器 |
| 11211 | Memcached |
排查方法:
# 查找占用的进程
lsof -i :8000
# 或
netstat -anp | grep 8000
解决冲突:
- 如果端口被其他 devservices 实例占用,先执行
devservices down。 - 如果被其他进程占用,终止该进程或修改配置。
- 对于 Spotligh 等非关键服务,可以在配置中临时注释掉。
以上是 Sentry 开发环境搭建的完整指南。随着项目的发展,某些工具链和配置可能会发生变化,始终以仓库中的最新文件(AGENTS.md、Makefile、pyproject.toml、devservices/config.yml、devenv/sync.py)为权威参考。