Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changesets/add-support-for-oban-timeout-exceptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
bump: patch
type: add
---

Add support for Oban timeout exceptions
35 changes: 20 additions & 15 deletions lib/appsignal/oban.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,21 @@ defmodule Appsignal.Oban do
def oban_job_start(
_event,
_measurements,
%{
id: id,
args: args,
queue: queue,
worker: worker,
attempt: attempt
} = metadata,
metadata,
_config
) do
do_oban_job_start(metadata)
end

defp do_oban_job_start(
%{
id: id,
args: args,
queue: queue,
worker: worker,
attempt: attempt
} = metadata
) do
span = @tracer.create_span("oban")

span
Expand Down Expand Up @@ -92,6 +98,8 @@ defmodule Appsignal.Oban do
for tag <- Map.get(metadata, :tags, []) do
@span.set_attribute(span, "job_tag_#{tag}", true)
end

span
end

def oban_job_stop(
Expand Down Expand Up @@ -135,8 +143,8 @@ defmodule Appsignal.Oban do
_event,
%{duration: duration},
%{
worker: worker,
queue: queue,
worker: worker,
kind: kind,
error: reason,
stacktrace: stacktrace
Expand All @@ -147,13 +155,10 @@ defmodule Appsignal.Oban do
# If not present, assume the job failed.
state = Map.get(metadata, :state, "failure")

span =
@tracer.current_span()
|> @span.set_attribute("state", to_string(state))

@span.add_error(span, kind, reason, stacktrace)

@tracer.close_span(span)
(@tracer.current_span() || do_oban_job_start(metadata))
|> @span.set_attribute("state", to_string(state))
|> @span.add_error(kind, reason, stacktrace)
|> @tracer.close_span()

increment_job_stop_counter(worker, queue, state)

Expand Down
84 changes: 84 additions & 0 deletions test/appsignal/oban_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,90 @@ defmodule Appsignal.ObanTest do
end
end

describe "oban_job_exception/4, when no span exists" do
setup do
fake_appsignal = start_supervised!(FakeAppsignal)

with_config(%{}, &Appsignal.Oban.attach/0)

execute_job_exception()

[fake_appsignal: fake_appsignal]
end

test "creates a span" do
assert {:ok, [{"oban"}]} = Test.Tracer.get(:create_span)
end

test "closes the span" do
assert {:ok, [{%Span{}}]} = Test.Tracer.get(:close_span)
end

test "sets the span's name" do
assert {:ok, [{%Span{}, "Test.Worker#perform"}]} = Test.Span.get(:set_name)
end

test "sets the span's category" do
assert attribute?("appsignal:category", "job.oban")
end

test "sets job arguments as span params" do
assert {:ok, [{%Span{}, "params", %{foo: "bar"}}]} = Test.Span.get(:set_sample_data)
end

test "sets job attributes as span tags" do
assert attribute?("id", 123)
assert attribute?("worker", "Test.Worker")
assert attribute?("queue", "default")
assert attribute?("attempt", 1)
end

test "sets the state attribute to failure" do
assert attribute?("state", "failure")
end

test "adds the error to the span" do
assert {:ok,
[
{
%Span{},
:error,
%RuntimeError{message: "Exception!"},
[{Appsignal.ObanTest, :execute_job_exception, _, _} | _]
}
]} = Test.Span.get(:add_error)
end

test "increments job stop counter", %{fake_appsignal: fake_appsignal} do
assert [
%{key: _, value: 1, tags: %{state: "failure"}},
%{key: _, value: 1, tags: %{state: "failure", queue: "default"}},
%{key: _, value: 1, tags: %{state: "failure", worker: "Test.Worker"}},
%{
key: _,
value: 1,
tags: %{state: "failure", worker: "Test.Worker", queue: "default"}
}
] = FakeAppsignal.get_counters(fake_appsignal, "oban_job_count")
end

test "adds job duration distribution value", %{fake_appsignal: fake_appsignal} do
assert [
%{key: _, value: 123, tags: %{worker: "Test.Worker"}},
%{
key: _,
value: 123,
tags: %{hostname: "Bobs-MBP.example.com", worker: "Test.Worker"}
},
%{key: _, value: 123, tags: %{state: "failure", worker: "Test.Worker"}}
] = FakeAppsignal.get_distribution_values(fake_appsignal, "oban_job_duration")
end

test "does not detach the handler" do
assert attached?([:oban, :job, :exception])
end
end

describe "oban_job_exception/4, with a :state metadata key (v2.4.0)" do
setup do
fake_appsignal = start_supervised!(FakeAppsignal)
Expand Down
Loading