Current section

Files

Jump to
new_relic_agent lib new_relic harvest telemetry_sdk logs harvester.ex
Raw

lib/new_relic/harvest/telemetry_sdk/logs/harvester.ex

defmodule NewRelic.Harvest.TelemetrySdk.Logs.Harvester do
use GenServer
@moduledoc false
alias NewRelic.Harvest
alias NewRelic.Harvest.TelemetrySdk
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,
sampling: %{
reservoir_size: Application.get_env(:new_relic_agent, :log_reservior_size, 5_000),
logs_seen: 0
},
logs: []
}}
end
# API
def report_log(log),
do:
TelemetrySdk.Logs.HarvestCycle
|> Harvest.HarvestCycle.current_harvester()
|> GenServer.cast({:report, log})
def gather_harvest,
do:
TelemetrySdk.Logs.HarvestCycle
|> Harvest.HarvestCycle.current_harvester()
|> GenServer.call(:gather_harvest)
def handle_cast(_late_msg, :completed), do: {:noreply, :completed}
def handle_cast({:report, log}, state) do
state =
state
|> store_log(log)
|> store_sampling
{:noreply, state}
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_log_data(state.logs), state}
end
# Helpers
def store_log(%{sampling: %{logs_seen: seen, reservoir_size: size}} = state, log)
when seen < size,
do: %{state | logs: [log | state.logs]}
def store_log(state, _log),
do: state
def store_sampling(%{sampling: sampling} = state),
do: %{state | sampling: Map.update!(sampling, :logs_seen, &(&1 + 1))}
def send_harvest(state) do
TelemetrySdk.API.log(build_log_data(state.logs))
log_harvest(length(state.logs))
end
def log_harvest(harvest_size) do
NewRelic.log(:debug, "Completed Log harvest - size: #{harvest_size}")
end
defp build_log_data(logs) do
[
%{
logs: logs,
common: common()
}
]
end
defp common() do
%{
attributes: NewRelic.LogsInContext.linking_metadata()
}
end
end