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
Current section
Files
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