Packages
new_relic_agent
1.17.1
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/distributed_trace/new_relic_context.ex
defmodule NewRelic.DistributedTrace.NewRelicContext do
@moduledoc false
alias NewRelic.DistributedTrace.Context
alias NewRelic.Harvest.Collector.AgentRun
def extract(trace_payload) do
decode(trace_payload)
|> restrict_access
end
def generate(context) do
encode(context)
end
def decode(raw_payload) when is_binary(raw_payload) do
with {:ok, json} <- Base.decode64(raw_payload),
{:ok, map} <- Jason.decode(json),
context <- validate(map) do
NewRelic.report_metric(:supportability, [:dt, :accept, :success])
context
else
error ->
NewRelic.report_metric(:supportability, [:dt, :accept, :parse_error])
NewRelic.log(:debug, "Bad DT Payload: #{inspect(error)} #{inspect(raw_payload)}")
:bad_dt_payload
end
end
def restrict_access(:bad_dt_payload), do: :bad_dt_payload
def restrict_access(context) do
if (context.trust_key || context.account_id) == AgentRun.trusted_account_key() do
context
else
:restricted
end
end
@payload_version [0, 1]
def validate(%{
"v" => @payload_version,
"d" =>
%{
"ty" => type,
"ac" => account_id,
"ap" => app_id,
"tr" => trace_id,
"ti" => timestamp
} = data
}) do
%Context{
source: :new_relic,
version: @payload_version,
type: type,
account_id: account_id,
app_id: app_id,
parent_id: data["tx"],
span_guid: data["id"],
trace_id: trace_id,
trust_key: data["tk"],
priority: data["pr"],
sampled: data["sa"],
timestamp: timestamp
}
end
def validate(_invalid), do: :invalid
def encode(context) do
%{
"v" => @payload_version,
"d" =>
%{
"ty" => context.type,
"ac" => context.account_id,
"ap" => context.app_id,
"tx" => context.guid,
"tr" => context.trace_id,
"pr" => context.priority,
"sa" => context.sampled,
"ti" => context.timestamp
}
|> maybe_put(:span_guid, "id", context.sampled, context.span_guid)
|> maybe_put(:trust_key, "tk", context.account_id, context.trust_key)
}
|> Jason.encode!()
|> Base.encode64()
end
def maybe_put(data, :span_guid, key, true = _sampled, guid), do: Map.put(data, key, guid)
def maybe_put(data, :span_guid, _key, false = _sampled, _guid), do: data
def maybe_put(data, :trust_key, _key, account_id, account_id), do: data
def maybe_put(data, :trust_key, _key, _account_id, nil), do: data
def maybe_put(data, :trust_key, key, _account_id, trust_key), do: Map.put(data, key, trust_key)
def parse_int(nil), do: :error
def parse_int(field), do: Integer.parse(field)
end