Logger with uptime

Hi,

I would like to configure Logger to show uptime in the dev mode. Is it possible? I found it very helpful in rust with tracing.

The “just make it work” way is probably:

Alternatively (for better resolution maybe?) you could probably set some kv pair in config, to the current time (i.e. boot time), then do the same as above but do a now-then.

Phoenix might have it’s own statistic too. Might even already exist in the telemetry metrics.

1 Like

Well, if you are using Elixir 1.10 (or later) then you can use magic of “primary filters”:

:logger.add_primary_filter(:add_uptime, {fn log, _args ->
  put_in(log, [:meta, :uptime], :erlang.statistics(:wall_clock))
end)

And then you will have :uptime field available in all logs metadata. Without need for any additional magic.

2 Likes

Another option is to give custom formatting to the console logger used by default in the development environment: Logger — Logger v1.11.4

Thank you all! I will probably try first the approach with the custom formatter. As far as I understand, I need to store a kind of application start time in a GenServer and then subtract the log event timestamp from that stored time.

I’m also curious what you like about showing the uptime in dev. Is that the only timestamp you use in dev? Or do you also use the absolute time?

You wont need a separate gen server, you can piggyback your phx app.

#config/dev.exs
config :my_app,
  booted_at: System.monotonic_time(:microsecond)

config :logger, :console
  metadata: [
    :uptime
  ]
# whatever telemetry handler for phoenix endpoint stop
# or in your formatter or whatever
    boot_time = application.get_env(:my_app, :booted_at)
    now = system.monotonic_time(:microsecond)
    t = now - boot_time
    logger.metadata(uptime: "#{t}ns")

See also Precise timings with `monotonic_time` - Today I Learned

Though I would go with hauleth’s option, should be able to stick that in Application.ex I think.

3 Likes

I am mostly interested in the time difference between two log events. Thanks that you asked :slight_smile: I came to Elixir from Rust where I used to use the uptime in the dev mode. So I wanted to have this in Elixir too. But simply adding the $time to the logger format does actually more or less the same.

config :logger, :console, 
  format: "$time [$level] $message\n"

If it were possible to specify the format like $uptime [$level].... I would probably pick this option, but $time is also fine.

2 Likes