Current section
Files
Jump to
Current section
Files
lib/exseq.ex
defmodule ExSeq do
@behaviour :gen_event
alias ExSeq.CLEFLevel
defstruct [
:flusher,
:level
]
def start_link(_args) do
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
end
@impl true
def init(_args) do
config = Application.get_env(:logger, __MODULE__, [])
level = Keyword.get(config, :level, :info)
{:ok, flusher} = GenServer.start_link(ExSeq.Flusher, config, name: ExSeq.Flusher)
{:ok, %__MODULE__{flusher: flusher, level: level}}
end
@impl true
def handle_event({_level, gl, {Logger, _, _, _}}, state)
when node(gl) != node() do
{:ok, state}
end
def handle_event({level, _group_leader, {Logger, message, timestamp, metadata}}, state) do
level_order = %{
debug: 0,
info: 1,
warn: 2,
error: 3
}
if level_order[level] >= level_order[state.level] do
create_event(level, message, timestamp, metadata)
|> send_event()
end
{:ok, state}
end
def handle_event(:flush, state) do
IO.puts("Flush event")
{:ok, state}
end
def handle_event(_, state) do
{:ok, state}
end
@impl true
def handle_info(_, state) do
{:ok, state}
end
@impl true
def handle_call({:configure, _options}, state) do
{:ok, :ok, state}
end
defp message_parts(message) do
message = IO.iodata_to_binary(message)
case String.split(message, "\n", parts: 2) do
[message, exception] ->
{message, exception}
[message] ->
{message, nil}
end
end
defp create_event(level, message, timestamp, metadata) do
ts =
case Keyword.get(metadata, :time) do
nil ->
{{year, month, day}, {hour, minute, second, millisecond}} = timestamp
NaiveDateTime.new!(year, month, day, hour, minute, second, millisecond * 1000)
t ->
DateTime.from_unix!(t, :microsecond)
end
metadata =
Keyword.delete(metadata, :time)
|> Keyword.delete(:erl_level)
|> Keyword.delete(:gl)
|> Keyword.delete(:domain)
{message, exception} = message_parts(message)
%ExSeq.CLEFEvent{
timestamp: ts,
message: message,
exception: exception,
level: CLEFLevel.elixir_to_clef_level(level),
properties: metadata
}
end
defp send_event(clef_event) do
GenServer.cast(ExSeq.Flusher, {:receive, clef_event})
end
end