Packages
new_relic_agent
1.22.5
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/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), state.sampling.logs_seen, state.sampling.reservoir_size)
end
def log_harvest(harvest_size, logs_seen, reservoir_size) do
NewRelic.log(
:debug,
"Completed Log harvest - " <>
"size: #{harvest_size}, seen: #{logs_seen}, max: #{reservoir_size}"
)
end
defp build_log_data(logs) do
[
%{
logs: logs,
common: common()
}
]
end
defp common() do
%{
attributes: NewRelic.LogsInContext.linking_metadata()
}
end
end