Packages
new_relic_agent
1.26.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/error/reporter.ex
defmodule NewRelic.Error.Reporter do
@moduledoc false
alias NewRelic.Util
alias NewRelic.Harvest.Collector
# Don't report exceptions that result in a 400 level response
def report_error(_, [
{:initial_call, _},
{:pid, _},
{:registered_name, _},
{:error_info, {:exit, {{{%{plug_status: plug_status}, _plug_stack}, _init_call}, _}, _}}
| _
])
when plug_status < 500 do
:ignore
end
# Don't double report exceptions re-raised by PlugCowboy
def report_error(_, [
{:initial_call, {:cowboy_stream_h, :request_process, _}},
{:pid, _},
{:registered_name, _},
{:error_info, {:exit, {_, [{Plug.Cowboy.Handler, :exit_on_error, _, _} | _]}, _}}
| _
]) do
:ignore
end
def report_error(:transaction, report) do
{kind, exception, stacktrace} = parse_error_info(report[:error_info])
process_name = parse_process_name(report[:registered_name], stacktrace)
NewRelic.add_attributes(process: process_name)
NewRelic.Transaction.Reporter.error(%{
kind: kind,
reason: exception,
stack: stacktrace
})
end
def report_error(:process, report) do
{kind, exception, stacktrace} = parse_error_info(report[:error_info])
{exception_type, exception_reason, exception_stacktrace} =
Util.Error.normalize(kind, exception, stacktrace, report[:initial_call])
process_name = parse_process_name(report[:registered_name], stacktrace)
expected = parse_error_expected(exception)
automatic_attributes = NewRelic.Config.automatic_attributes()
Collector.ErrorTrace.Harvester.report_error(%NewRelic.Error.Trace{
timestamp: System.system_time(:millisecond) / 1_000,
error_type: exception_type,
message: exception_reason,
expected: expected,
stack_trace: exception_stacktrace,
transaction_name: "OtherTransaction/Elixir/ElixirProcess//#{process_name}",
user_attributes:
Map.merge(automatic_attributes, %{
process: process_name
})
})
Collector.TransactionErrorEvent.Harvester.report_error(%NewRelic.Error.Event{
timestamp: System.system_time(:millisecond) / 1_000,
error_class: exception_type,
error_message: exception_reason,
expected: expected,
transaction_name: "OtherTransaction/Elixir/ElixirProcess//#{process_name}",
user_attributes:
Map.merge(automatic_attributes, %{
process: process_name,
stacktrace: Enum.join(exception_stacktrace, "\n")
})
})
unless expected do
NewRelic.report_metric({:supportability, :error_event}, error_count: 1)
NewRelic.report_metric(:error, error_count: 1)
end
end
defp parse_process_name([], [{module, _f, _a, _} | _]), do: inspect(module)
defp parse_process_name([], _stacktrace), do: "UnknownProcess"
defp parse_process_name(registered_name, _stacktrace), do: inspect(registered_name)
defguard is_mfa(value) when is_tuple(value) and tuple_size(value) == 3
defp parse_error_info({kind, {{{exception, call}, init_call}, _init_stack}, _proc_stack})
when is_mfa(call) and is_mfa(init_call) do
{kind, exception, [parse_call(call), parse_call(init_call)]}
end
defp parse_error_info({kind, {{{exception, stacktrace}, _init_call}, _init_stack}, _proc_stack}) do
{kind, exception, stacktrace}
end
defp parse_error_info({kind, {exception, stacktrace}, _stack}) when is_list(stacktrace) do
{kind, exception, stacktrace}
end
defp parse_error_info({kind, exception, stacktrace}) do
{kind, exception, stacktrace}
end
defp parse_call({m, f, a}), do: {m, f, length(a), []}
defp parse_error_expected(%{expected: true}), do: true
defp parse_error_expected(_), do: false
end