Packages

lager backends sending log messages to Graylog

Current section

Files

Jump to
lager_graylog src lager_graylog_udp_backend.erl
Raw

src/lager_graylog_udp_backend.erl

-module(lager_graylog_udp_backend).
-behaviour(gen_event).
-export([init/1]).
-export([handle_call/2]).
-export([handle_event/2]).
-export([handle_info/2]).
-export([terminate/2]).
-export([code_change/3]).
-type name() :: {?MODULE, {lager_graylog:host(), lager_graylog:port_number()}}.
-type socket() :: gen_udp:socket().
-type state() :: #{name := name(),
level := lager_graylog_utils:mask(),
host := lager_graylog:host(),
port := lager_graylog:port_number(),
socket := socket(),
formatter := module(),
formatter_config := any()}.
%% gen_event callbacks
-spec init([lager_graylog:backend_option()]) ->
{ok, state()} | {error, {invalid_opts | gen_udp_open_failed, term()}}.
init(Opts) ->
case lager_graylog_utils:parse_common_opts(Opts) of
{ok, Config} ->
open_socket_and_init_state(Config);
{error, Reason} ->
{error, {invalid_opts, Reason}}
end.
handle_call({set_loglevel, Level}, State) ->
case lager_graylog_utils:validate_loglevel(Level) of
error ->
{ok, {error, bad_loglevel}, State};
{ok, Mask} ->
{ok, ok, State#{level => Mask}}
end;
handle_call(get_loglevel, #{level := Level} = State) ->
{ok, Level, State};
handle_call(_Request, State) ->
{ok, ok, State}.
handle_event({log, Message}, #{name := Name,
level := Mask,
host := Host,
port := Port,
socket := Socket,
formatter := Formatter,
formatter_config := FormatterConfig} = State) ->
case lager_util:is_loggable(Message, Mask, Name) of
true ->
FormattedLog = Formatter:format(Message, FormatterConfig),
gen_udp:send(Socket, Host, Port, FormattedLog);
false ->
ok
end,
{ok, State}.
handle_info(_, State) ->
{ok, State}.
terminate(_Arg, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% Helpers
-spec open_socket_and_init_state(lager_graylog_utils:common_config()) ->
{ok, state()} | {error, {gen_udp_open_failed, term()}}.
open_socket_and_init_state(Config) ->
#{level := Mask,
host := Host,
port := Port,
address_family := AddressFamily,
formatter := Formatter,
formatter_config := FormatterConfig} = Config,
case gen_udp:open(0, [binary, {active, false} | extra_open_opts(AddressFamily)]) of
{ok, Socket} ->
State = #{name => {?MODULE, {Host, Port}},
level => Mask,
host => Host,
port => Port,
socket => Socket,
formatter => Formatter,
formatter_config => FormatterConfig},
{ok, State};
{error, Reason} ->
{error, {gen_udp_open_failed, Reason}}
end.
-spec extra_open_opts(lager_graylog:address_family()) -> [inet:address_family()].
extra_open_opts(undefined) -> [];
extra_open_opts(inet) -> [inet];
extra_open_opts(inet6) -> [inet6].