riak_test/src/riak_test_lager_backend.erl

232 lines
7.7 KiB
Erlang
Raw Normal View History

2012-10-10 22:14:06 +00:00
%% -------------------------------------------------------------------
%%
%% Copyright (c) 2012 Basho Technologies, Inc.
%%
%% This file is provided to you 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.
%%
%% -------------------------------------------------------------------
2012-08-27 17:50:18 +00:00
%% @doc This lager backend keeps a buffer of logs in memory and returns them all
%% when the handler terminates.
-module(riak_test_lager_backend).
-behavior(gen_event).
2012-08-27 17:50:18 +00:00
%% gen_event callbacks
-export([init/1,
handle_call/2,
handle_event/2,
handle_info/2,
terminate/2,
code_change/3]).
-export([get_logs/0]).
2012-08-27 17:50:18 +00:00
%% holds the log messages for retreival on terminate
-record(state, {level, verbose, log = []}).
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-compile([{parse_transform, lager_transform}]).
-endif.
2012-08-30 20:58:49 +00:00
-include_lib("lager/include/lager.hrl").
-spec get_logs() -> [iolist()] | {error, term()}.
get_logs() ->
gen_event:call(lager_event, ?MODULE, get_logs, infinity).
2012-08-27 17:50:18 +00:00
-spec(init(integer()|atom()|[term()]) -> {ok, #state{}} | {error, atom()}).
%% @private
%% @doc Initializes the event handler
init(Level) when is_atom(Level) ->
init([Level, false]);
init([Level, Verbose]) ->
try parse_level(Level) of
Lvl ->
{ok, #state{level=Lvl, verbose=Verbose}}
catch
_:_ ->
{error, bad_log_level}
end.
2012-08-27 17:50:18 +00:00
2012-08-27 18:27:47 +00:00
-spec(handle_event(tuple(), #state{}) -> {ok, #state{}}).
2012-08-27 17:50:18 +00:00
%% @private
%% @doc handles the event, adding the log message to the gen_event's state.
%% this function attempts to handle logging events in both the simple tuple
%% and new record (introduced after lager 1.2.1) formats.
handle_event({log, Dest, Level, {Date, Time}, [LevelStr, Location, Message]}, %% lager 1.2.1
#state{level=L, verbose=Verbose, log = Logs} = State) when Level > L ->
case lists:member(riak_test_lager_backend, Dest) of
true ->
Log = case Verbose of
true ->
[Date, " ", Time, " ", LevelStr, Location, Message];
_ ->
[Time, " ", LevelStr, Message]
end,
{ok, State#state{log=[Log|Logs]}};
false ->
{ok, State}
end;
handle_event({log, Level, {Date, Time}, [LevelStr, Location, Message]}, %% lager 1.2.1
#state{level=LogLevel, verbose=Verbose, log = Logs} = State) when Level =< LogLevel ->
Log = case Verbose of
true ->
[Date, " ", Time, " ", LevelStr, Location, Message];
_ ->
[Time, " ", LevelStr, Message]
end,
{ok, State#state{log=[Log|Logs]}};
handle_event({log, Msg},
#state{level=Level, verbose=Verbose, log = Logs} = State) -> %% lager 2.0.0
case lager_util:is_loggable(Msg, Level, ?MODULE) of
true ->
Format = log_format(Verbose),
Log = lager_default_formatter:format(Msg, Format),
{ok, State#state{log=[Log|Logs]}};
false ->
{ok, State}
end;
handle_event(Event, State) ->
{ok, State#state{log = [Event|State#state.log]}}.
2012-08-27 18:27:47 +00:00
-spec(handle_call(any(), #state{}) -> {ok, any(), #state{}}).
2012-08-27 17:50:18 +00:00
%% @private
%% @doc gets and sets loglevel. This is part of the lager backend api.
handle_call(get_loglevel, #state{level=Level} = State) ->
{ok, Level, State};
handle_call({set_loglevel, Level}, State) ->
try parse_level(Level) of
Lvl ->
{ok, ok, State#state{level=Lvl}}
catch
_:_ ->
{ok, {error, bad_log_level}, State}
end;
handle_call(get_logs, #state{log = Logs} = State) ->
{ok, Logs, State};
handle_call(_, State) ->
{ok, ok, State}.
2012-08-27 17:50:18 +00:00
-spec(handle_info(any(), #state{}) -> {ok, #state{}}).
%% @private
%% @doc gen_event callback, does nothing.
handle_info(_, State) ->
{ok, State}.
2012-08-27 17:50:18 +00:00
-spec(code_change(any(), #state{}, any()) -> {ok, #state{}}).
%% @private
%% @doc gen_event callback, does nothing.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
2012-08-27 17:50:18 +00:00
-spec(terminate(any(), #state{}) -> {ok, list()}).
%% @doc gen_event callback, does nothing.
terminate(_Reason, #state{log=Logs}) ->
{ok, lists:reverse(Logs)}.
parse_level(Level) ->
try lager_util:config_to_mask(Level) of
Res ->
Res
catch
error:undef ->
%% must be lager < 2.0
lager_util:level_to_num(Level)
end.
log_format(true) ->
[date, " " , time, " [", severity, "] ",
{pid, ""},
{module, [
module,
{function, [":", function], ""},
{line, [":", line], ""},
" "], ""},
message, "\r\n"];
log_format(false) ->
[time, " [", severity, "] ", message, "\r\n"].
-ifdef(TEST).
log_test_() ->
{foreach,
fun() ->
error_logger:tty(false),
application:load(lager),
application:set_env(lager, handlers, [{riak_test_lager_backend, debug}]),
application:set_env(lager, error_logger_redirect, false),
lager:start()
end,
fun(_) ->
application:stop(lager),
error_logger:tty(true)
end,
[
{"Test logging",
fun() ->
lager:info("Here's a message"),
lager:debug("Here's another message"),
{ok, Logs} = gen_event:delete_handler(lager_event, riak_test_lager_backend, []),
?assertEqual(3, length(Logs)),
?assertMatch([_, "[debug]", "Lager installed handler riak_test_lager_backend into lager_event"], re:split(lists:nth(1, Logs), " ", [{return, list}, {parts, 3}])),
?assertMatch([_, "[info]", "Here's a message"], re:split(lists:nth(2, Logs), " ", [{return, list}, {parts, 3}])),
?assertMatch([_, "[debug]", "Here's another message"], re:split(lists:nth(3, Logs), " ", [{return, list}, {parts, 3}]))
end
}
]
}.
set_loglevel_test_() ->
{foreach,
fun() ->
error_logger:tty(false),
application:load(lager),
application:set_env(lager, handlers, [{riak_test_lager_backend, info}]),
application:set_env(lager, error_logger_redirect, false),
lager:start()
end,
fun(_) ->
application:stop(lager),
error_logger:tty(true)
end,
[
{"Get/set loglevel test",
fun() ->
?assertEqual(info, lager:get_loglevel(riak_test_lager_backend)),
lager:set_loglevel(riak_test_lager_backend, debug),
?assertEqual(debug, lager:get_loglevel(riak_test_lager_backend))
end
},
{"Get/set invalid loglevel test",
fun() ->
?assertEqual(info, lager:get_loglevel(riak_test_lager_backend)),
?assertEqual({error, bad_log_level},
lager:set_loglevel(riak_test_lager_backend, fatfinger)),
?assertEqual(info, lager:get_loglevel(riak_test_lager_backend))
end
}
]
}.
2012-08-30 20:58:49 +00:00
-endif.