Packages
new_relic_agent
1.17.0-rc.4
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