Current section

Files

Jump to
ring_logger lib ring_logger.ex
Raw

lib/ring_logger.ex

defmodule RingLogger do
@behaviour :gen_event
alias RingLogger.{Server, Autoclient}
@typedoc "Option values used by `attach`"
@type client_option ::
{:io, term}
| {:color, term}
| {:metadata, Logger.metadata()}
| {:format, String.t()}
| {:level, Logger.level()}
@type entry :: {module(), Logger.level(), Logger.message(), Logger.Formatter.time(), keyword()}
#
# API
#
@doc """
Attach the current IEx session to the logger. It will start printing log messages.
Options include:
* `:io` - Defaults to `:stdio`
* `:colors` -
* `:metadata` - A KV list of additional metadata
* `:format` - A custom format string
* `:level` - The minimum log level to report.
"""
@spec attach([client_option]) :: :ok
defdelegate attach(opts \\ []), to: Autoclient
@doc """
Detach the current IEx session from the logger.
"""
@spec detach() :: :ok
defdelegate detach(), to: Autoclient
@doc """
Tail the messages in the log.
"""
@spec tail([client_option]) :: [String.t()]
defdelegate tail(opts \\ []), to: Autoclient
@doc """
Reset the index into the log for `tail/1` to the oldest entry.
"""
@spec reset([client_option]) :: [String.t()]
defdelegate reset(opts \\ []), to: Autoclient
@doc """
Helper method for formatting log messages per the current client's
configuration.
"""
@spec format(entry()) :: :ok
defdelegate format(message), to: Autoclient
@doc """
Get all log messages at the specified index and later.
"""
@spec get(non_neg_integer()) :: [entry()]
defdelegate get(index \\ 0), to: Server
@doc """
Update the logger configuration.
Options include:
* `:max_size` - the max number of log messages to store at a time
"""
defdelegate configure(opts), to: Server
#
# Logger backend callbacks
#
def init(__MODULE__) do
{:ok, init({__MODULE__, []})}
end
def init({__MODULE__, opts}) when is_list(opts) do
env = Application.get_env(:logger, __MODULE__, [])
opts = Keyword.merge(env, opts)
Application.put_env(:logger, __MODULE__, opts)
Server.start_link(opts)
{:ok, configure(opts)}
end
def handle_call({:configure, opts}, _state) do
env = Application.get_env(:logger, __MODULE__, [])
opts = Keyword.merge(env, opts)
Application.put_env(:logger, __MODULE__, opts)
{:ok, :ok, configure(opts)}
end
def handle_event(:flush, state) do
{:ok, state}
end
def handle_event({level, _gl, {Logger, _, _, _} = msg}, state) do
Server.log({level, msg})
{:ok, state}
end
def handle_info(_, state) do
{:ok, state}
end
def code_change(_old_vsn, state, _extra) do
{:ok, state}
end
def terminate(_reason, _state) do
Server.stop()
:ok
end
end