Packages

appsignal

1.9.2
2.17.4 2.17.3 2.17.2 2.17.1 2.17.0 2.16.0 2.15.11 2.15.10 2.15.9 2.15.8 2.15.7 2.15.6 2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.1 2.14.0 2.13.4 2.13.3 2.13.2 2.13.1 2.13.0 2.12.3 2.12.2 2.12.1 2.12.0 2.11.0 2.10.2 2.10.1 2.10.0 2.9.2 2.9.1 2.9.0 2.8.3 2.8.2 2.8.1 2.8.0 2.7.13 2.7.12 2.7.11 2.7.10 2.7.9 2.7.8 2.7.7 2.7.6 2.7.5 2.7.4 2.7.3 2.7.2 2.7.1 2.7.0 2.7.0-beta.1 2.6.1 2.6.0 2.5.3 2.5.2 2.5.1 2.5.0 2.4.3 2.4.2 2.4.1 2.4.0 2.3.1 2.3.0 2.2.19 2.2.18 2.2.17 2.2.16 2.2.15 2.2.14 2.2.13 2.2.12 retired 2.2.11 2.2.10 2.2.9 2.2.8 2.2.7 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 2.2.1 2.2.0 2.1.15 2.1.14 2.1.13 2.1.12 2.1.11 2.1.10 2.1.9 2.1.8 2.1.7 2.1.7-beta.1 2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.1 2.1.0 2.0.8 2.0.7 2.0.6 2.0.6-beta.1 2.0.5 retired 2.0.4 retired 2.0.3 retired 2.0.2 retired 2.0.1 retired 2.0.0 retired 2.0.0-beta.11 2.0.0-beta.10 2.0.0-beta.9 2.0.0-beta.8 2.0.0-beta.7 2.0.0-beta.6 2.0.0-beta.5 2.0.0-beta.4 2.0.0-beta.3 2.0.0-beta.2 2.0.0-beta.1 2.0.0-alpha.7 2.0.0-alpha.6 2.0.0-alpha.5 2.0.0-alpha.4 2.0.0-alpha.3 2.0.0-alpha.2 2.0.0-alpha.1 1.13.5 1.13.4 1.13.3 1.13.2 1.13.1 1.13.0 1.13.0-beta.2 1.13.0-beta.1 1.12.1 1.12.0 1.12.0-beta.3 1.12.0-beta.2 1.12.0-beta.1 1.11.8 1.11.7 1.11.6 1.11.5 1.11.4 1.11.3 1.11.2 1.11.1 1.11.0 1.11.0-beta.1 1.10.13 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.4 1.9.3 1.9.2 1.9.1 1.9.1-beta.1 1.9.0 1.9.0-beta.1 1.9.0-alpha.1 1.8.2 1.8.1 1.8.1-beta.2 1.8.1-beta.1 1.8.0 1.7.2 1.7.1 1.7.0 1.7.0-beta.2 1.7.0-beta.1 1.7.0-alpha.4 1.7.0-alpha.3 1.7.0-alpha.2 1.7.0-alpha.1 1.6.7 1.6.6 1.6.6-beta.2 1.6.6-beta.1 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.6.0-beta.1 1.6.0-alpha.1 1.5.1 1.5.0 1.5.0-beta.2 1.5.0-beta.1 1.4.11-beta.1 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.4.0-alpha.1 1.3.6 1.3.6-beta.1 1.3.5 1.3.4 1.3.4-beta.1 1.3.3 1.3.2 1.3.1 1.3.0 1.3.0-beta.3 1.3.0-beta.2 1.3.0-beta.1 1.2.3 1.2.2 1.2.1 1.2.0 1.1.1 1.1.0 1.0.4 1.0.3 1.0.2 1.0.1 1.0.0 1.0.0-rc.1 0.13.0 0.12.3 0.12.2 0.12.1 0.12.0 0.11.6 0.11.5 0.11.4 0.11.3 0.11.2 0.11.1 0.11.0 0.10.0 0.9.2 0.9.1 0.9.0 0.8.0 0.7.1 0.7.0 0.6.2 0.6.1 0.6.0 0.5.0 0.4.0 0.3.0 0.2.0 0.1.0 0.0.9 0.0.8 0.0.7 0.0.6 0.0.5 0.0.4 0.0.3 0.0.2 0.0.1

