Example of using Logger.metadata

Can someone provide an example of how you would attach metadata to a process using metatdata/1? If I have a GenServer say that accepts messages with a user_id. Where would I add the user_id to the metadata so that it’s printed in the logging? I’ve been searching the docs and online, but feel I need an example to drive home the concept.

Given the following entry in your config file:

config :logger, :console, format: "[$level] $metadata$message\n",
  metadata: [:module, :function, :my_id]

You can do the following;

iex(1)> require Logger
Logger
iex(2)> Logger.info "test"
[info] module= function= test
:ok
iex(3)> Logger.info "test", [my_id: 123]
[info] module= function= my_id=123 test
:ok
iex(4)> Logger.metadata [my_id: 999]
:ok
iex(5)> Logger.info "another test"
[info] module= function= my_id=999 another test
:ok
iex(6)>

I added the :module and :function into the meta data, as an example of other meta data you might want. However, since I’m running it from iex, the don’t print anything useful.

9 Likes

This is exactly what I was looking for. Thank you!

1 Like

One thing to note about Logger.metadata is that it is set only for the current process. From the documentation

https://hexdocs.pm/logger/Logger.html#metadata/1

## Metadata

Metadata to be sent to the Logger can be read and written with the
Logger.metadata/0 and Logger.metadata/1 functions. For example, you can set
Logger.metadata([user_id: 13]) to add user_id metadata to the current process.
The user can configure the backend to chose which metadata it wants to print
and it will replace the $metadata value.
1 Like

@minhajuddin That is a good point. Glad you emphasis that.

It does, however, lend itself to a model where you have a process for each item in some collection. By setting metadata for that process at startup (presumedly with some id or name) its an easy way to identify the logs for the given item of the collection.

3 Likes

That’s the route I’ve gone thanks to your advice. Very helpful.

1 Like

Glad I found this, because I was logging like:

[warn] | Elixir.Auth.Csrf Error for :auth_csrf_secret in the session: missing.

and now:

[warn] | module=Auth.Csrf function=valid_session?/1 line=54  | Error for :auth_csrf_secret in the session: missing.

This is way better logging. In my opinion should be the default :wink: