148 lines
5.1 KiB
Erlang
148 lines
5.1 KiB
Erlang
%% Copyright (c) 2011-2012, 2014 Basho Technologies, Inc. All Rights Reserved.
|
|
%%
|
|
%% 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.
|
|
|
|
%% @doc Console backend for lager that mutes logs to the shell when
|
|
%% CT runs succeed. Configured with a single option, the loglevel
|
|
%% desired.
|
|
|
|
-module(cth_readable_lager_backend).
|
|
|
|
-behaviour(gen_event).
|
|
|
|
-export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2,
|
|
code_change/3]).
|
|
|
|
-record(state, {level :: {'mask', integer()},
|
|
out = user :: user | standard_error,
|
|
formatter :: atom(),
|
|
format_config :: any(),
|
|
colors=[] :: list()}).
|
|
|
|
%-include("lager.hrl").
|
|
-define(TERSE_FORMAT,[time, " ", color, "[", severity,"] ", message]).
|
|
-define(DEFAULT_FORMAT_CONFIG, ?TERSE_FORMAT ++ [eol()]).
|
|
-define(FORMAT_CONFIG_OFF, [{eol, eol()}]).
|
|
|
|
%% @private
|
|
init([Level]) when is_atom(Level) ->
|
|
init([{level, Level}]);
|
|
init([Level, true]) when is_atom(Level) -> % for backwards compatibility
|
|
init([{level, Level}, {formatter_config, ?FORMAT_CONFIG_OFF}]);
|
|
init([Level, false]) when is_atom(Level) -> % for backwards compatibility
|
|
init([{level, Level}]);
|
|
init(Options) when is_list(Options) ->
|
|
Colors = case application:get_env(lager, colored) of
|
|
{ok, true} ->
|
|
{ok, LagerColors} = application:get_env(lager, colors),
|
|
LagerColors;
|
|
_ -> []
|
|
end,
|
|
|
|
Level = get_option(level, Options, undefined),
|
|
%% edited out a bunch of console detection stuff, hopefully not breaking
|
|
try lager_util:config_to_mask(Level) of
|
|
L ->
|
|
[UseErr, Formatter, Config] =
|
|
[get_option(K, Options, Default) || {K, Default} <- [{use_stderr, false},
|
|
{formatter, lager_default_formatter},
|
|
{formatter_config, ?DEFAULT_FORMAT_CONFIG}]
|
|
],
|
|
Out = case UseErr of
|
|
false -> user;
|
|
true -> standard_error
|
|
end,
|
|
{ok, #state{level=L,
|
|
out=Out,
|
|
formatter=Formatter,
|
|
format_config=Config,
|
|
colors=Colors}}
|
|
catch
|
|
_:_ ->
|
|
{error, {fatal, bad_log_level}}
|
|
end;
|
|
init(Level) ->
|
|
init([Level,{lager_default_formatter,?TERSE_FORMAT ++ [eol()]}]).
|
|
|
|
get_option(K, Options, Default) ->
|
|
case lists:keyfind(K, 1, Options) of
|
|
{K, V} -> V;
|
|
false -> Default
|
|
end.
|
|
|
|
%% @private
|
|
handle_call(get_loglevel, #state{level=Level} = State) ->
|
|
{ok, Level, State};
|
|
handle_call({set_loglevel, Level}, State) ->
|
|
try lager_util:config_to_mask(Level) of
|
|
Levels ->
|
|
{ok, ok, State#state{level=Levels}}
|
|
catch
|
|
_:_ ->
|
|
{ok, {error, bad_log_level}, State}
|
|
end;
|
|
handle_call(_Request, State) ->
|
|
{ok, ok, State}.
|
|
|
|
%% @private
|
|
handle_event({log, Message},
|
|
#state{level=L,formatter=Formatter,format_config=FormatConfig,colors=Colors} = State) ->
|
|
case lager_util:is_loggable(Message, L, lager_console_backend) of
|
|
true ->
|
|
%% Handle multiple possible functions -- older lagers didn't
|
|
%% support colors, and we depend on the currently running lib.
|
|
Formatted = case erlang:function_exported(Formatter, format, 3) of
|
|
true ->
|
|
Formatter:format(Message,FormatConfig,Colors);
|
|
false ->
|
|
Formatter:format(Message,FormatConfig)
|
|
end,
|
|
%% lagger forwards in sync mode, and a call to error_logger makes
|
|
%% everything deadlock, so we gotta go async on the logging call.
|
|
%% We also need to do a call so that lager doesn't reforward the
|
|
%% event in an infinite loop.
|
|
Name = case erlang:function_exported(logger, module_info, 0) of
|
|
true -> cth_readable_logger;
|
|
false -> error_logger
|
|
end,
|
|
spawn(fun() -> gen_event:call(Name, cth_readable_failonly, {lager, Formatted}) end),
|
|
ct_logs:tc_log(default, Formatted, []),
|
|
{ok, State};
|
|
false ->
|
|
{ok, State}
|
|
end;
|
|
handle_event(_Event, State) ->
|
|
{ok, State}.
|
|
|
|
%% @private
|
|
handle_info(_Info, State) ->
|
|
{ok, State}.
|
|
|
|
%% @private
|
|
terminate(_Reason, _State) ->
|
|
ok.
|
|
|
|
%% @private
|
|
code_change(_OldVsn, State, _Extra) ->
|
|
{ok, State}.
|
|
|
|
eol() ->
|
|
case application:get_env(lager, colored) of
|
|
{ok, true} ->
|
|
"\e[0m\r\n";
|
|
_ ->
|
|
"\r\n"
|
|
end.
|