epsilon
When/how is Logger app started?
I have a legacy Erlang app that is part of Mix umbrella project. The app has eunit tests that are ran using a custom Mix task. When migrating the whole project to Erlang/OTP 23 and Elixir 1.11 I switched logging from lager to Erlang logger (with Elixir backend) and for some reason logger config is not loaded from test.exs when running this custom eunit mix task - logger gets some default configuration with level: :all which is not ideal
.
This is not really specific to this mix task, this is true for any mix task it seems. Maybe the logger app is started before the config is loaded?
For example:
defmodule Mix.Tasks.Hello do
use Mix.Task
require Logger
def run(_) do
IO.inspect(Application.get_all_env(:logger))
# level is info:
# [
# utc_log: false,
# translators: [{Logger.Translator, :translate}],
# backends: [:console],
# discard_threshold_for_error_logger: 500,
# handle_sasl_reports: false,
# truncate: 8096,
# discard_threshold: 500,
# compile_time_application: nil,
# sync_threshold: 20,
# discard_threshold_periodic_check: 30000,
# console: [level: :info, format: {LoggerFormatter, :format}, metadata: :all],
# handle_otp_reports: true,
# start_options: [],
# level: :info,
# translator_inspect_opts: [],
# compile_time_purge_matching: []
# ]
Logger.debug("!!!")
# level is info in config but still a debug message is printed
# !!!
IO.inspect(:logger.get_config())
# level: :all is set for Elixir handler
# %{
# handlers: [
# %{
# config: %{ ... },
# filter_default: :stop,
# filters: [
# filter_non_ssl: {&:logger_filters.domain/2, {:log, :sub, [:otp, :ssl]}}
# ],
# formatter: {:ssl_logger, %{}},
# id: :ssl_handler,
# level: :debug,
# module: :logger_std_h
# },
# %{
# config: %{ ... },
# filter_default: :log,
# filters: [],
# formatter: {:logger_formatter, %{}},
# id: Logger,
# level: :all,
# module: Logger.Handler
# }
# ],
# module_levels: [ssl_logger: :debug],
# primary: %{
# filter_default: :log,
# filters: [process_disabled: {&Logger.Filter.process_disabled/2, []}],
# level: :debug
# },
# proxy: %{ ... }
# }
end
end
How and when is the Logger app started when Mix task is ran? Why is the specified env config not loaded?
Thanks!
Most Liked
hauleth
:logger and Logger are separate beasts. :logger is part of Erlang’s :kernel application and cannot be directly configured via config.exs file (as it is already loaded and started when config.exs is parsed) and :logger application is part of Elixir’s distribution. From now I will call them :logger module and logger application respectively.
The current flow is as follows (simplified):
-
kernelapplication is started (so:loggermodule is configured) -
config.exsfile is loaded (so it cannot configure:loggermodule) -
loggerapplication is started -
loggerapplication configures:loggermodule to use Elixir’s configuration
So if you want to change log level from the config.exs then you need to use logger application:
config :logger, level: :warning
This should set :logger.get_config().primary.level to :warning so messages would be filtered by :logger module.
Yes, this is a little bit confusing, because of the compatibility reasons in Elixir, but I hope to improve that over a time in the future.