Collects error and performance data from your Elixir applications and sends it to AppSignal

Current section

Files

Jump to
appsignal lib appsignal error_handler.ex
Raw

lib/appsignal/error_handler.ex

defmodule Appsignal.ErrorHandler do
@moduledoc """
Error handler which sends all crash reports to the AppSignal backend.
When you add `:appsignal` to your application's dependencies, this
error logger will automatically be installed. All processes that are
supervised, like GenServers, Tasks, Agents, Supervisored will be
monitored for crashes. In the case of a crash, the AppSignal error
handler collects error information and sends it to the backend.
"""
require Logger
alias Appsignal.{Backtrace, Error, TransactionRegistry}
@transaction Application.get_env(
:appsignal,
:appsignal_transaction,
Appsignal.Transaction
)
def init(state) do
{:ok, state}
end
def handle_event(event, state) do
case match_event(event) do
{origin, error, stack, conn} ->
transaction =
unless TransactionRegistry.ignored?(origin) do
@transaction.lookup_or_create_transaction(origin)
end
if transaction != nil do
handle_error(transaction, error, stack, conn)
end
_ ->
:ok
end
{:ok, state}
end
def handle_info(_, state) do
{:ok, state}
end
@spec handle_error(Appsignal.Transaction.t(), any, Exception.stacktrace(), map()) :: :ok
def handle_error(transaction, error, stack, conn) do
{exception, stacktrace} = Error.normalize(error, stack)
do_handle_error(transaction, exception, stacktrace, conn)
end
@spec do_handle_error(Appsignal.Transaction.t(), Exception.t(), list(String.t()), map()) :: :ok
defp do_handle_error(_, %{plug_status: status}, _, _) when status < 500, do: :ok
defp do_handle_error(transaction, exception, stack, conn) do
{reason, message} = Appsignal.Error.metadata(exception)
backtrace = Backtrace.from_stacktrace(stack)
@transaction.set_error(transaction, reason, message, backtrace)
if @transaction.finish(transaction) == :sample do
@transaction.set_request_metadata(transaction, conn)
end
@transaction.complete(transaction)
end
def submit_transaction(transaction, reason, message, stack, metadata, conn \\ nil)
def submit_transaction(transaction, reason, message, stack, metadata, nil) do
@transaction.set_error(transaction, reason, message, stack)
@transaction.set_meta_data(transaction, metadata)
@transaction.finish(transaction)
@transaction.complete(transaction)
Logger.debug(fn ->
"Submitting #{inspect(transaction)}: #{message}"
end)
transaction
end
if Appsignal.plug?() do
def submit_transaction(transaction, reason, message, stack, metadata, conn) do
if conn do
@transaction.set_request_metadata(transaction, conn)
end
submit_transaction(transaction, reason, message, stack, metadata)
end
end
@doc false
@spec match_event(term) :: {pid, term, String.t(), list, %{}} | :nomatch
def match_event({:error_report, _gleader, {origin, :crash_report, [report | _]}})
when is_list(report) do
try do
{_kind, error, stack} = report[:error_info]
{origin, error, stack, %{}}
rescue
exception ->
Logger.warn(fn ->
"""
AppSignal: Failed to match error report: #{Exception.message(exception)}
#{inspect(report[:error_info])}
"""
end)
:nomatch
end
end
def match_event(_event) do
:nomatch
end
@doc false
@deprecated "Use Appsignal.Backtrace.from_stacktrace/1 instead."
def format_stack(stacktrace) do
Backtrace.from_stacktrace(stacktrace)
end
@deprecated "Use Appsignal.Error.metadata/1 instead."
def extract_reason_and_message(any, prefix) do
{exception, _} = Error.normalize(any, [])
{name, message} = Error.metadata(exception)
{name, prefixed(prefix, message)}
end
defp prefixed(nil, msg), do: msg
defp prefixed("", msg), do: msg
defp prefixed(pre, msg), do: pre <> ": " <> msg
@pid_or_ref_regex ~r/\<(\d+\.)+\d+\>/
@deprecated "Use Appsignal.Error.metadata/1 instead."
def normalize_reason(reason) do
Regex.replace(@pid_or_ref_regex, reason, "<...>")
end
end