Current section

Files

Jump to
new_relic_agent lib new_relic distributed_trace plug.ex
Raw

lib/new_relic/distributed_trace/plug.ex

defmodule NewRelic.DistributedTrace.Plug do
@behaviour Plug
import Plug.Conn
require Logger
# Plug that accepts an incoming DT payload and tracks the DT context
@moduledoc false
alias NewRelic.DistributedTrace
alias NewRelic.DistributedTrace.Context
alias NewRelic.Harvest.Collector.AgentRun
@impl Plug
def init(opts), do: opts
@impl Plug
def call(%{private: %{newrelic_dt_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: trace(conn, NewRelic.Config.enabled?())
def trace(conn, false), do: conn
def trace(conn, true) do
determine_context(conn)
|> DistributedTrace.track_transaction(transport_type: "HTTP")
conn
|> put_private(:newrelic_dt_instrumented, true)
|> register_before_send(&before_send/1)
end
defp before_send(conn) do
DistributedTrace.cleanup_context()
conn
end
defp determine_context(conn) do
with %Context{} = context <- DistributedTrace.accept_distributed_trace_payload(:http, conn),
%Context{} = context <- restrict_access(context) do
context
else
_ -> DistributedTrace.generate_new_context()
end
end
def restrict_access(context) do
if (context.trust_key || context.account_id) == AgentRun.trusted_account_key() do
context
else
:restricted
end
end
end