Skip to content

Commit

Permalink
Add :monitor_config_defaults integrations option (#782)
Browse files Browse the repository at this point in the history
  • Loading branch information
whatyouhide authored Sep 3, 2024
1 parent bcdcc04 commit 2b6d68e
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 22 deletions.
2 changes: 1 addition & 1 deletion lib/sentry/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule Sentry.Application do
[]
end

integrations_config = Keyword.fetch!(config, :integrations)
integrations_config = Config.integrations()

children =
[
Expand Down
6 changes: 5 additions & 1 deletion lib/sentry/check_in.ex
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ defmodule Sentry.CheckIn do
"""
],
monitor_config: [
doc: "If you pass this optional option, you **must** pass the nested `:schedule` option.",
doc: """
If you pass this optional option, you **must** pass the nested `:schedule` option. The
options below are described in detail in the [Sentry
documentation](https://develop.sentry.dev/sdk/telemetry/check-ins/#monitor-upsert-support).
""",
type: :keyword_list,
keys: [
checkin_margin: number_schema_opts,
Expand Down
13 changes: 13 additions & 0 deletions lib/sentry/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ defmodule Sentry.Config do
*Available since 10.6.3*.
"""
],
monitor_config_defaults: [
type: :keyword_list,
default: [],
doc: """
Defaults to be used for the `monitor_config` when reporting cron jobs with one of the
integrations. This supports all the keys defined in the [Sentry
documentation](https://develop.sentry.dev/sdk/telemetry/check-ins/#monitor-upsert-support).
See also `Sentry.CheckIn.new/1`. *Available since v10.8.0*.
"""
],
oban: [
type: :keyword_list,
doc: """
Expand Down Expand Up @@ -555,6 +565,9 @@ defmodule Sentry.Config do
@spec test_mode?() :: boolean()
def test_mode?, do: fetch!(:test_mode)

@spec integrations() :: keyword()
def integrations, do: fetch!(:integrations)

@spec put_config(atom(), term()) :: :ok
def put_config(key, value) when is_atom(key) do
unless key in @valid_keys do
Expand Down
44 changes: 24 additions & 20 deletions lib/sentry/integrations/oban/cron.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,35 @@ defmodule Sentry.Integrations.Oban.Cron do
end

defp job_to_check_in_opts(job) when is_struct(job, Oban.Job) do
if schedule_opts = schedule_opts(job) do
id = CheckInIDMappings.lookup_or_insert_new(job.id)

[
check_in_id: id,
# This is already a binary.
monitor_slug: slugify(job.worker),
monitor_config: [schedule: schedule_opts]
]
else
nil
monitor_config_opts = Sentry.Config.integrations()[:monitor_config_defaults]

case Keyword.merge(monitor_config_opts, schedule_opts(job)) do
[] ->
nil

monitor_config_opts ->
id = CheckInIDMappings.lookup_or_insert_new(job.id)

[
check_in_id: id,
# This is already a binary.
monitor_slug: slugify(job.worker),
monitor_config: monitor_config_opts
]
end
end

defp schedule_opts(%{meta: meta} = job) when is_struct(job, Oban.Job) do
case meta["cron_expr"] do
"@hourly" -> [type: :interval, value: 1, unit: :hour]
"@daily" -> [type: :interval, value: 1, unit: :day]
"@weekly" -> [type: :interval, value: 1, unit: :week]
"@monthly" -> [type: :interval, value: 1, unit: :month]
"@yearly" -> [type: :interval, value: 1, unit: :year]
"@annually" -> [type: :interval, value: 1, unit: :year]
"@reboot" -> nil
cron_expr when is_binary(cron_expr) -> [type: :crontab, value: cron_expr]
_other -> nil
"@hourly" -> [schedule: [type: :interval, value: 1, unit: :hour]]
"@daily" -> [schedule: [type: :interval, value: 1, unit: :day]]
"@weekly" -> [schedule: [type: :interval, value: 1, unit: :week]]
"@monthly" -> [schedule: [type: :interval, value: 1, unit: :month]]
"@yearly" -> [schedule: [type: :interval, value: 1, unit: :year]]
"@annually" -> [schedule: [type: :interval, value: 1, unit: :year]]
"@reboot" -> []
cron_expr when is_binary(cron_expr) -> [schedule: [type: :crontab, value: cron_expr]]
_other -> []
end
end

Expand Down
45 changes: 45 additions & 0 deletions test/sentry/integrations/oban/cron_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,49 @@ defmodule Sentry.Integrations.Oban.CronTest do

assert_receive {^ref, :done}, 1000
end

test "uses default monitor configuration in Sentry's config if present", %{bypass: bypass} do
put_test_config(
integrations: [
monitor_config_defaults: [
checkin_margin: 10,
max_runtime: 42,
failure_issue_threshold: 84
]
]
)

test_pid = self()
ref = make_ref()

Bypass.expect_once(bypass, "POST", "/api/1/envelope/", fn conn ->
{:ok, body, conn} = Plug.Conn.read_body(conn)
assert [{_headers, check_in_body}] = decode_envelope!(body)

assert check_in_body["monitor_config"] == %{
"checkin_margin" => 10,
"failure_issue_threshold" => 84,
"max_runtime" => 42,
"schedule" => %{
"type" => "crontab",
"value" => "* 1 1 1 1"
}
}

send(test_pid, {ref, :done})

Plug.Conn.send_resp(conn, 200, ~s<{"id": "1923"}>)
end)

:telemetry.execute([:oban, :job, :exception], %{duration: 0}, %{
state: :success,
job: %Oban.Job{
worker: "Sentry.MyWorker",
id: 942,
meta: %{"cron" => true, "cron_expr" => "* 1 1 1 1"}
}
})

assert_receive {^ref, :done}, 1000
end
end

0 comments on commit 2b6d68e

Please sign in to comment.