lager_graylog

Build Status

This application provides lager backends for sending log messages to Graylog over UDP or TCP, and the formatter module which spits out logs in GELF format.

Installation

This library is available on Hex. Just add it to your dependencies!

{deps, [
  {lager_graylog, "1.0.0"}
]}.

TCP backend

When you need a reliable log delivery, you can use the backend which connects to Graylog using TCP. This backend will also try to reconnect to Graylog indefinitely (with backoff) in case of connection failure.

To use it, just declare it in your lager config:

[{lager, [{handlers, [{lager_graylog_tcp_backend, [{host, "graylog-hostname"},
                                                   {port, 12201}]

}]}]}].

This backend accepts configuration options as a list of tuples with atom keys. The following options are supported:

UDP backend

If you care more about speed than reliability of delivery, you can use UDP-based backend.

To use it, just declare it in your lager config:

[{lager, [{handlers, [{lager_graylog_tcp_backend, [{host, "graylog-hostname"},
                                                   {port, 12201}]

}]}]}].

It accepts exactly the same set of options as TCP backend.

Chunking & compression

This backend currently doesn't support neither chunking nor compression. This means that too big log messages won't be probably received by Graylog due to packet fragmentation.

GELF formatter

The GELF formatter is implemented by the lager_graylog_gelf_formatter module. It formats log messages according to GELF version 1.1. The following fields are always included in the message:

Metadata

All metadata provided by lager in the log message will be included as additional fields (thus prefixed with _ in the GELF payload). There are a couple things worth mentioning here:

Below you can find the table showing how metadata values on the Erlang side map to the JSON values in the GELF message sent to Graylog:

type Erlang GELF
atom()atom"atom"
integer()2323
float()1.231.23
binary()<<"alice has a cat">>; <<1, 2, 3>>"<<\"alice has a cat\">>"; "<<1,2,3>>"
list()"alice has a cat"; [1, 2, 3]"\"alice has a cat\""; "[1,2,3]"
bitstring()<<1:3>>"<<1:3>>"
tuple(){1, 2, 3}"{1,2,3}"
map()#{alice => "has a cat"}"#{alice => \"has a cat\"}"
pid()<0.68.0>"<0.68.0>"
reference()#Ref<0.4168780290.2597847048.103549>"#Ref<0.4168780290.2597847048.103549>"

Configuration

The formatter expects configuration as a list of tuples with atom keys. The following options are supported (all of them are optional):

Example configuration:

[{metadata, all},
 {include_default_ts, false},
 {override_host, "my-chosen-hostname"},
 {on_encode_failure, "Encoding log message as GELF failed"}]

Contributing

Pull requests are most welcome. If you have any questions, bug reports or feature proposals just open an issue.

The project is developed using rebar3:

Any new piece of code should be reasonably tested and covered by type specs. And again, if you have any questions or are struggling with implementing a new feature, just open an issue and we'll try to help :slightly_smiling_face:.

License

Copyright 2018 Erlang Solutions

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.