Packages
new_relic_agent
1.22.3
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/harvest/collector/agent_run.ex
defmodule NewRelic.Harvest.Collector.AgentRun do
use GenServer
# This GenServer is responsible for connecting to the collector
# and holding onto the Agent Run connect response in an ETS table
@moduledoc false
alias NewRelic.Harvest.Collector
def start_link(_) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(:ok) do
NewRelic.sample_process()
:ets.new(__MODULE__, [:named_table, :public, :set])
if NewRelic.Config.enabled?() do
{:ok, %{status: :not_connected}, {:continue, :preconnect}}
else
{:ok, %{status: :not_connected}}
end
end
def ensure_initialized do
GenServer.call(__MODULE__, :ping)
end
def agent_run_id, do: get(:agent_run_id)
def entity_guid, do: get(:entity_guid)
def trusted_account_key, do: get(:trusted_account_key)
def account_id, do: get(:account_id)
def primary_application_id, do: get(:primary_application_id)
def apdex_t, do: get(:apdex_t)
def request_headers, do: get(:request_headers)
def reconnect, do: send(__MODULE__, :reconnect)
def handle_continue(:preconnect, _state) do
case Collector.Protocol.preconnect() do
{:ok, %{"redirect_host" => redirect_host}} ->
Application.put_env(:new_relic_agent, :collector_instance_host, redirect_host)
{:noreply, %{status: :preconnected}, {:continue, :connect}}
_error ->
{:noreply, %{status: :error_during_preconnect}}
end
end
def handle_continue(:connect, _state) do
status = connect()
{:noreply, %{status: status}, {:continue, :complete_boot}}
end
def handle_continue(:complete_boot, %{status: :connected} = state) do
NewRelic.EnabledSupervisorManager.start_child()
{:noreply, state}
end
def handle_continue(:complete_boot, state) do
{:noreply, state}
end
def handle_info(:reconnect, _state) do
status = connect()
{:noreply, %{status: status}}
end
def handle_call(:ping, _from, state) do
{:reply, true, state}
end
defp connect() do
Collector.Connect.payload()
|> Collector.Protocol.connect()
|> store_agent_run()
end
def get(key),
do: :persistent_term.get(:nr_agent_run, %{})[key]
defp store_agent_run({:ok, %{"agent_run_id" => _} = connect_response}) do
:persistent_term.put(:nr_entity_metadata, %{
hostname: NewRelic.Util.hostname(),
"entity.type": "SERVICE",
"entity.guid": connect_response["entity_guid"],
"entity.name": NewRelic.Config.app_name() |> List.first()
})
:persistent_term.put(:nr_agent_run, %{
agent_run_id: connect_response["agent_run_id"],
entity_guid: connect_response["entity_guid"],
trusted_account_key: connect_response["trusted_account_key"],
account_id: connect_response["account_id"],
primary_application_id: connect_response["primary_application_id"],
apdex_t: connect_response["apdex_t"],
request_headers: connect_response["request_headers_map"] |> Map.to_list()
})
store(:sampling_target, connect_response["sampling_target"])
store(:sampling_target_period, connect_response["sampling_target_period_in_seconds"] * 1000)
connect_response["data_methods"]
event_harvest = connect_response["event_harvest_config"]
harvest_limits = event_harvest["harvest_limits"]
if harvest_limits["analytic_event_data"] do
store(:transaction_event_reservoir_size, harvest_limits["analytic_event_data"])
store(:transaction_event_harvest_cycle, event_harvest["report_period_ms"])
else
analytic_event = connect_response["data_methods"]["analytic_event_data"]
store(:transaction_event_reservoir_size, analytic_event["max_samples_stored"])
store(:transaction_event_harvest_cycle, analytic_event["report_period_in_seconds"] * 1000)
end
if harvest_limits["custom_event_data"] do
store(:custom_event_reservoir_size, harvest_limits["custom_event_data"])
store(:custom_event_harvest_cycle, event_harvest["report_period_ms"])
else
custom_event = connect_response["data_methods"]["custom_event_data"]
store(:custom_event_reservoir_size, custom_event["max_samples_stored"])
store(:custom_event_harvest_cycle, custom_event["report_period_in_seconds"] * 1000)
end
if harvest_limits["error_event_data"] do
store(:error_event_reservoir_size, harvest_limits["error_event_data"])
store(:error_event_harvest_cycle, event_harvest["report_period_ms"])
else
error_event = connect_response["data_methods"]["error_event_data"]
store(:error_event_reservoir_size, error_event["max_samples_stored"])
store(:error_event_harvest_cycle, error_event["report_period_in_seconds"] * 1000)
end
if harvest_limits["span_event_data"] do
store(:span_event_reservoir_size, harvest_limits["span_event_data"])
store(:span_event_harvest_cycle, event_harvest["report_period_ms"])
else
span_event = connect_response["data_methods"]["span_event_data"]
store(:span_event_reservoir_size, span_event["max_samples_stored"])
store(:span_event_harvest_cycle, span_event["report_period_in_seconds"] * 1000)
end
store(:data_report_period, connect_response["data_report_period"] * 1000)
:connected
end
defp store_agent_run(_bad_connect_response) do
:bad_connect_response
end
@empty_entity_metadata %{
"entity.type": "SERVICE",
"entity.guid": nil,
"entity.name": nil
}
def entity_metadata() do
:persistent_term.get(:nr_entity_metadata, @empty_entity_metadata)
end
defp store(key, value) do
:ets.insert(__MODULE__, {key, value})
end
def lookup(key, default \\ nil) do
Application.get_env(:new_relic_agent, key) ||
case :ets.lookup(__MODULE__, key) do
[{^key, value}] -> value
[] -> default
end
end
end