Sunday, October 26, 2025

Elixir Syslog Logger

Now that Elixir is fully integrated with the Erlang/OTP logger, using custom Elixir logger backends has been deprecated in favor of Erlang/OTP logger handlers.

So if you want improved systemd-journald logging that handles multi-line messages properly and propagates log levels, you can still use the ExSyslogger Elixir logger backend (which I advocated in my 2021 Elixir Systemd Logging blog post) — but the "modern" way is to use an Erlang/OTP logger handler that natively makes libc syslog calls.

Lukas Backström maintains just such a logger handler: syslogger. You can use it to replace the default handler in an Elixir project (that would normally log everything to stdout) with the following steps:

1. Add the syslogger dependency

First, add the syslogger library as a dependency to your mix.exs file. Unfortunately syslogger isn't available as a Hex package, so you have to pull the source from GitHub directly:

# mix.exs defp deps do [ {:syslogger, git: "https://github.com/garazdawi/syslogger.git", ref: "64d3b22"} ] end

2. Override default_handler module

Next, override the module option for the default_handler configuration of Elixir's logger to use syslogger in your config/prod.exs file:

# config/prod.exs config :logger, :default_handler, module: :syslogger

At this point, you've done enough to send all of your logging (in production) through the standard syslog /dev/log socket instead of stdout.

3. Configure syslogger

The main two configuration options of syslogger that you can adjust are the program identifier (aka ident) and facility under which messages will be logged. The defaults are to use the name of your program as the identifier, and user as the facility. You can change the defaults by setting the ident and facility options in your config/prod.exs file:

# config/prod.exs config :syslogger, :ident, ~c"my_app" config :syslogger, :facility, :daemon

4. Remove timestamp formatting

You will probably want to remove the extra timestamp in log messages output by syslogger, since syslog will include the timestamp automatically as part of its structured log data; you can do this by overriding the format option for the Elixir logger's default_formatter to remove the $time token in your config/prod.exs file:

# config/prod.exs config :logger, :default_formatter, format: "$metadata[$level] $message\n", metadata: [:request_id]

5. Remove ex_syslogger

If you were using the ex_syslogger library, remove it as a dependency in your mix.exs file:

# mix.exs defp deps do [ {:ex_syslogger, "~> 1.5"} ] end

And remove the backends option from the root logger configuration in your config/prod.exs file:

# config/prod.exs config :logger, level: :info, backends: [{ExSyslogger, :ex_syslogger}] config :logger, level: :info

And remove the ex_syslogger options from your config/config.exs file:

# config/config.exs config :logger, :ex_syslogger, format: "$time $metadata[$level] $message\n", metadata: [:request_id], ident: "my_app"