akasprzok

akasprzok

LogfmtEx is a log formatter for the logfmt format popularized by Heroku.

Logging in Elixir is pretty rudimentary: The :console logger can be configured to emit logs in a certain format according to a formatting string, specifying time, date, message, levek, node, and metadata fields.

A typical configuration will look like

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

which will emit logs along the lines of

18:43:12.439 user_id=13 [error] Hello\n

These logs are easy to sight read, however there are a variety of drawbacks to this approach. Firstly, the log is somewhat unstructured, and will require some kind of regex to be parsed by a log aggregator. Additionally, the metadata formatter will drop certain data types,such as structs, silently. Lastly, newlines and tabs aren’t escaped, which makes for stack traces that are easy to sight read, but require some sort of multiline regexing to be properly ingested by aggregators such as Datadog or Grafana Loki.

Logfmt

Logfmt is a log format in which each line consists key=value paris:

ts=18:43:12.439 user_id=13 level=error msg=Hello\n

It’s unambiguous, much easier to sight read than JSON, easy to search with grep, popularized by Heroku, and recommended by Splunk.

In Elixir, we can use the LogfmtEx library to convert our logs to logfmt.

Let’s pull the library into our mix.exs:

{:logfmt_ex, "~> 0.4"}

Then configure the :console logger to call LogfmtEx’s :format function:

config :logger, :console,
    :format: {LogfmtEx, :format}

Your logs will be emitted in logfmt with sensible defaults, but the order of fields, keys for timestamp and message, timestamp format, and more can be customized. See the docs for more info.

The library considers a variety of edge cases: messages with spaces are quoted, newlines and tabs escaped, and it supports custom encoding for your data types via the ValueEncoder protocol.

Value Encoding

Values are encoded using the LogfmtEx.ValueEncoder protocol, making it simple to encode your data types:

defmodule User do
  defstruct [:email, :name, :id]

  @doc """
  Encode user to just the ID so we don't accidentally
  leak PII into logs.
  """
  defimpl LogfmtEx.ValueEncoder do
    def encode(user), do: to_string(user.id)
  end
end

If there is no protocol specified for a given data type, encoding will fall back to String.Chars, and finally Kernel.inspect/1.

Examples

level=info msg="Finished request" traceID=8006567127ae87f1b2b4163ab05ebf3b pid=#PID<0.25691.2> mfa=TemporaryHack.Plug.Logger.call/2 path=/projects connection_type=sent span_id=f0f816caa49080aa status=200 duration_ms=3 method=GET
level=info msg="Finished request" pid=#PID<0.25614.2> mfa=TemporaryHack.Middleware.Logger.call/3 status=200 duration_ms=89.687 url=https://hex.pm/api/packages/:package method=GET query=""

Where Next? Top

Trending in Announcing Top

type1fool
WebAuthnLiveComponent WebAuthnComponents See this post about renaming the package. Passwordless authentication for Phoenix LiveView app...
New
GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
woylie
I released Doggo, a collection of unstyled Phoenix components. https://github.com/woylie/doggo Features Unstyled Phoenix components....
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
ahamez
Hi everyone, I’ve been working on this protobuf library for 3 years. We use it in the company I work for, EasyMile, to communicate with ...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
kip
I’ll shortly be launching Text, a nascent text analysis library. Current functionality In this early version (not ready for prime time) ...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
bartblast
Hey folks, I just published a post about Hologram’s funding and where the project goes next - the short version: Curiosum as Main Spons...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews