|
@ -16,7 +16,7 @@ Features |
|
|
* When no handler is consuming a log level (eg. debug) no event is sent |
|
|
* When no handler is consuming a log level (eg. debug) no event is sent |
|
|
to the log handler |
|
|
to the log handler |
|
|
* Supports multiple backends, including console and file. |
|
|
* Supports multiple backends, including console and file. |
|
|
* Supports multiple sinks (and eventually different sync/async policies per sink) |
|
|
|
|
|
|
|
|
* Supports multiple sinks |
|
|
* Rewrites common OTP error messages into more readable messages |
|
|
* Rewrites common OTP error messages into more readable messages |
|
|
* Support for pretty printing records encountered at compile time |
|
|
* Support for pretty printing records encountered at compile time |
|
|
* Tolerant in the face of large or many log messages, won't out of memory the node |
|
|
* Tolerant in the face of large or many log messages, won't out of memory the node |
|
@ -93,32 +93,52 @@ your app.config): |
|
|
The available configuration options for each backend are listed in their |
|
|
The available configuration options for each backend are listed in their |
|
|
module's documentation. |
|
|
module's documentation. |
|
|
|
|
|
|
|
|
Multiple sinks |
|
|
|
|
|
-------------- |
|
|
|
|
|
Previously, lager supported a single sink `lager_event`. Lager can now support |
|
|
|
|
|
additional sinks with their own backend configurations. Eventually, the goal is |
|
|
|
|
|
to support different latency and sync/async message policies. (For example, if |
|
|
|
|
|
there were an `audit` sink, we might be willing to pay the latency costs to log |
|
|
|
|
|
all of those messages to disk and we don't want lager to drop them in an |
|
|
|
|
|
overload scenario.) |
|
|
|
|
|
|
|
|
|
|
|
To use multiple sinks (beyond the built in sink of lager and lager_event), you |
|
|
|
|
|
|
|
|
Sinks |
|
|
|
|
|
----- |
|
|
|
|
|
Lager has traditionally supported a single sink (implemented as a |
|
|
|
|
|
`gen_event` manager) named `lager_event` to which all backends were |
|
|
|
|
|
connected. |
|
|
|
|
|
|
|
|
|
|
|
Lager now supports extra sinks; each sink can have different |
|
|
|
|
|
sync/async message thresholds and different backends. |
|
|
|
|
|
|
|
|
|
|
|
### Sink configuration |
|
|
|
|
|
|
|
|
|
|
|
To use multiple sinks (beyond the built-in sink of lager and lager_event), you |
|
|
need to: |
|
|
need to: |
|
|
|
|
|
|
|
|
1. Setup rebar.config |
|
|
1. Setup rebar.config |
|
|
2. Configure the backends in app.config |
|
|
2. Configure the backends in app.config |
|
|
|
|
|
|
|
|
### rebar.config |
|
|
|
|
|
|
|
|
#### Names |
|
|
|
|
|
|
|
|
|
|
|
Each sink has two names: one atom to be used like a module name for |
|
|
|
|
|
sending messages, and that atom with `_event` appended for backend |
|
|
|
|
|
configuration. |
|
|
|
|
|
|
|
|
|
|
|
This reflects the legacy behavior: `lager:info` (or `critical`, or |
|
|
|
|
|
`debug`, etc) is a way of sending a message to a sink named |
|
|
|
|
|
`lager_event`. Now developers can invoke `audit:info` or |
|
|
|
|
|
`myCompanyName:debug` so long as the corresponding `audit_event` or |
|
|
|
|
|
`myCompanyName_event` sinks are configured. |
|
|
|
|
|
|
|
|
|
|
|
#### rebar.config |
|
|
|
|
|
|
|
|
In `rebar.config` for the containing project, include this tuple in `erl_opts`: |
|
|
|
|
|
|
|
|
In `rebar.config` for the project that requires lager, include a list |
|
|
|
|
|
of sink names (without the `_event` suffix) in `erl_opts`: |
|
|
|
|
|
|
|
|
`{lager_extra_sinks, [sink1, sink2, sink3]}` |
|
|
|
|
|
|
|
|
`{lager_extra_sinks, [audit]}` |
|
|
|
|
|
|
|
|
### Runtime requirements |
|
|
|
|
|
|
|
|
#### Runtime requirements |
|
|
|
|
|
|
|
|
Sinks must be configured with backends (and possibly in the future behavioral differences). |
|
|
|
|
|
|
|
|
To be useful, sinks must be configured at runtime with backends. |
|
|
|
|
|
|
|
|
app.config |
|
|
|
|
|
|
|
|
In `app.config` for the project that requires lager, for example, |
|
|
|
|
|
extend the lager configuration to include an `extra_sinks` tuple with |
|
|
|
|
|
backends (aka "handlers") and optionally `async_threshold` and |
|
|
|
|
|
`async_threshold_window` values (see **Overload Protection** |
|
|
|
|
|
below). If async values are not configured, no overload protection |
|
|
|
|
|
will be applied on that sink. |
|
|
|
|
|
|
|
|
```erlang |
|
|
```erlang |
|
|
[{lager, [ |
|
|
[{lager, [ |
|
@ -134,14 +154,16 @@ Sinks must be configured with backends (and possibly in the future behavioral di |
|
|
%% Any other sinks |
|
|
%% Any other sinks |
|
|
{extra_sinks, |
|
|
{extra_sinks, |
|
|
[ |
|
|
[ |
|
|
{sink1_event, |
|
|
|
|
|
|
|
|
{audit_event, |
|
|
[{handlers, |
|
|
[{handlers, |
|
|
[{lager_file_backend, |
|
|
[{lager_file_backend, |
|
|
[{file, "sink1.log"}, |
|
|
[{file, "sink1.log"}, |
|
|
{level, info} |
|
|
{level, info} |
|
|
] |
|
|
] |
|
|
}] |
|
|
}] |
|
|
}] |
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
{async_threshold, 500}, |
|
|
|
|
|
{async_threshold_window, 50}] |
|
|
}] |
|
|
}] |
|
|
} |
|
|
} |
|
|
] |
|
|
] |
|
|