Packages
new_relic_agent
1.16.6
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/metric/harvester.ex
defmodule NewRelic.Harvest.Collector.Metric.Harvester do
use GenServer
@moduledoc false
alias NewRelic.Harvest.Collector
def start_link(_) do
GenServer.start_link(__MODULE__, [])
end
def init(_) do
{:ok,
%{
start_time: System.system_time(),
start_time_mono: System.monotonic_time(),
end_time_mono: nil,
metrics: []
}}
end
# API
def report_metric(identifier, values),
do:
Collector.Metric.HarvestCycle
|> Collector.HarvestCycle.current_harvester()
|> GenServer.cast({:report, Collector.MetricData.transform(identifier, values)})
def gather_harvest,
do:
Collector.Metric.HarvestCycle
|> Collector.HarvestCycle.current_harvester()
|> GenServer.call(:gather_harvest)
# Server
def handle_cast(_late_msg, :completed), do: {:noreply, :completed}
def handle_cast({:report, metrics}, state) when is_list(metrics) do
{:noreply, %{state | metrics: metrics ++ state.metrics}}
end
def handle_cast({:report, metric}, state) do
{:noreply, %{state | metrics: [metric | state.metrics]}}
end
def handle_call(_late_msg, _from, :completed), do: {:reply, :completed, :completed}
def handle_call(:send_harvest, _from, state) do
send_harvest(%{state | end_time_mono: System.monotonic_time()})
{:reply, :ok, :completed}
end
def handle_call(:gather_harvest, _from, state) do
{:reply, build_metric_data(state.metrics), state}
end
def send_harvest(state) do
metric_data = build_metric_data(state.metrics)
Collector.Protocol.metric_data([
Collector.AgentRun.agent_run_id(),
System.convert_time_unit(state.start_time, :native, :second),
System.convert_time_unit(
state.start_time + (state.end_time_mono - state.start_time_mono),
:native,
:second
),
metric_data
])
log_harvest(length(metric_data))
end
def log_harvest(harvest_size) do
NewRelic.report_metric({:supportability, "MetricData"}, harvest_size: harvest_size)
NewRelic.log(:debug, "Completed Metric harvest - size: #{harvest_size}")
end
defp build_metric_data(metrics),
do:
metrics
|> Enum.group_by(&metric_ident/1)
|> Enum.map(&aggregate/1)
|> Enum.map(&encode/1)
def metric_ident(metric), do: {metric.name, metric.scope}
def aggregate({_ident, metrics}), do: NewRelic.Metric.reduce(metrics)
def encode(%NewRelic.Metric{name: name, scope: scope} = m),
do: [
%{name: to_string(name), scope: to_string(scope)},
[
m.call_count,
m.total_call_time,
m.total_exclusive_time,
m.min_call_time,
m.max_call_time,
m.sum_of_squares
]
]
end