Packages

appsignal

1.12.0-beta.3
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 plug.ex
Raw

lib/appsignal/plug.ex

if Appsignal.plug?() do
defmodule Appsignal.Plug do
@moduledoc """
Plug handler for Phoenix requests
"""
import Appsignal.Utils
defmacro __using__(_) do
quote do
@transaction Application.get_env(
:appsignal,
:appsignal_transaction,
Appsignal.Transaction
)
def call(conn, opts) do
if Appsignal.Config.active?() do
transaction =
@transaction.generate_id()
|> @transaction.start(:http_request)
|> Appsignal.Plug.try_set_action(conn)
conn = Plug.Conn.put_private(conn, :appsignal_transaction, transaction)
try do
super(conn, opts)
catch
kind, reason -> Appsignal.Plug.handle_error(conn, kind, reason, System.stacktrace())
else
conn -> Appsignal.Plug.finish_with_conn(transaction, conn)
end
else
super(conn, opts)
end
end
defoverridable call: 2
end
end
@transaction Application.get_env(
:appsignal,
:appsignal_transaction,
Appsignal.Transaction
)
def handle_error(_conn, :error, %Plug.Conn.WrapperError{} = original_reason, _stack) do
%{conn: conn, kind: kind, reason: reason, stack: stack} = original_reason
do_handle_error(reason, stack, conn)
:erlang.raise(kind, original_reason, stack)
end
def handle_error(%Plug.Conn{private: %{appsignal_transaction: _}} = conn, kind, reason, stack) do
do_handle_error(reason, stack, conn)
:erlang.raise(kind, reason, stack)
end
def handle_error(_conn, kind, reason, stack) do
:erlang.raise(kind, reason, stack)
end
defp do_handle_error(%{plug_status: status}, _stack, _conn) when status < 500 do
Appsignal.TransactionRegistry.ignore(self())
end
defp do_handle_error(
error,
stack,
%Plug.Conn{private: %{appsignal_transaction: transaction}} = conn
) do
Appsignal.TransactionRegistry.ignore(self())
Appsignal.ErrorHandler.set_error(transaction, error, stack)
finish_with_conn(transaction, conn)
end
defp do_handle_error(_exception, _stack, _conn), do: :ok
def finish_with_conn(transaction, conn) do
if @transaction.finish(transaction) == :sample do
@transaction.set_request_metadata(transaction, conn)
end
@transaction.complete(transaction)
conn
end
def try_set_action(transaction, conn) do
action = Appsignal.Plug.extract_action(conn)
@transaction.set_action(transaction, action)
end
@doc false
@deprecated "Use Appsignal.Error.metadata/1 instead."
def extract_error_metadata(error) do
{exception, _stacktrace} = Appsignal.Error.normalize(error, [])
Appsignal.Error.metadata(exception)
end
@doc false
@deprecated "Use Appsignal.Error.metadata/1 instead."
def extract_error_metadata(error, conn, stack) do
{exception, stacktrace} = Appsignal.Error.normalize(error, stack)
{name, message} = Appsignal.Error.metadata(exception)
{name, message, stacktrace, conn}
end
def extract_action(%Plug.Conn{
private: %{phoenix_action: action, phoenix_controller: controller}
}) do
"#{module_name(controller)}##{action}"
end
def extract_action(%Plug.Conn{private: %{phoenix_endpoint: _}}), do: nil
def extract_action(%Plug.Conn{method: _method, request_path: _path}) do
"unknown"
end
def extract_sample_data(
%Plug.Conn{
params: params,
host: host,
method: method,
request_path: request_path,
port: port
} = conn
) do
%{
"params" => Appsignal.Utils.MapFilter.filter_parameters(params),
"environment" =>
%{
"host" => host,
"method" => method,
"request_path" => request_path,
"port" => port,
"request_uri" => url(conn)
}
|> Map.merge(extract_request_headers(conn))
}
end
def extract_request_headers(%Plug.Conn{req_headers: req_headers}) do
for {key, value} <- req_headers,
key in Appsignal.Config.request_headers() do
{"req_headers.#{key}", value}
end
|> Enum.into(%{})
end
def extract_meta_data(%Plug.Conn{method: method, request_path: path, status: status} = conn) do
request_id =
conn
|> Plug.Conn.get_resp_header("x-request-id")
|> List.first()
%{
"method" => method,
"path" => path,
"request_id" => request_id,
"http_status_code" => status
}
end
defp url(%Plug.Conn{scheme: scheme, host: host, port: port, request_path: request_path}) do
"#{scheme}://#{host}:#{port}#{request_path}"
end
end
end