Sentry: report crashes outside requests, and Oban jobs that run out of attempts

cb6d110 · gmorell · 2026-11-09 06:07

10 files +33 -5
Message
{commit_body(@commit)}

Files changed

modified apps/room_sanctum/config/config.exs
+0 −4
@@ -61,10 +61,6 @@ config :tailwind,
61 61 cd: Path.expand("../assets", __DIR__)
62 62 ]
63 63
64 −# Configures Elixir's Logger
65 −config :logger,
66 − backends: [:console, Sentry.LoggerBackend]
67 −
68 64 config :logger, :console,
69 65 format: "$time $metadata[$level] $message\n",
70 66 metadata: [:request_id]
modified apps/room_sanctum/lib/room_sanctum/application.ex
+4 −0
@@ -7,6 +7,10 @@ defmodule RoomSanctum.Application do
7 7
8 8 @impl true
9 9 def start(_type, _args) do
10 + # The :logger handlers named under this app's config -- in prod, Sentry's
11 + # crash reporting (see config/prod.exs). Nothing elsewhere.
12 + Logger.add_handlers(:room_sanctum)
13 +
10 14 children = [
11 15 # Start the Ecto repository
12 16 RoomSanctum.Repo,
modified config/prod.exs
+17 −0
@@ -113,3 +113,20 @@ config :logger, level: :info
113 113 config :sentry,
114 114 enable_source_code_context: true,
115 115 root_source_code_paths: Path.wildcard(Path.expand("../apps/*", __DIR__))
116 +
117 +# Crashes outside a web request -- a worker's GenServer dying, a Task, an Oban
118 +# job's process -- reach Sentry only through a :logger handler; Sentry.PlugCapture
119 +# sees requests and nothing else. RoomSanctum.Application attaches this at
120 +# startup. Crash reports only, not logged errors (capture_log_messages stays
121 +# false), and rate-limited, because a worker in a restart loop logs the same
122 +# crash every second. Cowboy and Bandit are left out by default, since
123 +# PlugCapture has already reported those.
124 +config :room_sanctum, :logger, [
125 + {:handler, :sentry_handler, Sentry.LoggerHandler,
126 + %{
127 + config: %{
128 + capture_metadata: [:request_id, :mfa],
129 + rate_limiting: [max_events: 10, interval: 60_000]
130 + }
131 + }}
132 +]
modified config/runtime.exs
+12 −1
@@ -182,7 +182,18 @@ if config_env() == :prod do
182 182 environment_name: :prod,
183 183 tags: %{
184 184 env: "production"
185 − }
185 + },
186 + # Oban catches what a job raises, so a failing job never reaches the
187 + # logger handler as a crash. Reported on its last attempt only: a feed
188 + # that is down for one retry is not news, one that has used them all is.
189 + # Here rather than prod.exs because a release cannot carry a function in
190 + # its compiled config.
191 + integrations: [
192 + oban: [
193 + capture_errors: true,
194 + should_report_error_callback: fn _worker, job -> job.attempt >= job.max_attempts end
195 + ]
196 + ]
186 197
187 198 else
188 199

Parents: 9d57f0c