Packages
appsignal
1.10.11
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
"""
defmacro __using__(_) do
quote do
@transaction Application.get_env(
:appsignal,
:appsignal_transaction,
Appsignal.Transaction
)
def call(conn, opts) 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
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(conn, kind, reason, stack) do
do_handle_error(reason, stack, conn)
:erlang.raise(kind, reason, stack)
end
defp do_handle_error(
error,
stack,
%Plug.Conn{private: %{appsignal_transaction: transaction}} = conn
) do
Appsignal.ErrorHandler.handle_error(transaction, error, stack, conn)
Appsignal.TransactionRegistry.ignore(self())
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
:ok = @transaction.complete(transaction)
conn
end
def try_set_action(transaction, conn) do
case Appsignal.Plug.extract_action(conn) do
nil -> transaction
action -> @transaction.set_action(transaction, action)
end
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
merge_action_and_controller(action, controller)
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 merge_action_and_controller(action, controller) when is_atom(controller) do
merge_action_and_controller(
action,
controller |> Atom.to_string() |> String.trim_leading("Elixir.")
)
end
defp merge_action_and_controller(action, controller) do
"#{controller}##{action}"
end
defp url(%Plug.Conn{scheme: scheme, host: host, port: port, request_path: request_path}) do
"#{scheme}://#{host}:#{port}#{request_path}"
end
end
end