Skip to content

Commit b15879f

Browse files
committed
feat(oban): add option to include job tags into reported exception tags
1 parent 1a76fa1 commit b15879f

File tree

4 files changed

+49
-12
lines changed

4 files changed

+49
-12
lines changed

lib/sentry/application.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ defmodule Sentry.Application do
7777
end
7878

7979
if config[:oban][:capture_errors] do
80-
Sentry.Integrations.Oban.ErrorReporter.attach()
80+
Sentry.Integrations.Oban.ErrorReporter.attach(config[:oban])
8181
end
8282

8383
if config[:quantum][:cron][:enabled] do

lib/sentry/config.ex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ defmodule Sentry.Config do
5151
tuples. *Available since 10.3.0*.
5252
"""
5353
],
54+
oban_tags: [
55+
type: :boolean,
56+
default: false,
57+
doc: """
58+
Whether to include Oban job tags in Sentry error tags. When enabled, the `job.tags`
59+
will be joined with a "," and added as an `oban_tags` tag to Sentry events.
60+
"""
61+
],
5462
cron: [
5563
doc: """
5664
Configuration options for configuring [*crons*](https://docs.sentry.io/product/crons/)

lib/sentry/integrations/oban/error_reporter.ex

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ defmodule Sentry.Integrations.Oban.ErrorReporter do
44
# See this blog post:
55
# https://getoban.pro/articles/enhancing-error-reporting
66

7-
@spec attach() :: :ok
8-
def attach do
7+
@spec attach(keyword()) :: :ok
8+
def attach(config \\ []) when is_list(config) do
99
_ =
1010
:telemetry.attach(
1111
__MODULE__,
1212
[:oban, :job, :exception],
1313
&__MODULE__.handle_event/4,
14-
:no_config
14+
config
1515
)
1616

1717
:ok
@@ -21,32 +21,41 @@ defmodule Sentry.Integrations.Oban.ErrorReporter do
2121
[atom(), ...],
2222
term(),
2323
%{required(:job) => struct(), optional(term()) => term()},
24-
:no_config
24+
keyword()
2525
) :: :ok
2626
def handle_event(
2727
[:oban, :job, :exception],
2828
_measurements,
2929
%{job: job, kind: kind, reason: reason, stacktrace: stacktrace} = _metadata,
30-
:no_config
30+
config
3131
) do
3232
if report?(reason) do
33-
report(job, kind, reason, stacktrace)
33+
report(job, kind, reason, stacktrace, config)
3434
else
3535
:ok
3636
end
3737
end
3838

39-
defp report(job, kind, reason, stacktrace) do
39+
defp report(job, kind, reason, stacktrace, config) do
4040
stacktrace =
4141
case {apply(Oban.Worker, :from_string, [job.worker]), stacktrace} do
4242
{{:ok, atom_worker}, []} -> [{atom_worker, :process, 1, []}]
4343
_ -> stacktrace
4444
end
4545

46+
base_tags = %{oban_worker: job.worker, oban_queue: job.queue, oban_state: job.state}
47+
48+
tags =
49+
if config[:oban_tags] and is_list(job.tags) and length(job.tags) > 0 do
50+
Map.put(base_tags, :oban_tags, Enum.join(job.tags, ","))
51+
else
52+
base_tags
53+
end
54+
4655
opts =
4756
[
4857
stacktrace: stacktrace,
49-
tags: %{oban_worker: job.worker, oban_queue: job.queue, oban_state: job.state},
58+
tags: tags,
5059
fingerprint: [job.worker, "{{ default }}"],
5160
extra:
5261
Map.take(job, [:args, :attempt, :id, :max_attempts, :meta, :queue, :tags, :worker]),

test/sentry/integrations/oban/error_reporter_test.exs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Sentry.Integrations.Oban.ErrorReporterTest do
44
alias Sentry.Integrations.Oban.ErrorReporter
55

66
defmodule MyWorker do
7-
use Oban.Worker
7+
use Oban.Worker, tags: ["tag1", "tag2"]
88

99
@impl Oban.Worker
1010
def perform(%Oban.Job{}), do: :ok
@@ -33,6 +33,7 @@ defmodule Sentry.Integrations.Oban.ErrorReporterTest do
3333
assert event.tags.oban_queue == "default"
3434
assert event.tags.oban_state == "available"
3535
assert event.tags.oban_worker == "Sentry.Integrations.Oban.ErrorReporterTest.MyWorker"
36+
assert event.tags.oban_tags == "tag1,tag2"
3637
assert %{job: %Oban.Job{}} = event.integration_meta.oban
3738

3839
assert event.fingerprint == [@worker_as_string, "{{ default }}"]
@@ -64,6 +65,7 @@ defmodule Sentry.Integrations.Oban.ErrorReporterTest do
6465
assert event.tags.oban_queue == "default"
6566
assert event.tags.oban_state == "available"
6667
assert event.tags.oban_worker == "Sentry.Integrations.Oban.ErrorReporterTest.MyWorker"
68+
assert event.tags.oban_tags == "tag1,tag2"
6769
assert %{job: %Oban.Job{}} = event.integration_meta.oban
6870

6971
assert event.fingerprint == [@worker_as_string, "{{ default }}"]
@@ -154,11 +156,29 @@ defmodule Sentry.Integrations.Oban.ErrorReporterTest do
154156
assert Sentry.Test.pop_sentry_reports() == []
155157
end
156158
end
159+
160+
test "includes oban_tags when config option is enabled" do
161+
Sentry.Test.start_collecting()
162+
163+
emit_telemetry_for_failed_job(:error, %RuntimeError{message: "oops"}, [], oban_tags: true)
164+
165+
assert [event] = Sentry.Test.pop_sentry_reports()
166+
assert event.tags.oban_tags == "tag1,tag2"
167+
end
168+
169+
test "excludes oban_tags when config option is disabled" do
170+
Sentry.Test.start_collecting()
171+
172+
emit_telemetry_for_failed_job(:error, %RuntimeError{message: "oops"}, [], oban_tags: false)
173+
174+
assert [event] = Sentry.Test.pop_sentry_reports()
175+
assert is_nil(Map.get(event.tags, :oban_tags))
176+
end
157177
end
158178

159179
## Helpers
160180

161-
defp emit_telemetry_for_failed_job(kind, reason, stacktrace) do
181+
defp emit_telemetry_for_failed_job(kind, reason, stacktrace, config \\ []) do
162182
job =
163183
%{"id" => "123", "entity" => "user", "type" => "delete"}
164184
|> MyWorker.new()
@@ -169,7 +189,7 @@ defmodule Sentry.Integrations.Oban.ErrorReporterTest do
169189
[:oban, :job, :exception],
170190
%{},
171191
%{job: job, kind: kind, reason: reason, stacktrace: stacktrace},
172-
:no_config
192+
config
173193
)
174194

175195
job

0 commit comments

Comments
 (0)