后端与接口
在 Elixir/Phoenix/Plug/LiveView…
当你需要为 Elixir 或 Phoenix 应用添加 Sentry,并配置错误监控、Tracing、Logging、Crons 时,按本经验扫描项目并逐步完成 SDK 接入与验证。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在 Elixir/Phoenix/Plu特定
解决思路
- 实施前始终对照 `docs.sentry.io/platforms/elixir/` 验证 SDK 版本和 API,因为本文反映 sentry v13.2.0 且要求 Elixir `~> 1.13`。
- 执行 `grep -i sentry mix.exs 2>/dev/null` 检查是否已有 Sentry 依赖。
- 执行 `cat .tool-versions 2>/dev/null | grep elixir` 和 `grep "elixir:" mix.exs 2>/dev/null` 检测 Elixir 版本。
- 执行 `grep -E '"phoenix"|"plug"' mix.exs 2>/dev/null` 检测 Phoenix 或 Plug。
- 执行 `grep "phoenix_live_view" mix.exs 2>/dev/null` 检测 Phoenix LiveView。
- 执行 `grep "oban" mix.exs 2>/dev/null` 检测 Oban。
- 执行 `grep "quantum" mix.exs 2>/dev/null` 检测 Quantum。
- 执行 `grep "opentelemetry" mix.exs 2>/dev/null` 检测 OpenTelemetry 使用。
- 执行 `ls assets/ frontend/ web/ client/ 2>/dev/null` 检查是否有配套前端。
- 如果 `mix.exs` 已有 `sentry`,跳过安装,进入 Phase 2 配置功能。
- 如果检测到 Phoenix,添加 `Sentry.PlugCapture`、`Sentry.PlugContext`,可选 `Sentry.LiveViewHook`。
- 如果检测到 LiveView,在 `my_app_web.ex` 的 `live_view` 宏中添加 `Sentry.LiveViewHook`。
- 如果检测到 Oban,推荐通过 Oban 集成使用 Crons 并捕获错误。
- 如果检测到 Quantum,推荐通过 Quantum 集成使用 Crons。
- 如果已有 OpenTelemetry,Tracing 设置只需 `Sentry.OpenTelemetry.*` 配置。
- 如果发现前端目录,触发 Phase 4 cross-link 建议。
- 基于检测结果给出具体推荐,不要开放式提问,先提出方案。
- 推荐核心覆盖:始终启用 Error Monitoring;始终启用 Logging,用 `Sentry.LoggerHandler` 转发 crash reports 和 error logs;如果检测到 Phoenix、Plug 或 Ecto,启用 Tracing(通过 OpenTelemetry)。
- 可选增强:Crons,用于检测 Oban、Quantum 或手动 GenServer 定时任务的静默失败;Sentry Logs,用于将结构化日志转发到 Sentry Logs Protocol(sentry v12.0.0+)。
- 推荐逻辑:Error Monitoring 始终推荐;Logging 始终推荐;Tracing 在检测到 Phoenix、Plug、Ecto 或 OpenTelemetry imports 时推荐;Crons 在检测到 Oban、Quantum 或周期性 `GenServer`/`Task` 模式时推荐;Sentry Logs 在使用 sentry v12.0.0+ 且需要结构化日志搜索时推荐。
- 提议话术:我推荐设置 Error Monitoring + Logging [+ 如果检测到 Phoenix/Ecto 则加 Tracing]。是否还要添加 Crons 或 Sentry Logs?
- 首选 Option 1:Igniter Installer。提示用户需要自己运行,因为 Igniter installer 需要交互式终端输入,代理无法处理;让用户复制并运行 `mix igniter.install sentry`。
- 说明 `mix igniter.install sentry` 自 sentry v11.0.0 起可用,会自动配置 `config/config.exs`、`config/prod.exs`、`config/runtime.exs` 和 `lib/my_app/application.ex`。
- 用户完成 Igniter 安装后,回来跳到 Verification。
- 如果用户跳过 Igniter installer,继续 Option 2 手动设置。
- 手动安装:在 `mix.exs` 的 `defp deps` 添加 `{:sentry, "~> 13.0"}` 和 `{:finch, "~> 0.21"}`;如果 Elixir < 1.18,添加 `{:jason, "~> 1.4"}`。
- 运行 `mix deps.get`。
- 在 `config/config.exs` 配置:`config :sentry, dsn: System.get_env("SENTRY_DSN"), environment_name: config_env(), enable_source_code_context: true, root_source_code_paths: [File.cwd!()], in_app_otp_apps: [:my_app]`。
- 运行时配置推荐用于 DSN 和 release:在 `config/runtime.exs` 写 `import Config`,然后 `config :sentry, dsn: System.fetch_env!("SENTRY_DSN"), release: System.get_env("SENTRY_RELEASE", "my-app@#{Application.spec(:my_app, :vsn)}")`。
- Quick Start 推荐初始化配置:在 `config/config.exs` 设置 `dsn`、`environment_name`、`enable_source_code_context`、`root_source_code_paths`、`in_app_otp_apps`,并设置 `logger: [{:handler, :sentry_handler, Sentry.LoggerHandler, %{config: %{metadata: [:request_id], capture_log_messages: true, level: :error}}}]` 以捕获 crash reports。
- 激活 Logger Handler:在 `lib/my_app/application.ex` 的 `Application.start/2` 中调用 `Logger.add_handlers(:my_app)` 来激活配置的 `:sentry_handler`。
- Phoenix 集成:在 `lib/my_app_web/endpoint.ex` 中,在 `use Phoenix.Endpoint` 上方添加 `use Sentry.PlugCapture`(仅 Cowboy adapter 需要);在 `plug Plug.Parsers` 使用 `parsers: [:urlencoded, :multipart, :json]`、`pass: ["*/*"]`、`json_decoder: Phoenix.json_library()`,并在其下方添加 `plug Sentry.PlugContext`。
- 注意 `Sentry.PlugCapture` 仅对 Cowboy adapter 必需;Phoenix 1.7+ 默认 Bandit,此时 `PlugCapture` 无害但非必需;`Sentry.PlugContext` 始终推荐,用于给事件补充 HTTP 请求数据。
- LiveView 错误:在 `lib/my_app_web.ex` 的 `live_view` 宏中,在 `use Phoenix.LiveView` 后添加 `on_mount Sentry.LiveViewHook`,以捕获 `mount`/`handle_event`/`handle_info` 中的错误。
- Plain Plug 应用:在 `lib/my_app/router.ex` 中 `use Plug.Router` 和 `use Sentry.PlugCapture`(Cowboy only),在 `plug Plug.Parsers, parsers: [:urlencoded, :multipart]` 后添加 `plug Sentry.PlugContext`。
- 对每个已同意功能逐个处理;按表加载参考文件:Error Monitoring 始终加载 `${SKILL_ROOT}/references/error-monitoring.md`;Tracing 在检测到 Phoenix/Ecto/OpenTelemetry 时加载 `${SKILL_ROOT}/references/tracing.md`;Logging 在设置 `LoggerHandler` 或 Sentry Logs 时加载 `${SKILL_ROOT}/references/logging.md`;Crons 在检测到 Oban、Quantum 或周期性任务时加载 `${SKILL_ROOT}/references/crons.md`。
- 对每个功能执行 `Read ${SKILL_ROOT}/references/<feature>.md`,严格按步骤操作,并验证其工作后再进入下一个。
- 配置参考 `:dsn`:类型 string | nil,默认 nil,SDK 为 nil 时禁用;环境变量 `SENTRY_DSN`。
- 配置参考 `:environment_name`:类型 atom | string,默认 production,例如 `:prod`;环境变量 `SENTRY_ENVIRONMENT`。
- 配置参考 `:release`:类型 string | nil,默认 nil,例如 `my-app@1.0.0`;环境变量 `SENTRY_RELEASE`。
- 配置参考 `:sample_rate`:类型 float,默认 `1.0`,错误事件采样率 `0.0–1.0`。
- 配置参考 `:enable_source_code_context`:类型 boolean,默认 `false`,包含错误附近源代码行。
- 配置参考 `:root_source_code_paths`:类型 `[path]`,默认 `[]`,启用 source context 时必需。
- 配置参考 `:in_app_otp_apps`:类型 `[atom]`,默认 `[]`,指定 stacktrace 中视为 in-app 的 OTP apps。
- 配置参考 `:before_send`:类型 `(event -> event | nil) | {m, f}`,默认 nil,用于修改或丢弃错误事件的 hook。
- 配置参考 `:after_send_event`:类型 `(event, result -> any) | {m, f}`,默认 nil,事件发送后调用的 hook。
- 配置参考 `:filter`:类型 module,默认 `Sentry.DefaultEventFilter`,实现 `Sentry.EventFilter` 的模块。
- 配置参考 `:max_breadcrumbs`:类型 integer,默认 `100`,每进程最大 breadcrumbs。
- 配置参考 `:max_stacktrace_arg_length`:类型 integer,默认 `10000`,stacktrace vars 中每个 inspected 函数参数最大长度(graphemes),v13.2.0+。
- 配置参考 `:dedup_events`:类型 boolean,默认 `true`,在约 30 秒内去重相同事件。
- 配置参考 `:tags`:类型 map,默认 `%{}`,随每个事件发送的全局 tags。
- 配置参考 `:traces_sample_rate`:类型 float | nil,默认 nil,非 nil 启用 tracing(需要 OTel 设置)。
- 配置参考 `:traces_sampler`:类型 fn | {m, f} | nil,默认 nil,自定义每 transaction 采样。
- 配置参考 `:enable_logs`:类型 boolean,默认 `false`,启用 Sentry Logs Protocol(v12.0.0+)。
- 配置参考 `:scrubber`:类型 keyword,默认 `[]`,Scrubber 配置(v13.1.1+);键 `:conn_private_allow_list`(保留在 `Plug.Conn.private` 中的 atom 列表)。
- 配置参考 `:test_mode`:类型 boolean,默认 `false`,在内存中捕获事件以进行测试。
- Default PII:大多数 Sentry SDK 暴露 send-default-PII 选项;截至 sentry v12,Elixir SDK 的文档选项列表或当前 config schema 没有 `send_default_pii`,不要添加不存在的选项;为获得更丰富用户上下文,使用 `Sentry.PlugContext` 并通过 `Sentry.Context.set_user_context/1` 显式设置允许字段,必要时用 `:before_send` 擦除;如果未来 Elixir SDK 发布增加 `send_default_pii`,建议设置它。
- 自动 PII 擦除:自 v13.1.0 起,stacktrace frame variables 和 `FunctionClauseError`/`Phoenix.ActionClauseError` 参数会自动使用与 HTTP 请求数据相同的 scrubber 规则擦除敏感数据;使用 `:scrubber` 配置自定义保留哪些 `Plug.Conn.private` keys。
- 环境变量:`SENTRY_DSN` 映射到 `:dsn`,表示 Data Source Name。
- 环境变量:`SENTRY_RELEASE` 映射到 `:release`,表示 App version,例如 `my-app@1.0.0`。
- 环境变量:`SENTRY_ENVIRONMENT` 映射到 `:environment_name`,表示 Deployment environment。
- 验证:运行 `MIX_ENV=dev mix sentry.send_test_event` 从项目发送测试事件。
- 验证:或在 controller action 中临时添加 `Sentry.capture_message("Sentry Elixir SDK test event")` 和 `text(conn, "sent")`,确认后移除。
- 验证:几秒后检查 Sentry dashboard。若无事件:设置 `config :sentry, log_level: :debug` 获取详细 SDK 输出;验证 `SENTRY_DSN` 已设置且项目存在;确认 `:environment_name` 未被 Sentry 告警规则过滤。
- Phase 4 Cross-Link:运行 `ls assets/ frontend/ web/ client/ ui/ 2>/dev/null` 检查配套前端。
- Phase 4:运行 `cat assets/package.json frontend/package.json 2>/dev/null | grep -E '"react"|"svelte"|"vue"|"next"'` 检测前端框架。
- Phase 4:如果前端目录存在但未配置 Sentry,建议匹配技能:React / Next.js 用 `sentry-react-sdk` 或 `sentry-nextjs-sdk`;Svelte / SvelteKit 用 `sentry-svelte-sdk`;Vue 参考 `docs.sentry.io/platforms/javascript/guides/vue/`;其他 JS/TS 用 `sentry-browser-sdk`。
- Phase 4:连接 Phoenix 后端和 JavaScript 前端的关联 Sentry 项目可实现 distributed tracing,在单个 trace view 中跨浏览器、Phoenix HTTP server 和下游服务查看 stack traces。
- Troubleshooting:Events not appearing -> 验证 `SENTRY_DSN` 已设置;运行 `mix sentry.send_test_event`;设置 `log_level: :debug`。
- Troubleshooting:Missing stack traces on captured exceptions -> 在 `rescue` 块中传递 `stacktrace: __STACKTRACE__`:`Sentry.capture_exception(e, stacktrace: __STACKTRACE__)`。
- Troubleshooting:`PlugCapture` not working on Bandit -> `Sentry.PlugCapture` 仅限 Cowboy;使用 Bandit 时错误通过 `LoggerHandler` 暴露。
- Troubleshooting:Source code context missing in production -> 在构建 OTP release 前运行 `mix sentry.package_source_code`。
- Troubleshooting:Context not appearing on async events -> `Sentry.Context.*` 是进程作用域;显式传递值或在进程间传播 Logger metadata。
- Troubleshooting:Oban integration not reporting crons -> 需要 Oban v2.17.6+ 或 Oban Pro;cron jobs 必须在 job meta 中有 `"cron" => true`。
- Troubleshooting:Duplicate events from Cowboy/Bandit crashes -> 在 `LoggerHandler` 配置中设置 `excluded_domains: [:cowboy, :bandit]`(截至 v13.1.0 两者默认排除)。
- Troubleshooting:`finch` not starting -> 确保 deps 中有 `{:finch, "~> 0.21"}`;自 v12.0.0 起 Finch 是默认 HTTP client。
- Troubleshooting:JSON encoding error -> 对 Elixir < 1.18,添加 `{:jason, "~> 1.4"}` 并设置 `json_library: Jason`。
适用边界 · 注意事项
- 项目不是 Elixir/Phoenix/Plug/LiveView/Oban/Quantum 技术栈时,不应套用此技能。
- 使用 Bandit 适配器时不要依赖 `Sentry.PlugCapture` 捕获错误,应改用 `LoggerHandler`;`PlugCapture` 仅对 Cowboy 有效。
- Elixir 版本低于 `~> 1.13` 或无法使用 Sentry 服务/DSN 时,不应按本文安装 sentry v13 配置。