Packages
new_relic_agent
1.39.0
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_reservoir_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
defp store_log(%{sampling: %{logs_seen: seen, reservoir_size: size}} = state, log)
when seen < size,
do: %{state | logs: [log | state.logs]}
defp store_log(state, _log),
do: state
defp store_sampling(%{sampling: sampling} = state),
do: %{state | sampling: Map.update!(sampling, :logs_seen, &(&1 + 1))}
defp 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
defp log_harvest(harvest_size, logs_seen, reservoir_size) do
NewRelic.log(
:debug,
"Completed TelemetrySdk.Logs 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