Browse Source

Typos, extra formatting, rework the semi-iolist description

pull/219/head
John R. Daily 11 years ago
committed by Andrew Thompson
parent
commit
30fbfbfd62
1 changed files with 66 additions and 63 deletions
  1. +66
    -63
      README.md

+ 66
- 63
README.md View File

@ -13,7 +13,7 @@ Features
alert, emergency) alert, emergency)
* Logger calls are transformed using a parse transform to allow capturing * Logger calls are transformed using a parse transform to allow capturing
Module/Function/Line/Pid information 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 to the log handler
* Supports multiple backends, including console and file. * Supports multiple backends, including console and file.
* Rewrites common OTP error messages into more readable messages * Rewrites common OTP error messages into more readable messages
@ -26,8 +26,8 @@ Features
Usage Usage
----- -----
To use lager in your application, you need to define it as a rebar dep or have 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 ```erlang
{parse_transform, lager_transform} {parse_transform, lager_transform}
@ -41,7 +41,7 @@ enabled:
``` ```
Before logging any messages, you'll need to start the lager application. The 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. lager requires.
```erlang ```erlang
@ -67,7 +67,7 @@ lager:error("Some message")
lager:warning("Some message with a term: ~p", [Term]) 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. mentioned above.
Configuration Configuration
@ -94,7 +94,7 @@ module's documentation.
Custom Formatting Custom Formatting
----------------- -----------------
All loggers have a default formatting that can be overriden. A formatter is any module that 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: for the backend:
```erlang ```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. ["Foo"] -> "Foo", regardless of message content.
[message] -> The content of the logged message, alone. [message] -> The content of the logged message, alone.
[{pid,"Unknown Pid"}] -> "<?.?.?>" if pid is in the metadata, "Unknown Pid" if not. [{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" [{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)" [{server,[$(,{pid,"Unknown Server"},$)]}}] -> user provided server metadata, otherwise "(<?.?.?>)", otherwise "(Unknown Server)"
``` ```
Error logger integration 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 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 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 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 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. 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 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 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 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 polls its own mailbox size and toggles the messaging between synchronous and
asynchronous depending on mailbox size. 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 point synchronous messaging will be used, and switch back to asynchronous, when
size reduces to `20 - 5 = 15`. 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 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 problems. In general, lager should process messages as fast as they come in, so getting
20 behind should be relatively exceptional anyway. 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 which is a good idea if you want to weather a flood of messages when lots of
related processes crash, you can set a limit: related processes crash, you can set a limit:
@ -193,8 +196,8 @@ lager:set_loglevel(lager_console_backend, debug).
lager:set_loglevel(lager_file_backend, "console.log", debug). lager:set_loglevel(lager_file_backend, "console.log", debug).
``` ```
Lager keeps track of the minium log level being used by any backend and
supresses generation of messages lower than that level. This means that debug
Lager keeps track of the minimum log level being used by any backend and
suppresses generation of messages lower than that level. This means that debug
log messages, when no backend is consuming debug messages, are effectively log messages, when no backend is consuming debug messages, are effectively
free. A simple benchmark of doing 1 million debug log messages while the free. A simple benchmark of doing 1 million debug log messages while the
minimum threshold was above that takes less than half a second. minimum threshold was above that takes less than half a second.
@ -218,21 +221,21 @@ a quoted atom or a string.
Internal log rotation Internal log rotation
--------------------- ---------------------
Lager can rotate its own logs or have it done via an external process. To Lager can rotate its own logs or have it done via an external process. To
use internal rotation, use the 'size', 'date' and 'count' values in the file
use internal rotation, use the `size`, `date` and `count` values in the file
backend's config: backend's config:
```erlang ```erlang
[{file, "error.log"}, {level, error}, {size, 10485760}, {date, "$D0"}, {count, 5}] [{file, "error.log"}, {level, error}, {size, 10485760}, {date, "$D0"}, {count, 5}]
``` ```
This tells lager to log error and above messages to "error.log" and to
rotate the file at midnight or when it reaches 10mb, whichever comes first
and to keep 5 rotated logs, in addition to the current one. Setting the
This tells lager to log error and above messages to `error.log` and to
rotate the file at midnight or when it reaches 10mb, whichever comes first,
and to keep 5 rotated logs in addition to the current one. Setting the
count to 0 does not disable rotation, it instead rotates the file and keeps count to 0 does not disable rotation, it instead rotates the file and keeps
no previous versions around. To disable rotation set the size to 0 and the no previous versions around. To disable rotation set the size to 0 and the
date to "". date to "".
The "$D0" syntax is taken from the syntax newsyslog uses in newsyslog.conf.
The `$D0` syntax is taken from the syntax newsyslog uses in newsyslog.conf.
The relevant extract follows: The relevant extract follows:
``` ```
@ -263,18 +266,18 @@ Some examples:
To configure the crash log rotation, the following application variables are To configure the crash log rotation, the following application variables are
used: used:
* crash_log_size
* crash_log_date
* crash_log_count
* `crash_log_size`
* `crash_log_date`
* `crash_log_count`
See the .app.src file for further details.
See the `.app.src` file for further details.
Syslog Support Syslog Support
-------------- --------------
Lager syslog output is provided as a separate application;
Lager syslog output is provided as a separate application:
[lager_syslog](https://github.com/basho/lager_syslog). It is packaged as a [lager_syslog](https://github.com/basho/lager_syslog). It is packaged as a
separate application so Lager itself doesn't have an indirect dependancy on a
port driver. Please see the lager_syslog README for configuration information.
separate application so lager itself doesn't have an indirect dependency on a
port driver. Please see the `lager_syslog` README for configuration information.
Older Backends Older Backends
-------------- --------------
@ -287,26 +290,26 @@ Record Pretty Printing
Lager's parse transform will keep track of any record definitions it encounters Lager's parse transform will keep track of any record definitions it encounters
and store them in the module's attributes. You can then, at runtime, print any and store them in the module's attributes. You can then, at runtime, print any
record a module compiled with the lager parse transform knows about by using the record a module compiled with the lager parse transform knows about by using the
lager:pr/2 function, which takes the record and the module that knows about the record:
`lager:pr/2` function, which takes the record and the module that knows about the record:
```erlang ```erlang
lager:info("My state is ~p", [lager:pr(State, ?MODULE)]) lager:info("My state is ~p", [lager:pr(State, ?MODULE)])
``` ```
Often, ?MODULE is sufficent, but you can obviously substitute that for a literal module name.
lager:pr also works from the shell.
Often, `?MODULE` is sufficent, but you can obviously substitute that for a literal module name.
`lager:pr` also works from the shell.
Colored terminal output Colored terminal output
----------------------- -----------------------
If you have erlang R16 or higher, you can tell lager's console backend to be colored. Simply
add
If you have Erlang R16 or higher, you can tell lager's console backend to be colored. Simply
add to lager's application environment config:
```erlang ```erlang
{colored, true} {colored, true}
``` ```
To lager's application environment config. If you don't like the default colors, they are
also configurable, see the app.src file for more details.
If you don't like the default colors, they are also configurable; see
the `.app.src` file for more details.
The output will be colored from the first occurrence of the atom color The output will be colored from the first occurrence of the atom color
in the formatting configuration. For example: in the formatting configuration. For example:
@ -336,17 +339,17 @@ based on request or vhost:
lager:trace_file("logs/example.com.error", [{vhost, "example.com"}], error) lager:trace_file("logs/example.com.error", [{vhost, "example.com"}], error)
``` ```
To persist metadata for the life of a process, you can use lager:md/1 to store metadata
To persist metadata for the life of a process, you can use `lager:md/1` to store metadata
in the process dictionary: in the process dictionary:
```erlang ```erlang
lager:md([{zone, forbidden}]) lager:md([{zone, forbidden}])
``` ```
Note that lager:md will *only* accept a list of key/value pairs keyed by atoms.
Note that `lager:md` will *only* accept a list of key/value pairs keyed by atoms.
You can also omit the final argument, and the loglevel will default to You can also omit the final argument, and the loglevel will default to
'debug'.
`debug`.
Tracing to the console is similar: Tracing to the console is similar:
@ -357,22 +360,22 @@ lager:trace_console([{request, 117}])
In the above example, the loglevel is omitted, but it can be specified as the In the above example, the loglevel is omitted, but it can be specified as the
second argument if desired. second argument if desired.
You can also specify multiple expressions in a filter, or use the '*' atom as
You can also specify multiple expressions in a filter, or use the `*` atom as
a wildcard to match any message that has that attribute, regardless of its a wildcard to match any message that has that attribute, regardless of its
value. value.
Tracing to an existing logfile is also supported, if you wanted to log Tracing to an existing logfile is also supported, if you wanted to log
warnings from a particular function in a particular module to the default error.log:
warnings from a particular function in a particular module to the default `error.log`:
```erlang ```erlang
lager:trace_file("log/error.log", [{module, mymodule}, {function, myfunction}], warning) lager:trace_file("log/error.log", [{module, mymodule}, {function, myfunction}], warning)
``` ```
To view the active log backends and traces, you can use the lager:status()
function. To clear all active traces, you can use lager:clear_all_traces().
To view the active log backends and traces, you can use the `lager:status()`
function. To clear all active traces, you can use `lager:clear_all_traces()`.
To delete a specific trace, store a handle for the trace when you create it, To delete a specific trace, store a handle for the trace when you create it,
that you later pass to lager:stop_trace/1:
that you later pass to `lager:stop_trace/1`:
```erlang ```erlang
{ok, Trace} = lager:trace_file("log/error.log", [{module, mymodule}]), {ok, Trace} = lager:trace_file("log/error.log", [{module, mymodule}]),
@ -391,27 +394,27 @@ As of lager 2.0, you can also use a 3 tuple while tracing, where the second
element is a comparison operator. The currently supported comparison operators element is a comparison operator. The currently supported comparison operators
are: are:
* '<' - less than
* '=' - equal to
* '>' - greater than
* `<` - less than
* `=` - equal to
* `>` - greater than
```erlang ```erlang
lager:trace_console([{request, '>', 117}, {request, '<', 120}]) lager:trace_console([{request, '>', 117}, {request, '<', 120}])
``` ```
Using '=' is equivalent to the 2-tuple form.
Using `=` is equivalent to the 2-tuple form.
Setting the truncation limit at compile-time Setting the truncation limit at compile-time
-------------------------------------------- --------------------------------------------
Lager defaults to truncating messages at 4096 bytes, you can alter this by Lager defaults to truncating messages at 4096 bytes, you can alter this by
using the {lager_truncation_size, X} option. In rebar, you can add it to
erl_opts:
using the `{lager_truncation_size, X}` option. In rebar, you can add it to
`erl_opts`:
```erlang ```erlang
{erl_opts, [{parse_transform, lager_transform}, {lager_truncation_size, 1024}]}. {erl_opts, [{parse_transform, lager_transform}, {lager_truncation_size, 1024}]}.
``` ```
You can also pass it to erlc, if you prefer:
You can also pass it to `erlc`, if you prefer:
``` ```
erlc -pa lager/ebin +'{parse_transform, lager_transform}' +'{lager_truncation_size, 1024}' file.erl erlc -pa lager/ebin +'{parse_transform, lager_transform}' +'{lager_truncation_size, 1024}' file.erl

Loading…
Cancel
Save