Skip to content

Commit 2b6d68e

Browse files
authored
Add :monitor_config_defaults integrations option (#782)
1 parent bcdcc04 commit 2b6d68e

File tree

5 files changed

+88
-22
lines changed

5 files changed

+88
-22
lines changed

lib/sentry/application.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ defmodule Sentry.Application do
1919
[]
2020
end
2121

22-
integrations_config = Keyword.fetch!(config, :integrations)
22+
integrations_config = Config.integrations()
2323

2424
children =
2525
[

lib/sentry/check_in.ex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ defmodule Sentry.CheckIn do
115115
"""
116116
],
117117
monitor_config: [
118-
doc: "If you pass this optional option, you **must** pass the nested `:schedule` option.",
118+
doc: """
119+
If you pass this optional option, you **must** pass the nested `:schedule` option. The
120+
options below are described in detail in the [Sentry
121+
documentation](https://develop.sentry.dev/sdk/telemetry/check-ins/#monitor-upsert-support).
122+
""",
119123
type: :keyword_list,
120124
keys: [
121125
checkin_margin: number_schema_opts,

lib/sentry/config.ex

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ defmodule Sentry.Config do
1717
*Available since 10.6.3*.
1818
"""
1919
],
20+
monitor_config_defaults: [
21+
type: :keyword_list,
22+
default: [],
23+
doc: """
24+
Defaults to be used for the `monitor_config` when reporting cron jobs with one of the
25+
integrations. This supports all the keys defined in the [Sentry
26+
documentation](https://develop.sentry.dev/sdk/telemetry/check-ins/#monitor-upsert-support).
27+
See also `Sentry.CheckIn.new/1`. *Available since v10.8.0*.
28+
"""
29+
],
2030
oban: [
2131
type: :keyword_list,
2232
doc: """
@@ -555,6 +565,9 @@ defmodule Sentry.Config do
555565
@spec test_mode?() :: boolean()
556566
def test_mode?, do: fetch!(:test_mode)
557567

568+
@spec integrations() :: keyword()
569+
def integrations, do: fetch!(:integrations)
570+
558571
@spec put_config(atom(), term()) :: :ok
559572
def put_config(key, value) when is_atom(key) do
560573
unless key in @valid_keys do

lib/sentry/integrations/oban/cron.ex

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,35 @@ defmodule Sentry.Integrations.Oban.Cron do
6969
end
7070

7171
defp job_to_check_in_opts(job) when is_struct(job, Oban.Job) do
72-
if schedule_opts = schedule_opts(job) do
73-
id = CheckInIDMappings.lookup_or_insert_new(job.id)
74-
75-
[
76-
check_in_id: id,
77-
# This is already a binary.
78-
monitor_slug: slugify(job.worker),
79-
monitor_config: [schedule: schedule_opts]
80-
]
81-
else
82-
nil
72+
monitor_config_opts = Sentry.Config.integrations()[:monitor_config_defaults]
73+
74+
case Keyword.merge(monitor_config_opts, schedule_opts(job)) do
75+
[] ->
76+
nil
77+
78+
monitor_config_opts ->
79+
id = CheckInIDMappings.lookup_or_insert_new(job.id)
80+
81+
[
82+
check_in_id: id,
83+
# This is already a binary.
84+
monitor_slug: slugify(job.worker),
85+
monitor_config: monitor_config_opts
86+
]
8387
end
8488
end
8589

8690
defp schedule_opts(%{meta: meta} = job) when is_struct(job, Oban.Job) do
8791
case meta["cron_expr"] do
88-
"@hourly" -> [type: :interval, value: 1, unit: :hour]
89-
"@daily" -> [type: :interval, value: 1, unit: :day]
90-
"@weekly" -> [type: :interval, value: 1, unit: :week]
91-
"@monthly" -> [type: :interval, value: 1, unit: :month]
92-
"@yearly" -> [type: :interval, value: 1, unit: :year]
93-
"@annually" -> [type: :interval, value: 1, unit: :year]
94-
"@reboot" -> nil
95-
cron_expr when is_binary(cron_expr) -> [type: :crontab, value: cron_expr]
96-
_other -> nil
92+
"@hourly" -> [schedule: [type: :interval, value: 1, unit: :hour]]
93+
"@daily" -> [schedule: [type: :interval, value: 1, unit: :day]]
94+
"@weekly" -> [schedule: [type: :interval, value: 1, unit: :week]]
95+
"@monthly" -> [schedule: [type: :interval, value: 1, unit: :month]]
96+
"@yearly" -> [schedule: [type: :interval, value: 1, unit: :year]]
97+
"@annually" -> [schedule: [type: :interval, value: 1, unit: :year]]
98+
"@reboot" -> []
99+
cron_expr when is_binary(cron_expr) -> [schedule: [type: :crontab, value: cron_expr]]
100+
_other -> []
97101
end
98102
end
99103

test/sentry/integrations/oban/cron_test.exs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,49 @@ defmodule Sentry.Integrations.Oban.CronTest do
194194

195195
assert_receive {^ref, :done}, 1000
196196
end
197+
198+
test "uses default monitor configuration in Sentry's config if present", %{bypass: bypass} do
199+
put_test_config(
200+
integrations: [
201+
monitor_config_defaults: [
202+
checkin_margin: 10,
203+
max_runtime: 42,
204+
failure_issue_threshold: 84
205+
]
206+
]
207+
)
208+
209+
test_pid = self()
210+
ref = make_ref()
211+
212+
Bypass.expect_once(bypass, "POST", "/api/1/envelope/", fn conn ->
213+
{:ok, body, conn} = Plug.Conn.read_body(conn)
214+
assert [{_headers, check_in_body}] = decode_envelope!(body)
215+
216+
assert check_in_body["monitor_config"] == %{
217+
"checkin_margin" => 10,
218+
"failure_issue_threshold" => 84,
219+
"max_runtime" => 42,
220+
"schedule" => %{
221+
"type" => "crontab",
222+
"value" => "* 1 1 1 1"
223+
}
224+
}
225+
226+
send(test_pid, {ref, :done})
227+
228+
Plug.Conn.send_resp(conn, 200, ~s<{"id": "1923"}>)
229+
end)
230+
231+
:telemetry.execute([:oban, :job, :exception], %{duration: 0}, %{
232+
state: :success,
233+
job: %Oban.Job{
234+
worker: "Sentry.MyWorker",
235+
id: 942,
236+
meta: %{"cron" => true, "cron_expr" => "* 1 1 1 1"}
237+
}
238+
})
239+
240+
assert_receive {^ref, :done}, 1000
241+
end
197242
end

0 commit comments

Comments
 (0)