Packages
new_relic_agent
1.40.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/logger.ex
defmodule NewRelic.Logger do
use GenServer
require Logger
# Log Agent events to the configured output device
# - "tmp/new_relic.log" (Default)
# - :memory
# - :stdio
# - {:file, filename}
@moduledoc false
def start_link(_) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(:ok) do
NewRelic.sample_process()
logger = initial_logger()
{:ok, io_device} = device(logger)
{:ok, %{io_device: io_device, logger: logger}}
end
# API
@levels [:debug, :info, :warning, :error]
def log(level, message) when level in @levels do
GenServer.cast(__MODULE__, {:log, level, message})
end
# Server
def handle_cast({:log, level, message}, %{io_device: Logger} = state) do
elixir_logger(level, "new_relic_agent - " <> message)
{:noreply, state}
end
def handle_cast({:log, level, message}, %{io_device: io_device} = state) do
IO.write(io_device, formatted(level, message))
{:noreply, state}
end
def handle_call(:flush, _from, %{logger: :memory, io_device: io_device} = state) do
{:reply, StringIO.flush(io_device), state}
end
def handle_call(:flush, _from, state) do
{:reply, "", state}
end
def handle_call({:logger, logger}, _from, old_state) do
{:ok, io_device} = device(logger)
{:reply, old_state, %{io_device: io_device, logger: logger}}
end
def handle_call({:replace, logger}, _from, _old_state) do
{:reply, :ok, logger}
end
# Helpers
def initial_logger do
case NewRelic.Config.logger() do
nil -> :logger
"file" -> {:file, "tmp/new_relic.log"}
"stdout" -> :stdio
"memory" -> :memory
"Logger" -> :logger
log_file_path -> {:file, log_file_path}
end
end
defp device(:stdio), do: {:ok, :stdio}
defp device(:memory), do: StringIO.open("")
defp device(:logger), do: {:ok, Logger}
defp device({:file, logfile}) do
log(:info, "Log File: #{Path.absname(logfile)}")
logfile |> Path.dirname() |> File.mkdir_p!()
{:ok, _file} = File.open(logfile, [:append, :utf8])
end
defp elixir_logger(:debug, message), do: Logger.debug(message)
defp elixir_logger(:info, message), do: Logger.info(message)
defp elixir_logger(:warning, message), do: Logger.warning(message)
defp elixir_logger(:error, message), do: Logger.error(message)
@sep " - "
defp formatted(level, message), do: [formatted(level), @sep, timestamp(), @sep, message, "\n"]
defp formatted(:debug), do: "[DEBUG]"
defp formatted(:info), do: "[INFO]"
defp formatted(:warning), do: "[WARN]"
defp formatted(:error), do: "[ERROR]"
defp timestamp do
:calendar.local_time()
|> NaiveDateTime.from_erl!()
|> NaiveDateTime.to_string()
end
end