Home > Erlang > How to log your stuff with Lager

How to log your stuff with Lager

When you start coding something more complex in Erlang, eventually you will need some sort of logging framework for your Erlang/OTP applications.
There are many solutions available out there for you, but today I would like to write a post about Lager. Who knows, maybe in the future I will write something about the others as well.

Lager is tasty!


Lager (as the beer) is a logging framework introduced by Basho, a company that you should already know since they are the authors of some killer applications such as rebar and riak. If you want to know more about Basho check out their web site or my interview to Dave Smith.

Why should you pick Lager for you project? In my humble opinion I have to say that Lager is easier to integrate to your project, easy to use and (last but not least) log files generated using it will be loved by your sysadmins.

I have to be honest here: I have always been “scared” by the multi-line-message (maybe with SASL) you receive when something goes wrong in your code. Actually, I strongly believe most of Erlang developers reading this post felt the same when they started with Erlang.

Yes, it is true that with SASL you have much more information about what went wrong and why, but sometimes (especially if you are a beginner) too much information can confuse you. Lager helps a lot in this sense. It gives just a friendlier one-line print, but if you need more information you can still access them since Lager stores them in a crash log which can be inspected later if needed.

What? You say this is still not enough? Well, I can list you some more cool features!

  1. Lager allows you to chose among different log messages (e.g. debug, info, notice, warning, error, critical, alert, emergency), this is something I have seen also on ejabberd custom logger, and I find it very very useful.
  2.  Lager gives support for multiple backends (e.g. console and file). What does this mean in practice? You just need to know that Lager is a gen_event with multiple handlers installed. At Basho, they are planning to add more, but currently they provided a console handler and a file handler. The interesting thing about file logging is that you can have differente files for different log levels, so for example you can have a log of only errors and above. Notice also that log levels may be changed at runtime.
  3. Lager does not need to add a newline (~n) at the end of the message. I’m lazy…so I love this small feature!

If you liked this introduction on Lager, you may want to add it to your project and try some of the API provided! Let’s see how to do it.

I assume you build your projects using rebar, therefore the first thing to do is to add Lager as a deps in you rebar.config file, that in the end should look like this:

{sub_dirs, []}.

{deps, [
        {lager, ".*", {git, "git://github.com/basho/lager.git", "master"}}

{erl_opts, [{parse_transform, lager_transform}]}.

For this tutorial I will show you how to build a simple application (myapp) with consists of just a supervisor and a gen_server (I assume you know how to spawn the top supervisor from the application and the gen_server from the top supervisor).

Since this is not a tutorial on rebar, I will just use a common way used to compile and start an application for development purposes, if you want something which may fit in production take a look at this tutorial.

Ok, this is my directory structure:

paolo@paolo-laptop:~/blog/lager-article$ ls
deps ebin rebar rebar.config src

Let see src content:

paolo@paolo-laptop:~/blog/lager-article$ ls src
myapp.app.src myapp.erl myapp_server.erl myapp_sup.erl

Where myapp.app.src is:

paolo@paolo-laptop:~/blog/lager-article$ less src/myapp.app.src

{application, myapp, [
        {description, "experimenting with lager."},
        {vsn, "0.1.0"},
        {modules, [myapp_sup, myapp_server]},
        {registered, [myapp_sup, myapp_server]},
        {applications, [
        {env, []},
        {mod, {myapp, []}}

Cool, everything is in place! We can compile and run the application using:

paolo@paolo-laptop:~/blog/lager-article$ erl -sname mynode -pa deps/lager/ebin -pa ebin -eval "application:start(compiler), application:start(syntax_tools), application:start(lager), application:start(myapp)."

Erlang R15B (erts-5.9)  [64-bit] [smp:2:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9  (abort with ^G)
(paolo@paolo-laptop)1> 20:24:04.070 [info] Application lager started on node myapp@paolo-laptop
20:24:04.072 [info] Application myapp started on node mynode@paolo-laptop

Lager starts, awesome! Now you can experiment more using in your gen_server (for example in init/1) one of these functions:

     lager:info("~s is ~s!", [lager, cool]),
     lager:warning("but pay ~s!", [attention]),
     lager:error("there is always some ~s", [error]),

You should now have a nice directory called “log”, open it and inspect the files!

Tere is much more stuff I would love to say about Lager, but I think this post is growing too much, so I suggest you to read the readme file you can find with Lager on github and this post by Andrew Thompson.

Categories: Erlang Tags: , ,
  1. dmitrij
    February 6, 2014 at 3:14 pm

    Thanks, it is very useful post.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: