logi_stdlib
===========
[](https://hex.pm/packages/logi_stdlib)
[](https://travis-ci.org/sile/logi_stdlib)
[](https://codecov.io/gh/sile/logi_stdlib/branch/master)
[](LICENSE)
Standard library for [logi](https://github.com/sile/logi)
Build
-----
The build tool is [rebar3](https://github.com/erlang/rebar3).
Add following code to your `rebar.config` file:
```erlang
{deps,
[
logi_stdlib
]}.
```
Starts erlang shell:
```erlang
$ rebar3 shell
> application:ensure_all_started(logi_stdlib).
> error_logger:tty(false). % Suppresses annoying warnings for the sake of brevity
> {ok, _} = logi_channel:install_sink(logi_sink_console:new(sample), info).
> logi:info("Hello World!").
2016-05-09 13:15:54.758 [info] nonode@nohost <0.88.0> erl_eval:do_apply:674 [] Hello World!
```
API
---
See [EDoc Documents](https://hexdocs.pm/logi_stdlib/)
Usage Examples
--------------
### Outputs to console and file
```erlang
%%% Installs sinks
> ConsoleSink = logi_sink_console:new(console).
> FileSink = logi_sink_file:new(file, "/tmp/alert.log").
> {ok, _} = logi_channel:install_sink(ConsoleSink, info).
> {ok, _} = logi_channel:install_sink(FileSink, alert).
%%% Log messages
%% info log
> logi:info("Hello World!").
2016-05-09 13:19:55.327 [info] nonode@nohost <0.88.0> erl_eval:do_apply:674 [] Hello World!
> file:read_file("/tmp/alert.log").
{ok, <<>>}
%% alert log
> logi:alert("Something Wrong").
2016-05-09 13:21:04.953 [alert] nonode@nohost <0.88.0> erl_eval:do_apply:674 [] Something Wrong
> file:read_file("/tmp/alert.log").
{ok,<<"2016-05-09 13:21:04.953 [alert] nonode@nohost <0.88.0> erl_eval:do_apply:674 [] Something Wrong\n">>}
```
### Forwards error_logger messages
```erlang
%%% Installs sinks
> {ok, _} = logi_channel:install_sink(logi_sink_console:new(console), info).
%%% Installs logi's error_logger handler
> ok = logi_source_error_logger:install().
%%% Log messages via error_logger module
> error_logger:info_msg("Hello World!").
2016-05-09 13:28:43.575 [info] nonode@nohost <0.5.0> logi_source_error_logger:default_log_fun:144 [gleader=<0.86.0>,sender=<0.88.0>] Hello World!
```
### Limits log messages size
```erlang
%%% Installs sinks
> Layout = logi_layout_newline:new(logi_layout_limit:new(logi_layout_default:new(), [{max_size, 32}])). % limit: 32 bytes
> Sink = logi_sink_console:new(console, Layout).
> {ok, _} = logi_channel:install_sink(Sink, info).
%%% Log messages
> logi:info("Hello World!").
2016-05-09 13:33:23.840 [info] n...59... % Tail of the long message was abbreviated
```
### Frequency control per logger
```erlang
%%% Installs sinks
> {ok, _} = logi_channel:install_sink(logi_sink_console:new(console), info).
%%% Setup logger instance with a logi_filter_frequency filter
%%% LIMIT: 3 messages per second
> logi:save_as_default(logi:new([{filter, logi_filter_frequency:new([{max_count, 3}, {period, 1000}])}])).
%%% Log messages
> lists:foreach(fun (I) -> logi:info("Hello: ~p", [I]) end, lists:seq(1, 10)).
2016-05-09 13:41:29.150 [info] nonode@nohost <0.195.0> lists:foreach:1337 [] Hello: 1
2016-05-09 13:41:29.150 [info] nonode@nohost <0.195.0> lists:foreach:1337 [] Hello: 2
2016-05-09 13:41:29.151 [info] nonode@nohost <0.195.0> lists:foreach:1337 [] Hello: 3
> timer:sleep(1000).
> logi:info("World!").
2016-05-09 13:41:30.812 [info] nonode@nohost <0.195.0> lists:foreach:1337 [] Over a period of 1.661 seconds, 7 messages were dropped
2016-05-09 13:41:30.812 [info] nonode@nohost <0.195.0> erl_eval:do_apply:674 [] World!
```
### Frequency control per sink
```erlang
%%% Installs sinks
%%% LIMITE: 300 bytes per second
> Sink = logi_sink_flow_limiter:new(limiter, logi_sink_console:new(console), [{write_rate_limits, [{300, 1000}]}]).
> {ok, _} = logi_channel:install_sink(Sink, info).
%%% Log messages
> lists:foreach(fun (I) -> logi:info("Hello: ~p", [I]) end, lists:seq(1, 10)).
2016-05-09 13:48:26.160 [info] nonode@nohost <0.105.0> lists:foreach:1337 [] Hello: 1
2016-05-09 13:48:26.171 [info] nonode@nohost <0.105.0> lists:foreach:1337 [] Hello: 2
2016-05-09 13:48:26.172 [info] nonode@nohost <0.105.0> lists:foreach:1337 [] Hello: 3
2016-05-09 13:48:26.172 [info] nonode@nohost <0.105.0> lists:foreach:1337 [] Hello: 4
> timer:sleep(1000).
> logi:info("World!").
2016-05-09 13:48:43.768 [info] nonode@nohost <0.105.0> erl_eval:do_apply:674 [] World!
2016-05-09 13:49:01.889 [warning] nonode@nohost <0.111.0> logi_sink_flow_limiter_writer:report_omissions:189 [] Over a period of 60 seconds, 6 info messages were omitted: channel=logi_default_log, reason=rate_exceeded (e.g. [{pid,module,line},{<0.105.0>,lists,1337}])
```
### High Availability Configuration
```erlang
%%% Installs sinks
> File1 = logi_sink_file:new(file1, "/tmp/file1.log").
> File2 = logi_sink_file:new(file2, "/tmp/file2.log").
> Sink = logi_sink_ha:new(ha, [#{sink => File1}, #{sink => File2}], [{strategy, first_available}, {logger, null}]).
> {ok, _} = logi_channel:install_sink(Sink, info).
%%% Log messages
%% First available sink is `file1`
> logi:info("Hello").
> file:read_file("/tmp/file1.log").
{ok,<<"2016-05-09 13:55:38.410 [info] nonode@nohost <0.88.0> erl_eval:do_apply:674 [] Hello\n">>}
> file:read_file("/tmp/file2.log").
{ok,<<>>}
%% Removes permission of file1 and forces reopen
> file:change_mode("/tmp/file1.log", 0).
> exit(logi_channel:whereis_sink_proc([ha, file1]), kill).
%% Now, first available sink is `file2`
> logi:info("World!").
> file:read_file("/tmp/file2.log").
{ok,<<"2016-05-09 03:59:06.420 [info] nonode@nohost <0.88.0> erl_eval:do_apply:674 [] World!\n">>}
```
License
-------
This library is released under the MIT License.
See the [LICENSE](LICENSE) file for full license information.