Logger & Metadata

Hello everybody,

I’m trying to use Logger to do some structured logging. When trying it in iex, just to try to understand the way it works, I’ve done the following:

▶ iex             
Erlang/OTP 19 [erts-8.2] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.4.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> require Logger
Logger
iex(2)> Logger.configure_backend(:console, [format: "$time $message $metadata\n", metadata: [:all]])
:ok
iex(3)> Logger.debug("MSG", [key: :value])
17:27:19.470 MSG 
:ok

iex(4)> 

I expected the result to be something like:

17:27:19.470 MSG key=value 
:ok

But the metadata is not displayed here.

What am I missing here? I think I’ve read the doc multiple times without success. I’ve even tried to follow the Logger's code which just seem to confirm my first understanding.

Thank you in advance for your help, it will be much appreciated :smile:

1 Like

According to Logger — Logger v1.16.0, the only pre-defined metadata keys are :application, :module, :function, :file, :line. You specify :all in your example, which has no special meaning and is treated as a regular key. So this would work:

iex(17)> Logger.debug("MSG", [all: :value])
17:11:20.925 MSG all=value
:ok
1 Like

Well, in the console back end code I’ve found this:

  defp format_event(level, msg, ts, md, state) do
    %{format: format, metadata: keys, colors: colors} = state
    format
    |> Logger.Formatter.format(level, msg, ts, take_metadata(md, keys))
    |> color_event(level, colors, md)
  end

  defp take_metadata(metadata, :all), do: metadata
  defp take_metadata(metadata, keys) do
    Enum.reduce keys, [], fn key, acc ->
      case Keyword.fetch(metadata, key) do
        {:ok, val} -> [{key, val} | acc]
        :error     -> acc
      end
    end
  end

Which seems to allow to output all metadata, without filtering, which is my purpose here. I want any metadata passed to the Logger.debug to be appended to the output. Not just some keys provided in the logger’s back end config.

1 Like

You’ll need to use master and compile from sources. The :all option seems to have been merged only a few days ago: https://github.com/elixir-lang/elixir/pull/5892

1 Like

That’s it! That’s the point I missed. Thank you @pma. For the time being I’m stuck with Elixir 1.4.2. The fact is that I’ve been looking for something like the :all keyword to be able to log any meta data provided in the Logger.debug. Because, without any configuration, the back end seems to refuse to output them.

1 Like