Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace error_logger handler with logger handler #84

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/shoehorn/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule Shoehorn.Application do
def start(_type, _args) do
if using_shoehorn?() do
opts = Application.get_all_env(:shoehorn)
:error_logger.add_report_handler(Shoehorn.ReportHandler, opts)
:logger.add_handler(:shoehorn, Shoehorn.ReportHandler, %{config: opts})
end

opts = [strategy: :one_for_one, name: Shoehorn.Supervisor]
Expand Down
95 changes: 54 additions & 41 deletions lib/shoehorn/report_handler.ex
Original file line number Diff line number Diff line change
@@ -1,76 +1,89 @@
defmodule Shoehorn.ReportHandler do
@moduledoc false

@behaviour :gen_event
use GenServer

alias Shoehorn.Handler

@shutdown_timer 30_000

@impl :gen_event
def init(opts) do
shutdown_timer = opts[:shutdown_timer] || @shutdown_timer
@doc false
def adding_handler(%{config: opts} = config) do
{:ok, pid} = GenServer.start_link(__MODULE__, opts)
{:ok, %{config | config: %{pid: pid}}}
end

{:ok,
%{
handler: Handler.init(opts),
shutdown_timer: shutdown_timer
}}
@doc false
def removing_handler(%{config: %{pid: pid}}) do
GenServer.stop(pid)
end

@impl :gen_event
def handle_call(_, s) do
{:ok, :ok, s}
@doc false
def log(
%{msg: {:report, %{label: {:application_controller, :progress}, report: report}}},
config
) do
application = Keyword.get(report, :application)
GenServer.cast(config.config.pid, {:start, application})
end

@impl :gen_event
def handle_event({:info_report, _pid, {_, :std_info, info}}, s) when is_list(info) do
case Keyword.get(info, :exited) do
nil ->
{:ok, s}
def log(%{msg: {:report, %{label: {:application_controller, :exit}, report: report}}}, config) do
application = Keyword.get(report, :application)
reason = Keyword.get(report, :exited)
GenServer.cast(config.config.pid, {:exit, application, reason})
end

def log(_log, _config), do: :ok

reason ->
app = Keyword.get(info, :application)
{:ok, exited(app, reason, s)}
end
@impl GenServer
def init(opts) do
shutdown_timer = opts[:shutdown_timer] || @shutdown_timer
{:ok, %{handler: Handler.init(opts), shutdown_timer: shutdown_timer}}
end

@impl GenServer
def handle_call(_, _, state) do
{:reply, :ok, state}
end

def handle_event({:info_report, _pid, {_, :progress, info}}, s) when is_list(info) do
case Keyword.get(info, :started_at) do
nil ->
{:ok, s}
@impl GenServer
def handle_cast({:start, application}, state) do
{:noreply, started(application, state)}
end

def handle_cast({:exit, application, reason}, state) do
{:noreply, exited(application, reason, state)}
end

_node ->
app = Keyword.get(info, :application)
{:ok, started(app, s)}
end
def handle_cast(_, state) do
{:noreply, state}
end

def handle_event(_event, s) do
{:ok, s}
@impl GenServer
def handle_info(_, state) do
{:noreply, state}
end

@impl :gen_event
def terminate(_args, _s) do
@impl GenServer
def terminate(_reason, _state) do
:ok
end

defp exited(app, reason, s) do
{:ok, shutdown_timer_ref} = :timer.apply_after(s.shutdown_timer, :erlang, :halt, [])
defp exited(app, reason, state) do
{:ok, shutdown_timer_ref} = :timer.apply_after(state.shutdown_timer, :erlang, :halt, [])

return =
:application_exited
|> Handler.invoke(app, reason, s.handler)
|> react(s)
|> Handler.invoke(app, reason, state.handler)
|> react(state)

_ = :timer.cancel(shutdown_timer_ref)
return
end

defp started(app, s) do
defp started(app, state) do
:application_started
|> Handler.invoke(app, s.handler)
|> react(s)
|> Handler.invoke(app, state.handler)
|> react(state)
end

defp react({:halt, _}, _), do: :erlang.halt()
Expand Down