Logger - custom message filtering

In our library we have two kinds of debug logs:

  1. the ones that are printed very often and thus they usually introduce significant overhead and are hard to reason about, but sometimes they’re useful
  2. the ones that are not printed that often but still can pollute the output in some cases

I’d like to distinguish them and be able to configure whether they should be printed or not. If possible, the silenced ones should be purged at the compile.

I know the logger can be configured to purge logs from particular modules and functions, and while it’s a nice possibility that I’d like to leave available, I think it’s not a good idea to require the lib users to explicitly list all the functions from either category.

There is no real solution there except maybe deciding during compilation which is the preferred way. Alternative solution would be - just use respective levels - debug for debug messages and higher for the rest. In Elixir 1.11 there should be more levels available (notice, critical, alert, and emergency - see man 3 syslog for more details).

1 Like

If you use the Erlang logger you can add filters that does what you want: http://erlang.org/doc/man/logger_filters.html

3 Likes

This still applies more to the applications rather than libraries as magically adding filters by library is rather something I would avoid.

Thanks for your replies. I checked the logger code and realized that compile_time_purge_matching actually operates on logger’s metadata :slight_smile: And found out that’s even documented here. So I tried something like

debug("Something", my_lib_name: :detailed_debug)

and then

config :logger,
  backends: [:console],
  compile_time_purge_matching: [
    [my_lib_name: :detailed_debug]
  ]

and it seems to work :wink:

3 Likes

Remember that this will work only for your library compilation. End user will need to do the same if they want to exclude that log calls in their applications.

2 Likes

That’s true, it would be better to have detailed logs disabled by default. Maybe we’ll make a separate purging mechanism for that.

Only solution is to write your own tooling on top of Logger. For example you can do:

defmodule MyLogger do
  defmacro debug_verbose(msg, meta \\ []) do
    if enable_verbose?() do
      quote do
        Logger.debug(unquote(msg), unquote(meta))
      end
    else
      # To mitigate "unused variable" messages
      quote do
        fn -> unquote(msg) end
      end
    end
  end
end

This will now decide in compile-time whether you want to have your extra-verbose messages or not.

3 Likes