Restrict File Logger to a specific log level

Hey,

I want to store info and error logs in two separate files. Here is my setup:

config :logger,
   backends: [{LoggerFileBackend, :log_file_info},
              {LoggerFileBackend, :log_file_error}]

config :logger, :log_file_info,
   level: :info,
   format: "$message\n",
   path: "./log/info.log",

config :logger, :log_file_error,
       level: :error,
       format: "$time $metadata[$level] $message\n",
       path: "./log/error.log"

But the info.log file also contains errors. The error.log file only contains errors, as expected.
I also tried to set metadata_filter: [level: :info] on the info logger but then I get no logs at all.

Am I doing something wrong or is it not possible to limit it to only the exact log level?

The level there means this level or anything more urgent. The order is:

error
warn
info
debug

So, when you say info level for example, it means info and above. You could probably filter messages with a custom logger backend, though, there may be performance implications. Not sure.

Then the example in the File Logger README is very misleading as it covers this exact usecase.

I was describing how the elixir logger works, I’m not familiar with that library. Though, I agree, the docs do seem to imply what you’re saying. Looking at the source though, seems to clarify:

  def handle_event({level, _gl, {Logger, msg, ts, md}}, %{level: min_level, metadata_filter: metadata_filter} = state) do
    if (is_nil(min_level) or Logger.compare_levels(level, min_level) != :lt) and metadata_matches?(md, metadata_filter) do
      log_event(level, msg, ts, md, state)
    else
      {:ok, state}
    end
  end

That is really unfortunate.

I am using it in combination with plug_logger_json.
All my logs are in JSON while the Elixir error will just spread over multiple lines as normal Text.

That’s the reason I want to put them in different files. I intend to parse the request logs and will run into problems with that plain Elixir error in there.

Well, you could contribute a max_level option to that library. It’s also only a single file. You could probably write your own that starts with that one as a base.

Yeah, I will probably do one of that.