Packages
sentry
10.8.1
13.3.0
13.2.0
13.1.0
13.0.1
13.0.0
12.0.3
12.0.2
12.0.1
12.0.0
11.0.4
11.0.3
11.0.2
11.0.1
11.0.0
10.10.0
10.9.0
10.8.1
10.8.0
10.7.1
10.7.0
10.6.2
10.6.1
10.6.0
10.5.0
10.4.0
10.3.0
10.2.1
10.2.0
10.2.0-rc.2
10.2.0-rc.1
10.1.0
10.0.3
10.0.2
10.0.1
10.0.0
9.1.0
9.0.0
8.1.0
8.0.6
8.0.5
8.0.4
8.0.3
8.0.2
8.0.1
8.0.0
8.0.0-rc.2
8.0.0-rc.1
8.0.0-rc.0
retired
7.2.5
7.2.4
7.2.3
7.2.2
7.2.1
7.2.0
7.1.0
7.0.6
7.0.5
7.0.4
7.0.3
7.0.2
7.0.1
7.0.0
6.4.2
6.4.1
6.4.0
6.3.0
6.2.1
6.2.0
6.1.0
6.0.5
6.0.4
6.0.3
6.0.2
6.0.1
6.0.0
5.0.1
5.0.0
4.0.3
4.0.2
4.0.1
4.0.0
3.0.0
2.2.0
2.1.0
2.0.2
2.0.1
2.0.0
1.1.2
1.1.1
1.1.0
1.0.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
The Official Elixir client for Sentry
Current section
Files
Jump to
Current section
Files
lib/sentry/integrations/oban/cron.ex
defmodule Sentry.Integrations.Oban.Cron do
@moduledoc false
alias Sentry.Integrations.CheckInIDMappings
@events [
[:oban, :job, :start],
[:oban, :job, :stop],
[:oban, :job, :exception]
]
@spec attach_telemetry_handler(keyword()) :: :ok
def attach_telemetry_handler(config) when is_list(config) do
_ = :telemetry.attach_many(__MODULE__, @events, &__MODULE__.handle_event/4, config)
:ok
end
@spec handle_event([atom()], term(), term(), keyword()) :: :ok
def handle_event(event, measurements, metadata, config)
def handle_event(
[:oban, :job, event],
measurements,
%{job: %mod{meta: %{"cron" => true, "cron_expr" => cron_expr}}} = metadata,
config
)
when event in [:start, :stop, :exception] and mod == Oban.Job and is_binary(cron_expr) do
_ = handle_oban_job_event(event, measurements, metadata, config)
:ok
end
def handle_event([:oban, :job, event], _measurements, _metadata, _config)
when event in [:start, :stop, :exception] do
:ok
end
## Helpers
defp handle_oban_job_event(:start, _measurements, metadata, config) do
if opts = job_to_check_in_opts(metadata.job, config) do
opts
|> Keyword.merge(status: :in_progress)
|> Sentry.capture_check_in()
end
end
defp handle_oban_job_event(:stop, measurements, metadata, config) do
if opts = job_to_check_in_opts(metadata.job, config) do
status =
case metadata.state do
:success -> :ok
:failure -> :error
:cancelled -> :ok
:discard -> :ok
:snoozed -> :ok
end
opts
|> Keyword.merge(status: status, duration: duration_in_seconds(measurements))
|> Sentry.capture_check_in()
end
end
defp handle_oban_job_event(:exception, measurements, metadata, config) do
if opts = job_to_check_in_opts(metadata.job, config) do
opts
|> Keyword.merge(status: :error, duration: duration_in_seconds(measurements))
|> Sentry.capture_check_in()
end
end
defp job_to_check_in_opts(job, config) when is_struct(job, Oban.Job) do
monitor_config_opts = Sentry.Config.integrations()[:monitor_config_defaults]
monitor_slug =
case config[:monitor_slug_generator] do
nil ->
slugify(job.worker)
{mod, fun} when is_atom(mod) and is_atom(fun) ->
mod |> apply(fun, [job]) |> slugify()
end
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: monitor_slug,
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" -> [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
defp duration_in_seconds(%{duration: duration} = _measurements) do
duration
|> System.convert_time_unit(:native, :millisecond)
|> Kernel./(1000)
end
# MyApp.SomeWorker -> "my-app-some-worker"
defp slugify(worker_name) do
worker_name
|> String.split(".")
|> Enum.map_join("-", &(&1 |> Macro.underscore() |> String.replace("_", "-")))
|> String.slice(0, 50)
end
end