blob: 148742fc7b9b8d134fd9238b33ef145daa9415cf [file] [log] [blame]
%% Copyright (c) 2011-2012 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 Lager's application module. Not a lot to see here.
%% @private
-module(lager_app).
-behaviour(application).
-include("lager.hrl").
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
-export([start/0,
start/2,
stop/1]).
start() ->
application:start(lager).
start(_StartType, _StartArgs) ->
{ok, Pid} = lager_sup:start_link(),
case application:get_env(lager, async_threshold) of
undefined ->
ok;
{ok, undefined} ->
undefined;
{ok, Threshold} when is_integer(Threshold), Threshold >= 0 ->
_ = supervisor:start_child(lager_handler_watcher_sup, [lager_event, lager_backend_throttle, Threshold]),
ok;
{ok, BadThreshold} ->
error_logger:error_msg("Invalid value for 'async_threshold': ~p~n", [BadThreshold]),
throw({error, bad_config})
end,
Handlers = case application:get_env(lager, handlers) of
undefined ->
[{lager_console_backend, info},
{lager_file_backend, [{"log/error.log", error, 10485760, "", 5},
{"log/console.log", info, 10485760, "", 5}]}];
{ok, Val} ->
Val
end,
%% handlers failing to start are handled in the handler_watcher
_ = [supervisor:start_child(lager_handler_watcher_sup, [lager_event, Module, Config]) ||
{Module, Config} <- expand_handlers(Handlers)],
ok = add_configured_traces(),
%% mask the messages we have no use for
lager:update_loglevel_config(),
HighWaterMark = case application:get_env(lager, error_logger_hwm) of
{ok, undefined} ->
undefined;
{ok, HwmVal} when is_integer(HwmVal), HwmVal > 0 ->
HwmVal;
{ok, BadVal} ->
_ = lager:log(warning, self(), "Invalid error_logger high water mark: ~p, disabling", [BadVal]),
undefined;
undefined ->
undefined
end,
SavedHandlers =
case application:get_env(lager, error_logger_redirect) of
{ok, false} ->
[];
_ ->
WhiteList = case application:get_env(lager, error_logger_whitelist) of
undefined ->
[];
{ok, WhiteList0} ->
WhiteList0
end,
case supervisor:start_child(lager_handler_watcher_sup, [error_logger, error_logger_lager_h, [HighWaterMark]]) of
{ok, _} ->
[begin error_logger:delete_report_handler(X), X end ||
X <- gen_event:which_handlers(error_logger) -- [error_logger_lager_h | WhiteList]];
{error, _} ->
[]
end
end,
lager_util:trace_filter(none),
{ok, Pid, SavedHandlers}.
stop(Handlers) ->
lists:foreach(fun(Handler) ->
error_logger:add_report_handler(Handler)
end, Handlers).
expand_handlers([]) ->
[];
expand_handlers([{lager_file_backend, [{Key, _Value}|_]=Config}|T]) when is_atom(Key) ->
%% this is definitely a new-style config, no expansion needed
[maybe_make_handler_id(lager_file_backend, Config) | expand_handlers(T)];
expand_handlers([{lager_file_backend, Configs}|T]) ->
?INT_LOG(notice, "Deprecated lager_file_backend config detected, please consider updating it", []),
[ {lager_file_backend:config_to_id(Config), Config} || Config <- Configs] ++
expand_handlers(T);
expand_handlers([{Mod, Config}|T]) when is_atom(Mod) ->
[maybe_make_handler_id(Mod, Config) | expand_handlers(T)];
expand_handlers([H|T]) ->
[H | expand_handlers(T)].
add_configured_traces() ->
Traces = case application:get_env(lager, traces) of
undefined ->
[];
{ok, TraceVal} ->
TraceVal
end,
lists:foreach(fun({Handler, Filter, Level}) ->
{ok, _} = lager:trace(Handler, Filter, Level)
end,
Traces),
ok.
maybe_make_handler_id(Mod, Config) ->
%% Allow the backend to generate a gen_event handler id, if it wants to.
%% We don't use erlang:function_exported here because that requires the module
%% already be loaded, which is unlikely at this phase of startup. Using code:load
%% caused undesireable side-effects with generating code-coverage reports.
try Mod:config_to_id(Config) of
Id ->
{Id, Config}
catch
error:undef ->
{Mod, Config}
end.
-ifdef(TEST).
application_config_mangling_test_() ->
[
{"Explode the file backend handlers",
?_assertMatch(
[{lager_console_backend, info},
{{lager_file_backend,"error.log"},{"error.log",error,10485760, "$D0",5}},
{{lager_file_backend,"console.log"},{"console.log",info,10485760, "$D0",5}}
],
expand_handlers([{lager_console_backend, info},
{lager_file_backend, [
{"error.log", error, 10485760, "$D0", 5},
{"console.log", info, 10485760, "$D0", 5}
]}]
))
},
{"Explode the short form of backend file handlers",
?_assertMatch(
[{lager_console_backend, info},
{{lager_file_backend,"error.log"},{"error.log",error}},
{{lager_file_backend,"console.log"},{"console.log",info}}
],
expand_handlers([{lager_console_backend, info},
{lager_file_backend, [
{"error.log", error},
{"console.log", info}
]}]
))
},
{"Explode with formatter info",
?_assertMatch(
[{{lager_file_backend,"test.log"}, [{"test.log", debug, 10485760, "$D0", 5},{lager_default_formatter,["[",severity,"] ", message, "\n"]}]},
{{lager_file_backend,"test2.log"}, [{"test2.log",debug, 10485760, "$D0", 5},{lager_default_formatter,["2>[",severity,"] ", message, "\n"]}]}],
expand_handlers([{lager_file_backend, [
[{"test.log", debug, 10485760, "$D0", 5},{lager_default_formatter,["[",severity,"] ", message, "\n"]}],
[{"test2.log",debug, 10485760, "$D0", 5},{lager_default_formatter,["2>[",severity,"] ",message, "\n"]}]
]
}])
)
},
{"Explode short form with short formatter info",
?_assertMatch(
[{{lager_file_backend,"test.log"}, [{"test.log", debug},{lager_default_formatter,["[",severity,"] ", message, "\n"]}]},
{{lager_file_backend,"test2.log"}, [{"test2.log",debug},{lager_default_formatter}]}],
expand_handlers([{lager_file_backend, [
[{"test.log", debug},{lager_default_formatter,["[",severity,"] ", message, "\n"]}],
[{"test2.log",debug},{lager_default_formatter}]
]
}])
)
},
{"New form needs no expansion",
?_assertMatch([
{{lager_file_backend,"test.log"}, [{file, "test.log"}]},
{{lager_file_backend,"test2.log"}, [{file, "test2.log"}, {level, info}, {sync_on, none}]},
{{lager_file_backend,"test3.log"}, [{formatter, lager_default_formatter}, {file, "test3.log"}]}
],
expand_handlers([
{lager_file_backend, [{file, "test.log"}]},
{lager_file_backend, [{file, "test2.log"}, {level, info}, {sync_on, none}]},
{lager_file_backend, [{formatter, lager_default_formatter},{file, "test3.log"}]}
])
)
}
].
-endif.