Skip to content

Commit 30a684a

Browse files
authored
Add cron integration for Oban (#698)
1 parent c5c959b commit 30a684a

File tree

7 files changed

+398
-10
lines changed

7 files changed

+398
-10
lines changed

lib/sentry/application.ex

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ defmodule Sentry.Application do
2727
cache_loaded_applications()
2828
_ = Sources.load_source_code_map_if_present()
2929

30-
Supervisor.start_link(children, strategy: :one_for_one, name: Sentry.Supervisor)
30+
with {:ok, pid} <-
31+
Supervisor.start_link(children, strategy: :one_for_one, name: Sentry.Supervisor) do
32+
start_integrations(config)
33+
{:ok, pid}
34+
end
3135
end
3236

3337
defp cache_loaded_applications do
@@ -42,4 +46,10 @@ defmodule Sentry.Application do
4246

4347
:persistent_term.put({:sentry, :loaded_applications}, apps_with_vsns)
4448
end
49+
50+
defp start_integrations(config) do
51+
if config[:oban][:cron][:enabled] do
52+
Sentry.Cron.Oban.attach_telemetry_handler()
53+
end
54+
end
4555
end

lib/sentry/config.ex

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,35 @@
11
defmodule Sentry.Config do
22
@moduledoc false
33

4+
integrations_schema = [
5+
oban: [
6+
type: :keyword_list,
7+
doc: """
8+
Configuration for the [Oban](https://github.com/sorentwo/oban) integration. *Available
9+
since v10.2.0*.
10+
""",
11+
keys: [
12+
cron: [
13+
doc: """
14+
Configuration options for configuring [*crons*](https://docs.sentry.io/product/crons/)
15+
for Oban.
16+
""",
17+
type: :keyword_list,
18+
keys: [
19+
enabled: [
20+
type: :boolean,
21+
default: false,
22+
doc: """
23+
Whether to enable the Oban integration. When enabled, the Sentry SDK will
24+
capture check-ins for Oban jobs. *Available since v10.2.0*.
25+
"""
26+
]
27+
]
28+
]
29+
]
30+
]
31+
]
32+
433
basic_opts_schema = [
534
dsn: [
635
type: {:or, [nil, {:custom, __MODULE__, :__validate_string_dsn__, []}]},
@@ -147,6 +176,15 @@ defmodule Sentry.Config do
147176
there is a process **collecting events** and avoid sending those events if that's the
148177
case. This is useful for testing. See `Sentry.Test`.
149178
"""
179+
],
180+
integrations: [
181+
type: :keyword_list,
182+
doc: """
183+
Configuration for integrations with third-party libraries. Every integration has its own
184+
option and corresponding configuration options.
185+
""",
186+
default: [],
187+
keys: integrations_schema
150188
]
151189
]
152190

lib/sentry/cron/oban.ex

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
defmodule Sentry.Cron.Oban do
2+
@moduledoc false
3+
4+
@events [
5+
[:oban, :job, :start],
6+
[:oban, :job, :stop],
7+
[:oban, :job, :exception]
8+
]
9+
10+
@spec attach_telemetry_handler() :: :ok
11+
def attach_telemetry_handler do
12+
_ = :telemetry.attach_many(__MODULE__, @events, &__MODULE__.handle_event/4, :no_config)
13+
:ok
14+
end
15+
16+
@spec handle_event([atom()], term(), term(), :no_config) :: :ok
17+
def handle_event(event, measurements, metadata, _config)
18+
19+
def handle_event(
20+
[:oban, :job, event],
21+
measurements,
22+
%{job: %mod{meta: %{"cron" => true, "cron_expr" => cron_expr}}} = metadata,
23+
_config
24+
)
25+
when event in [:start, :stop, :exception] and mod == Oban.Job and is_binary(cron_expr) do
26+
_ = handle_event(event, measurements, metadata)
27+
:ok
28+
end
29+
30+
def handle_event([:oban, :job, event], _measurements, _metadata, _config)
31+
when event in [:start, :stop, :exception] do
32+
:ok
33+
end
34+
35+
## Helpers
36+
37+
defp handle_event(:start, _measurements, metadata) do
38+
if opts = job_to_check_in_opts(metadata.job) do
39+
opts
40+
|> Keyword.merge(status: :in_progress)
41+
|> Sentry.capture_check_in()
42+
end
43+
end
44+
45+
defp handle_event(:stop, measurements, metadata) do
46+
if opts = job_to_check_in_opts(metadata.job) do
47+
status =
48+
case metadata.state do
49+
:success -> :ok
50+
:failure -> :error
51+
:cancelled -> :ok
52+
:discard -> :ok
53+
:snoozed -> :ok
54+
end
55+
56+
opts
57+
|> Keyword.merge(status: status, duration: duration_in_seconds(measurements))
58+
|> Sentry.capture_check_in()
59+
end
60+
end
61+
62+
defp handle_event(:exception, measurements, metadata) do
63+
if opts = job_to_check_in_opts(metadata.job) do
64+
opts
65+
|> Keyword.merge(status: :error, duration: duration_in_seconds(measurements))
66+
|> Sentry.capture_check_in()
67+
end
68+
end
69+
70+
defp job_to_check_in_opts(job) when is_struct(job, Oban.Job) do
71+
if schedule_opts = schedule_opts(job) do
72+
[
73+
check_in_id: "oban-#{job.id}",
74+
# This is already a binary.
75+
monitor_slug: job.worker,
76+
monitor_config: [schedule: schedule_opts]
77+
]
78+
else
79+
nil
80+
end
81+
end
82+
83+
defp schedule_opts(%{meta: meta} = job) when is_struct(job, Oban.Job) do
84+
case meta["cron_expr"] do
85+
"@hourly" -> [type: :interval, value: 1, unit: :hour]
86+
"@daily" -> [type: :interval, value: 1, unit: :day]
87+
"@weekly" -> [type: :interval, value: 1, unit: :week]
88+
"@monthly" -> [type: :interval, value: 1, unit: :month]
89+
"@yearly" -> [type: :interval, value: 1, unit: :year]
90+
"@annually" -> [type: :interval, value: 1, unit: :year]
91+
"@reboot" -> nil
92+
cron_expr when is_binary(cron_expr) -> [type: :crontab, value: cron_expr]
93+
_other -> nil
94+
end
95+
end
96+
97+
defp duration_in_seconds(%{duration: duration} = _measurements) do
98+
duration
99+
|> System.convert_time_unit(:native, :millisecond)
100+
|> Kernel./(1000)
101+
end
102+
end

mix.exs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,17 @@ defmodule Sentry.Mixfile do
3131
"README.md",
3232
"CHANGELOG.md",
3333
"pages/setup-with-plug-and-phoenix.md",
34+
"pages/oban-integration.md",
3435
"pages/upgrade-8.x.md",
3536
"pages/upgrade-9.x.md",
3637
"pages/upgrade-10.x.md"
3738
],
3839
groups_for_extras: [
39-
"Upgrade Guides": [
40-
"pages/upgrade-8.x.md",
41-
"pages/upgrade-9.x.md",
42-
"pages/upgrade-10.x.md"
43-
]
40+
Integrations: [
41+
"pages/setup-with-plug-and-phoenix.md",
42+
"pages/oban-integration.md"
43+
],
44+
"Upgrade Guides": [~r{^pages/upgrade}]
4445
],
4546
groups_for_modules: [
4647
"Plug and Phoenix": [Sentry.PlugCapture, Sentry.PlugContext],
@@ -58,7 +59,7 @@ defmodule Sentry.Mixfile do
5859
],
5960
authors: ["Mitchell Henke", "Jason Stiebs", "Andrea Leopardi"]
6061
],
61-
xref: [exclude: [:hackney, :hackney_pool, Plug.Conn]],
62+
xref: [exclude: [:hackney, :hackney_pool, Plug.Conn, :telemetry]],
6263
aliases: [aliases()]
6364
]
6465
end
@@ -87,6 +88,7 @@ defmodule Sentry.Mixfile do
8788
{:hackney, "~> 1.8", optional: true},
8889
{:jason, "~> 1.1", optional: true},
8990
{:plug, "~> 1.6", optional: true},
91+
{:telemetry, "~> 0.4 or ~> 1.0", optional: true},
9092

9193
# Dev and test dependencies
9294
{:bypass, "~> 2.0", only: [:test]},
@@ -95,7 +97,16 @@ defmodule Sentry.Mixfile do
9597
{:excoveralls, "~> 0.17.1", only: [:test]},
9698
{:phoenix, "~> 1.5", only: [:test]},
9799
{:phoenix_html, "~> 2.0", only: [:test]}
98-
]
100+
] ++ maybe_oban_optional_dependency()
101+
end
102+
103+
# TODO: Remove this once we drop support for Elixir 1.13.
104+
defp maybe_oban_optional_dependency do
105+
if Version.match?(System.version(), "~> 1.13") do
106+
[{:oban, "~> 2.17 and >= 2.17.6", only: [:test]}]
107+
else
108+
[]
109+
end
99110
end
100111

101112
defp package do

mix.lock

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
"cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
55
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"},
66
"cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
7+
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
8+
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
79
"dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"},
810
"earmark_parser": {:hex, :earmark_parser, "1.4.32", "fa739a0ecfa34493de19426681b23f6814573faee95dfd4b4aafe15a7b5b32c6", [:mix], [], "hexpm", "b8b0dd77d60373e77a3d7e8afa598f325e49e8663a51bcc2b88ef41838cca755"},
11+
"ecto": {:hex, :ecto, "3.11.1", "4b4972b717e7ca83d30121b12998f5fcdc62ba0ed4f20fd390f16f3270d85c3e", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ebd3d3772cd0dfcd8d772659e41ed527c28b2a8bde4b00fe03e0463da0f1983b"},
12+
"ecto_sql": {:hex, :ecto_sql, "3.11.1", "e9abf28ae27ef3916b43545f9578b4750956ccea444853606472089e7d169470", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ce14063ab3514424276e7e360108ad6c2308f6d88164a076aac8a387e1fea634"},
913
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
1014
"ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"},
1115
"excoveralls": {:hex, :excoveralls, "0.17.1", "83fa7906ef23aa7fc8ad7ee469c357a63b1b3d55dd701ff5b9ce1f72442b2874", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "95bc6fda953e84c60f14da4a198880336205464e75383ec0f570180567985ae0"},
1216
"hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"},
1317
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
14-
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
18+
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
1519
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
1620
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
1721
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
@@ -21,6 +25,7 @@
2125
"nimble_options": {:hex, :nimble_options, "1.0.2", "92098a74df0072ff37d0c12ace58574d26880e522c22801437151a159392270e", [:mix], [], "hexpm", "fd12a8db2021036ce12a309f26f564ec367373265b53e25403f0ee697380f1b8"},
2226
"nimble_ownership": {:hex, :nimble_ownership, "0.2.1", "3e44c72ebe8dd213db4e13aff4090aaa331d158e72ce1891d02e0ffb05a1eb2d", [:mix], [], "hexpm", "bf38d2ef4fb990521a4ecf112843063c1f58a5c602484af4c7977324042badee"},
2327
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
28+
"oban": {:hex, :oban, "2.17.6", "bac1dacd836edbf6a200ddd880db10faa2d39bb2e550ec6d19b3eb9c43852c2a", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "623f3554212e9a776e015156c47f076d66c7b74115ac47a7d3acba0294e65acb"},
2429
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
2530
"phoenix": {:hex, :phoenix, "1.5.8", "71cfa7a9bb9a37af4df98939790642f210e35f696b935ca6d9d9c55a884621a4", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "35ded0a32f4836168c7ab6c33b88822eccd201bcd9492125a9bea4c54332d955"},
2631
"phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
@@ -30,6 +35,6 @@
3035
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
3136
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
3237
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
33-
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
38+
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
3439
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
3540
}

pages/oban-integration.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Oban Integration
2+
3+
The Sentry SDK supports integrating with [Oban](https://github.com/sorentwo/oban), one of the most widely-used job-scheduling libraries in the Elixir ecosystem.
4+
5+
The Oban integration is available since *v10.2.0* of the Sentry SDK, and it requires:
6+
7+
1. Oban to be a dependency of your application.
8+
1. Oban version 2.17.6 or greater.
9+
1. Elixir 1.13 or later, since that is required by Oban itself.
10+
11+
## Cron Support
12+
13+
To enable support for monitoring Oban jobs via [Sentry Cron](https://docs.sentry.io/product/crons/), make sure the following `:oban` configuration is in your Sentry configuration:
14+
15+
```elixir
16+
config :sentry,
17+
# ...,
18+
integrations: [
19+
oban: [
20+
cron: [enabled: true]
21+
]
22+
]
23+
```
24+
25+
This configuration will report started, completed, and failed job, alongside their duration. It will use the worker name as the `monitor_slug` of the reported cron.

0 commit comments

Comments
 (0)