Current section
Files
Jump to
Current section
Files
lib/bufflog.ex
defmodule BuffLog do
use GenServer
def init([acc_uuid, options]) do
ets = :ets.new(:somelog, [:public])
:erlang.send_after(3000, self(), :tick)
# open FD here if some persistent_term is true
st =
Map.merge(options, %{
ets: ets,
counter: 0,
monitors: [],
last_add: :os.system_time(1000),
name: acc_uuid
})
{:ok, st}
end
def handle_info(:tick, state) do
if state.monitors == [] && :os.system_time(1) > state.last_add + 60 * 60 do
{:stop, :normal, state}
else
:erlang.send_after(30000, self(), :tick)
{:noreply, state}
end
end
def handle_info({:add_line, line, side}, state) do
state = %{state | counter: state.counter + 1, last_add: :os.system_time(1000)}
if state.counter > 5000 do
:ets.delete(state.ets, state.counter - 5000)
end
:ets.insert(state.ets, {state.counter, state.last_add, side, line})
Enum.each(state.monitors, fn {pid, _} ->
send(pid, {:log_notification, state.counter, line})
end)
# write line to FD here if some persistent_term is true
{:noreply, state}
end
def handle_call(:get_lines, caller, state) do
lines = :ets.tab2list(state.ets)
{:reply, lines, state}
end
def handle_info({:DOWN, ref, :process, pid, _}, state) do
state = %{state | monitors: Enum.reject(state.monitors, fn {p, _} -> pid == p end)}
{:noreply, state}
end
def handle_call(:watch, {pid, _} = caller, state) do
ref = Process.monitor(pid)
state = %{state | monitors: [{pid, ref} | state.monitors]}
{:reply, :ok, state}
end
def add_line(log, line, side \\ "note") do
cond do
log == :log_mitm ->
cond do
is_binary(line) -> IO.puts(line)
true -> IO.inspect(line, limit: :infinity)
end
l = Process.whereis(log) ->
# Mitm.Game.send_to_log(side, (if is_binary(line) do line else inspect(line) end), inspect(line))
#
if Process.get(:output_std_io, false) do
if is_binary(line) do
IO.puts(line)
else
IO.inspect(line, limit: :infinity)
end
end
send(l, {:add_line, line, side})
is_pid(log) ->
send(log, {:add_line, line, side})
true ->
# :ok
IO.puts("log process doesn't exists: #{inspect(log)} #{inspect(line)}")
end
end
def get_lines(log) do
GenServer.call(log, :get_lines) |> Enum.sort_by(fn {x, _, _, _} -> x end)
end
def tail(log, num \\ 20) do
name =
if is_binary(log) do
:"log_#{log}"
else
log
end
lines = BuffLog.get_lines(name)
lines = Enum.drop(lines, max(0, Enum.count(lines) - num))
Enum.each(lines, fn line ->
if is_binary(line) do
IO.puts(line)
else
IO.inspect(line, limit: :infinity)
end
end)
end
def watch(log) do
GenServer.call(log, :watch)
end
def watch1() do
receive do
{:log_notification, _, x} when is_binary(x) ->
IO.puts(x)
watch1()
{:log_notification, _, x} ->
IO.inspect(x, limit: :infinity)
watch1()
:exit ->
:ok
msg ->
IO.inspect(msg, limit: :infinity)
end
end
def start_log(acc_uuid, options \\ %{}) do
log_name = :"log_#{acc_uuid}"
Process.put(:bufflog, log_name)
if Process.whereis(log_name) == nil do
GenServer.start(BuffLog, [acc_uuid, options], name: log_name)
end
end
def add(line, side \\ "note") do
line =
case line do
"->" <> _ -> IO.ANSI.color(200) <> line <> IO.ANSI.reset()
"<-" <> _ -> IO.ANSI.light_green() <> line <> IO.ANSI.reset()
_ when is_binary(line) -> IO.ANSI.light_yellow() <> line <> IO.ANSI.reset()
_ -> line
end
add_line(Process.get(:bufflog), line, side)
end
end