Most erlang applications use a combination of the default run_erl logging and sasl/error_logger. I briefly discussed tweaking the run_erl logging via environment variables in a previous post. While these tools are useful, they are not feature rich and could be improved on.

Lager is a logging tool recently introduced by the folks from Basho. The application provides a simple syntax for writing log messages. By using parse transforms, Lager is able to offer a clean API, while decorating log messages with many conveniences. Lager also has a few tricks to boost performance by ignoring certain log statements altogether if no handlers are present to receive those events. A quick anecdotal test indicated an 80% performance increase when switching over to lager from (horrors) io:format() log statements.

Integrating Lager into a project is relatively straight forward, although there are a few gotchas along the way for the uninitiated.

Activating the Parse Transform

There are two ways to activate the parse transform: include in your rebar erl_opts or add a -compile directive in the source file containing lager statements. The first is a wholesale activation, which seems like a good idea rather than on a per module basis, but it isn’t as rosy as that. Often, you’ll enocunter and undef related to the parse transform when compiling. This occurs because rebar is attempting to apply the parse_transform to each dependency. If this is not what you want, then you should stick to -compile directives. Otherwise a simple hack is to make lager your first dependency. Clearly this will only work if you only have one parse_transform. There are likely other options using other rebar config options, although erl_first_files is not what you’re looking for.*

Starting the Application

The other critical step is to start the lager application! If you are writing a standard OTP application, then add it in your root supervisor init.


  • Is lager started in your application? Verify that application:which_applications() contains lager.
  • If your configuration is bad, you won’t know it but there also won’t be any messages. The basic sanity check is to remove your configuration completely and let lager use its default configuration. You should see an error.log and a console.log appear in the log directory of your release.
  • As mentioned above, if you add the parse_transform to erl_opts, you must make lager your first dependency in your rebar.config. If you have other dependencies with parse_transforms, let me know how you get that to work.


* Rebar already compiles parse_transforms first, but this seems to be limited to the top-level project, so dependencies with parse_transforms don’t seem to be compiled properly. Maybe there’s a way to scope erl_opts to only the current project and not its dependencies.