Packages
new_relic_agent
1.30.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/metadata_reporter.ex
defmodule NewRelic.Error.MetadataReporter do
@moduledoc false
alias NewRelic.Util
alias NewRelic.Harvest.Collector
import NewRelic.ConditionalCompile
# Before elixir 1.15, ignore terminating errors so they don't get reported twice
before_elixir_version("1.15.0", def(report_error(_, {{_, :terminating}, _}), do: nil))
def report_error(:transaction, {_cause, metadata}) do
kind = :error
{exception, stacktrace} = metadata.reason
process_name = parse_process_name(metadata[:registered_name], stacktrace)
NewRelic.add_attributes(process: process_name)
NewRelic.Transaction.Reporter.error(%{
kind: kind,
reason: exception,
stack: stacktrace
})
end
def report_error(:process, {_cause, metadata}) do
{exception_type, reason, stacktrace, expected} = parse_reason(metadata.reason)
process_name = parse_process_name(metadata[:registered_name], stacktrace)
automatic_attributes = NewRelic.Config.automatic_attributes()
formatted_stacktrace = Util.Error.format_stacktrace(stacktrace, nil)
Collector.ErrorTrace.Harvester.report_error(%NewRelic.Error.Trace{
timestamp: System.system_time(:millisecond) / 1_000,
error_type: exception_type,
message: reason,
expected: expected,
stack_trace: formatted_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: reason,
expected: expected,
transaction_name: "OtherTransaction/Elixir/ElixirProcess//#{process_name}",
user_attributes:
Map.merge(automatic_attributes, %{
process: process_name,
stacktrace: Enum.join(formatted_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_reason({%type{message: message} = exception, stacktrace}) do
expected = parse_error_expected(exception)
type = inspect(type)
reason = "(#{type}) #{message}"
{type, reason, stacktrace, expected}
end
defp parse_reason({exception, stacktrace}) do
exception = Exception.normalize(:error, exception, stacktrace)
type = inspect(exception.__struct__)
message = Exception.message(exception)
reason = "(#{type}) #{message}"
{type, reason, stacktrace, false}
end
defp parse_process_name([], [{module, _f, _a, _} | _]), do: inspect(module)
defp parse_process_name([], _stacktrace), do: "UnknownProcess"
defp parse_process_name(nil, _stacktrace), do: "UnknownProcess"
defp parse_process_name(registered_name, _stacktrace), do: inspect(registered_name)
defp parse_error_expected(%{expected: true}), do: true
defp parse_error_expected(_), do: false
end