* Logger calls are transformed using a parse transform to allow capturing
Module/Function/Line/Pid information
* When no handler is consuming a log level (eg. debug) no event is even sent
* When no handler is consuming a log level (eg. debug) no event is sent
to the log handler
* Supports multiple backends, including console and file.
* Rewrites common OTP error messages into more readable messages
@ -26,8 +26,8 @@ Features
Usage
-----
To use lager in your application, you need to define it as a rebar dep or have
some other way of including it in erlang's path. You can then add the
following option to the erlang compiler flags
some other way of including it in Erlang's path. You can then add the
following option to the erlang compiler flags:
```erlang
{parse_transform, lager_transform}
@ -41,7 +41,7 @@ enabled:
```
Before logging any messages, you'll need to start the lager application. The
lager module's start function takes care of loading and starting any dependencies
lager module's `start` function takes care of loading and starting any dependencies
lager requires.
```erlang
@ -67,7 +67,7 @@ lager:error("Some message")
lager:warning("Some message with a term: ~p", [Term])
```
The general form is lager:Severity() where Severity is one of the log levels
The general form is `lager:Severity()` where `Severity` is one of the log levels
mentioned above.
Configuration
@ -94,7 +94,7 @@ module's documentation.
Custom Formatting
-----------------
All loggers have a default formatting that can be overriden. A formatter is any module that
exports format(#lager_log_message{},Config#any()). It is specified as part of the configuration
exports `format(#lager_log_message{},Config#any())`. It is specified as part of the configuration
for the backend:
```erlang
@ -108,49 +108,52 @@ for the backend:
]}.
```
Included is lager_default_formatter. This provides a generic, default formatting for log messages using a "semi-iolist"
as configuration. Any iolist allowed elements in the configuration are printed verbatim. Atoms in the configuration
are treated as metadata properties and extracted from the log message.
The metadata properties date,time, message, and severity will always exist.
The properties pid, file, line, module, function, and node will always exist if the parser transform is used.
Included is `lager_default_formatter`. This provides a generic, default formatting for log messages using a structure similar to Erlang's [iolist](http://learnyousomeerlang.com/buckets-of-sockets#io-lists) which we call "semi-iolist":
* Any traditional iolist elements in the configuration are printed verbatim.
* Atoms in the configuration are treated as placeholders for lager metadata and extracted from the log message.
* The placeholders `date`, `time`, `message`, and `severity` will always exist.
* The placeholders `pid`, `file`, `line`, `module`, `function`, and `node` will always exist if the parse transform is used.
* Applications can define their own metadata placeholder.
* A tuple of `{atom(), semi-iolist()}` allows for a fallback for
the atom placeholder. If the value represented by the atom
cannot be found, the semi-iolist will be interpreted instead.
* A tuple of `{atom(), semi-iolist(), semi-iolist()}` represents a
conditional operator: if a value for the atom placeholder can be
found, the first semi-iolist will be output; otherwise, the
second will be used.
Examples:
```
["Foo"] -> "Foo", regardless of message content.
[message] -> The content of the logged message, alone.
[{pid,"Unknown Pid"}] -> "<?.?.?>" if pid is in the metadata, "Unknown Pid" if not.
[{pid, ["My pid is ", pid], "Unknown Pid"}] -> if pid is in the metadata print "My pid is <?.?.?>", otherwise print "Unknown Pid"
```
Optionally, a tuple of {atom(),semi-iolist()}
can be used. The atom will look up the property, but if not found it will use the semi-iolist() instead. These fallbacks
can be nested or refer to other properties.
```
[{pid,"Unknown Pid"}] -> "<?.?.?>" if pid is in the metadata, "Unknown Pid" if not.
[{server,[$(,{pid,"Unknown Server"},$)]}}] -> user provided server metadata, otherwise "(<?.?.?>)", otherwise "(Unknown Server)"
```
Error logger integration
------------------------
Lager is also supplied with a error_logger handler module that translates
Lager is also supplied with a `error_logger` handler module that translates
traditional erlang error messages into a friendlier format and sends them into
lager itself to be treated like a regular lager log call. To disable this, set
the lager application variable `error_logger_redirect` to `false`.
The error_logger handler will also log more complete error messages (protected
with use of trunc_io) to a "crash log" which can be referred to for further
The `error_logger` handler will also log more complete error messages (protected
with use of `trunc_io`) to a "crash log" which can be referred to for further
information. The location of the crash log can be specified by the crash_log
application variable. If set to `undefined` it is not written at all.
Messages in the crash log are subject to a maximum message size which can be
specified via the crash_log_msg_size application variable.
specified via the `crash_log_msg_size` application variable.
Overload Protection
-------------------
Prior to lager 2.0, the gen_event at the core of lager operated purely in
Prior to lager 2.0, the `gen_event` at the core of lager operated purely in
synchronous mode. Asynchronous mode is faster, but has no protection against
message queue overload. In lager 2.0, the gen_event takes a hybrid approach. it
message queue overload. In lager 2.0, the `gen_event` takes a hybrid approach. it
polls its own mailbox size and toggles the messaging between synchronous and
asynchronous depending on mailbox size.
@ -163,12 +166,12 @@ This will use async messaging until the mailbox exceeds 20 messages, at which
point synchronous messaging will be used, and switch back to asynchronous, when
size reduces to `20 - 5 = 15`.
If you wish to disable this behaviour, simply set it to 'undefined'. It defaults
If you wish to disable this behaviour, simply set it to `undefined`. It defaults
to a low number to prevent the mailbox growing rapidly beyond the limit and causing
problems. In general, lager should process messages as fast as they come in, so getting
20 behind should be relatively exceptional anyway.
If you want to limit the number of messages per second allowed from error_logger,
If you want to limit the number of messages per second allowed from `error_logger`,
which is a good idea if you want to weather a flood of messages when lots of