I’ve been trying to add a custom logger backend to my application using the now-recommended :logger.add_handler/3
function as suggested to me by @LostKobrakai (on Twitter). I’ve ran into an issue with the config
of the handler, which changes between adding the handler and logging the first event. This is my logger:
defmodule Demo.FileLogger do
def adding_handler(config) do
IO.inspect(config, label: "Initial")
{:ok, config}
end
def log(event, config) do
IO.inspect(event, label: "Event")
IO.inspect(config, label: "Config")
:ok
end
end
This is how I add the handler to my application:
# lib/demo/application.ex
@impl true
def start(_type, _args) do
:ok = :logger.add_handler(:file_log, Demo.FileLogger, %{})
# ...
end
Now, the handler logs the following config in the adding_handler/1
callback:
Initial: %{
id: :file_log,
module: Demo.FileLogger,
level: :all,
filters: [],
filter_default: :log,
formatter: {:logger_formatter, %{}}
}
but once the log/2
callback is executed for the first time, config
only contains the following values:
Config: %{
id: :file_log,
module: Demo.FileLogger,
formatter: {:logger_formatter, %{}}
}
Note the missing level
, filters
, and filter_default
fields. This is surprising to me, because in the “old” :gen_event
behaviour for logger backends, you’d set a config
during the init/1
callback and this config would be passed to every callback thereafter, just like in a GenServer. Why is this different in the :logger
backend and what’s the suggested solution to pass on a config map between all callbacks?
I also implemented the changing_config/2
callback to see whether the config is changed somehow, but it never executes between the adding_handler/1
and the log/2
callback.