Packages
new_relic_agent
1.17.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/transaction/plug.ex
defmodule NewRelic.Transaction.Plug do
@behaviour Plug
import Plug.Conn
require Logger
# This Plug wires up Transaction reporting
# - `on_call` is triggered at the beginning of the request
# - `before_send` is triggered at the end, and reports the data to the Transaction.Reporter
@moduledoc false
alias NewRelic.Transaction
alias NewRelic.Util
@impl Plug
def init(opts), do: opts
@impl Plug
def call(%{private: %{newrelic_tx_instrumented: true}} = conn, _opts) do
Logger.warn(
"You have instrumented twice in the same plug! Please `use NewRelic.Transaction` only once."
)
conn
end
def call(conn, _opts) do
conn
|> on_call
|> put_private(:newrelic_tx_instrumented, true)
|> register_before_send(&before_send/1)
end
defp on_call(conn) do
Transaction.Reporter.start()
add_start_attrs(conn)
maybe_report_queueing(conn)
conn
end
defp before_send(conn) do
add_stop_attrs(conn)
Transaction.Reporter.complete(self(), :async)
conn
end
def add_start_attrs(conn) do
[
host: conn.host,
path: conn.request_path,
remote_ip: conn.remote_ip |> :inet_parse.ntoa() |> to_string(),
referer: get_req_header(conn, "referer") |> List.first(),
user_agent: get_req_header(conn, "user-agent") |> List.first(),
content_type: get_req_header(conn, "content-type") |> List.first(),
request_method: conn.method
]
|> NewRelic.add_attributes()
end
@kb 1024
def add_stop_attrs(conn) do
info = Process.info(self(), [:memory, :reductions])
[
plug_name: plug_name(conn),
status: conn.status,
memory_kb: info[:memory] / @kb,
reductions: info[:reductions]
]
|> NewRelic.add_attributes()
end
def plug_name(conn),
do:
"/Plug/#{conn.method}/#{match_path(conn)}"
|> String.replace("/*glob", "")
|> String.replace("/*_path", "")
def match_path(conn) do
case conn.private[:plug_route] do
{match_path, _fun} -> match_path
_ -> nil
end
end
@request_start_header "x-request-start"
def maybe_report_queueing(conn) do
with [request_start | _] <- get_req_header(conn, @request_start_header),
{:ok, request_start_s} <- Util.RequestStart.parse(request_start) do
NewRelic.add_attributes(request_start_s: request_start_s)
else
_ -> :ignore
end
end
end