Packages
new_relic_agent
1.33.0
1.40.3
1.40.2
1.40.1
1.40.0
1.39.0
1.38.0
1.37.0
1.36.0
1.35.0
1.34.0
1.33.0
1.32.0
1.31.1
1.31.0
1.30.0
1.29.0
1.28.0
1.27.8
1.27.7
1.27.6
1.27.5
1.27.4
1.27.3
1.27.2
1.27.1
1.27.0
1.26.0
1.25.3
1.25.2
1.25.1
1.25.0
1.24.5
1.24.4
1.24.3
1.24.2
1.24.1
1.24.0
1.24.0-rc.10
1.24.0-rc.9
1.24.0-rc.8
1.24.0-rc.7
1.23.6
1.23.5
1.23.4
1.23.3
1.23.2
1.23.1
1.23.0
1.23.0-rc.6
1.23.0-rc.5
1.23.0-rc.4
1.23.0-rc.3
1.23.0-rc.2
1.23.0-rc.1
1.22.6
1.22.5
1.22.4
1.22.3
1.22.2
1.22.1
1.22.0
1.21.2
1.21.1
1.21.0
1.21.0-rc.3
1.21.0-rc.1
1.20.0
1.20.0-rc.1
1.19.7
1.19.6
1.19.5
1.19.4
1.19.3
1.19.2
1.19.1
1.19.0
1.18.5
1.18.4
1.18.3
1.18.2
1.18.1
1.18.0
1.18.0-rc.5
1.18.0-rc.4
1.18.0-rc.2
1.18.0-rc.1
1.17.1
1.17.0
1.17.0-rc.4
1.17.0-rc.3
1.17.0-rc.2
1.17.0-rc.1
1.17.0-rc.0
1.16.7
1.16.6
1.16.5
1.16.4
1.16.3
1.16.2
1.16.1
1.16.0
1.16.0-rc.2
1.16.0-rc.1
1.16.0-rc.0
1.15.0
1.15.0-rc.3
1.15.0-rc.2
1.15.0-rc.1
1.14.0
1.13.1
1.13.0
1.12.0
1.11.0
1.10.2
1.10.1
1.10.0
1.9.12
1.9.11
1.9.10
1.9.9
1.9.8
1.9.7
1.9.6
1.9.5
1.9.4
1.9.3
1.9.2
1.9.1
1.9.0
1.8.0
1.7.0
1.6.2
1.6.1
1.6.0
1.5.0
1.4.0
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.0
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
New Relic's Open-Source Elixir Agent
Current section
Files
Jump to
Current section
Files
lib/new_relic/telemetry/oban.ex
defmodule NewRelic.Telemetry.Oban do
use GenServer
@moduledoc """
Provides `Oban` instrumentation via `telemetry`.
Oban jobs are auto-discovered and instrumented.
We automatically gather:
* Transaction metrics and events
* Transaction Traces
* Distributed Traces
You can opt-out of this instrumentation with `:oban_instrumentation_enabled` via configuration.
See `NewRelic.Config` for details.
"""
alias NewRelic.Transaction
@doc false
def start_link(_) do
config = %{
enabled?: NewRelic.Config.feature?(:oban_instrumentation),
handler_id: {:new_relic, :oban}
}
GenServer.start_link(__MODULE__, config, name: __MODULE__)
end
@oban_start [:oban, :job, :start]
@oban_stop [:oban, :job, :stop]
@oban_exception [:oban, :job, :exception]
@oban_events [
@oban_start,
@oban_stop,
@oban_exception
]
@doc false
def init(%{enabled?: false}), do: :ignore
def init(%{enabled?: true} = config) do
:telemetry.attach_many(
config.handler_id,
@oban_events,
&__MODULE__.handle_event/4,
config
)
Process.flag(:trap_exit, true)
{:ok, config}
end
@doc false
def terminate(_reason, %{handler_id: handler_id}) do
:telemetry.detach(handler_id)
end
@doc false
def handle_event(
@oban_start,
%{system_time: start_time},
meta,
_config
) do
Transaction.Reporter.start_transaction(:other)
NewRelic.DistributedTrace.start(:other)
add_start_attrs(meta, start_time)
end
def handle_event(
@oban_stop,
%{duration: duration} = meas,
meta,
_config
) do
add_stop_attrs(meas, meta, duration)
Transaction.Reporter.stop_transaction(:other)
end
def handle_event(
@oban_exception,
%{duration: duration} = meas,
%{kind: kind} = meta,
_config
) do
add_stop_attrs(meas, meta, duration)
{reason, stack} = NewRelic.Util.Telemetry.reason_and_stack(meta)
Transaction.Reporter.fail(%{kind: kind, reason: reason, stack: stack})
Transaction.Reporter.stop_transaction(:other)
end
def handle_event(_event, _measurements, _meta, _config) do
:ignore
end
defp add_start_attrs(meta, start_time) do
[
pid: inspect(self()),
start_time: start_time,
other_transaction_name: "Oban/#{meta.queue}/#{meta.worker}/perform",
"oban.worker": meta.worker,
"oban.queue": meta.queue,
"oban.job.args": meta.job.args,
"oban.job.tags": meta.job.tags |> Enum.join(","),
"oban.job.attempt": meta.job.attempt,
"oban.job.attempted_by": meta.job.attempted_by |> Enum.join("."),
"oban.job.max_attempts": meta.job.max_attempts,
"oban.job.priority": meta.job.priority
]
|> NewRelic.add_attributes()
end
@kb 1024
defp add_stop_attrs(meas, meta, duration) do
info = Process.info(self(), [:memory, :reductions])
[
duration: duration,
memory_kb: info[:memory] / @kb,
reductions: info[:reductions],
"oban.job.result": meta.state,
"oban.job.queue_time": System.convert_time_unit(meas.queue_time, :native, :millisecond)
]
|> NewRelic.add_attributes()
end
end