diff options
author | Evgeny Khramtsov <ekhramtsov@process-one.net> | 2019-10-25 11:44:04 +0300 |
---|---|---|
committer | Evgeny Khramtsov <ekhramtsov@process-one.net> | 2019-10-25 11:44:04 +0300 |
commit | e3962aea6e2b3a50e371a9e93c2cf161672598df (patch) | |
tree | f5e7afaf03b3e1a7b6c9cf9be2ed8ee365a1801f /src | |
parent | Limit result set of disco#items for mod_pubsub (diff) |
Use lager on OTP<22.0
This also lowers Erlang/OTP minimum version requirement back to 19.3
Diffstat (limited to 'src')
-rw-r--r-- | src/ejabberd.app.src.in | 2 | ||||
-rw-r--r-- | src/ejabberd.erl | 1 | ||||
-rw-r--r-- | src/ejabberd_app.erl | 2 | ||||
-rw-r--r-- | src/ejabberd_logger.erl | 202 |
4 files changed, 183 insertions, 24 deletions
diff --git a/src/ejabberd.app.src.in b/src/ejabberd.app.src.in index 7908ec101..f1d08b8c7 100644 --- a/src/ejabberd.app.src.in +++ b/src/ejabberd.app.src.in @@ -6,7 +6,7 @@ {modules, []}, {registered, []}, {applications, [kernel, stdlib, sasl, ssl]}, - {included_applications, [os_mon, mnesia, inets, p1_utils, fast_yaml, fast_tls, pkix, xmpp, cache_tab, eimp]}, + {included_applications, [os_mon, lager, mnesia, inets, p1_utils, fast_yaml, fast_tls, pkix, xmpp, cache_tab, eimp]}, {env, [{enabled_backends, [@enabled_backends@]}]}, {mod, {ejabberd_app, []}}]}. diff --git a/src/ejabberd.erl b/src/ejabberd.erl index 4758fd2f9..861714d26 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -49,6 +49,7 @@ stop() -> application:stop(ejabberd). halt() -> + application:stop(sasl), ejabberd_logger:flush(), erlang:halt(1, [{flush, true}]). diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index d777fd86e..7988077c0 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -84,6 +84,8 @@ start_included_apps() -> lists:foreach( fun(mnesia) -> ok; + (lager) -> + ok; (os_mon)-> ok; (App) -> diff --git a/src/ejabberd_logger.erl b/src/ejabberd_logger.erl index 916ca6fea..211099720 100644 --- a/src/ejabberd_logger.erl +++ b/src/ejabberd_logger.erl @@ -25,25 +25,33 @@ -module(ejabberd_logger). -compile({no_auto_import, [get/0]}). --include_lib("kernel/include/logger.hrl"). - %% API -export([start/0, get/0, set/1, get_log_path/0, flush/0]). -export([convert_loglevel/1, loglevels/0]). +-ifndef(LAGER). -export([progress_filter/2]). +-endif. %% Deprecated functions -export([restart/0, reopen_log/0, rotate_log/0]). -deprecated([{restart, 0}, {reopen_log, 0}, {rotate_log, 0}]). --type loglevel() :: none | logger:level(). +-type loglevel() :: none | emergency | alert | critical | + error | warning | notice | info | debug. -define(is_loglevel(L), ((L == none) or (L == emergency) or (L == alert) or (L == critical) or (L == error) or (L == warning) or (L == notice) or (L == info) or (L == debug))). +-spec restart() -> ok. +-spec reopen_log() -> ok. +-spec rotate_log() -> ok. +-spec get() -> loglevel(). +-spec set(0..5 | loglevel()) -> ok. +-spec flush() -> ok. + %%%=================================================================== %%% API %%%=================================================================== @@ -61,20 +69,6 @@ get_log_path() -> end end. --spec get_integer_env(atom(), T) -> T. -get_integer_env(Name, Default) -> - case application:get_env(ejabberd, Name) of - {ok, I} when is_integer(I), I>0 -> - I; - undefined -> - Default; - {ok, Junk} -> - ?LOG_ERROR("Wrong value for ~ts: ~p; " - "using ~p as a fallback", - [Name, Junk, Default]), - Default - end. - -spec loglevels() -> [loglevel(), ...]. loglevels() -> [none, emergency, alert, critical, error, warning, notice, info, debug]. @@ -87,11 +81,174 @@ convert_loglevel(3) -> warning; convert_loglevel(4) -> info; convert_loglevel(5) -> debug. +-spec get_integer_env(atom(), T) -> T. +get_integer_env(Name, Default) -> + case application:get_env(ejabberd, Name) of + {ok, I} when is_integer(I), I>=0 -> + I; + undefined -> + Default; + {ok, Junk} -> + error_logger:error_msg("wrong value for ~ts: ~p; " + "using ~p as a fallback~n", + [Name, Junk, Default]), + Default + end. + +-ifdef(LAGER). +-spec get_string_env(atom(), T) -> T. +get_string_env(Name, Default) -> + case application:get_env(ejabberd, Name) of + {ok, L} when is_list(L) -> + L; + undefined -> + Default; + {ok, Junk} -> + error_logger:error_msg("wrong value for ~ts: ~p; " + "using ~p as a fallback~n", + [Name, Junk, Default]), + Default + end. + -spec start() -> ok. start() -> start(info). --spec start(loglevel()) -> ok. +start(Level) -> + StartedApps = application:which_applications(5000), + case lists:keyfind(logger, 1, StartedApps) of + %% Elixir logger is started. We assume everything is in place + %% to use lager to Elixir logger bridge. + {logger, _, _} -> + error_logger:info_msg("Ignoring ejabberd logger options, using Elixir Logger.", []), + %% Do not start lager, we rely on Elixir Logger + do_start_for_logger(Level); + _ -> + do_start(Level) + end. + +do_start_for_logger(Level) -> + application:load(sasl), + application:set_env(sasl, sasl_error_logger, false), + application:load(lager), + application:set_env(lager, error_logger_redirect, false), + application:set_env(lager, error_logger_whitelist, ['Elixir.Logger.ErrorHandler']), + application:set_env(lager, crash_log, false), + application:set_env(lager, handlers, [{elixir_logger_backend, [{level, Level}]}]), + ejabberd:start_app(lager), + ok. + +do_start(Level) -> + application:load(sasl), + application:set_env(sasl, sasl_error_logger, false), + application:load(lager), + ConsoleLog = get_log_path(), + Dir = filename:dirname(ConsoleLog), + ErrorLog = filename:join([Dir, "error.log"]), + CrashLog = filename:join([Dir, "crash.log"]), + LogRotateDate = get_string_env(log_rotate_date, ""), + LogRotateSize = get_integer_env(log_rotate_size, 10*1024*1024), + LogRotateCount = get_integer_env(log_rotate_count, 1), + LogRateLimit = get_integer_env(log_rate_limit, 100), + ConsoleLevel = case get_lager_version() >= "3.6.0" of + true -> [{level, Level}]; + false -> Level + end, + application:set_env(lager, error_logger_hwm, LogRateLimit), + application:set_env( + lager, handlers, + [{lager_console_backend, ConsoleLevel}, + {lager_file_backend, [{file, ConsoleLog}, {level, Level}, {date, LogRotateDate}, + {count, LogRotateCount}, {size, LogRotateSize}]}, + {lager_file_backend, [{file, ErrorLog}, {level, error}, {date, LogRotateDate}, + {count, LogRotateCount}, {size, LogRotateSize}]}]), + application:set_env(lager, crash_log, CrashLog), + application:set_env(lager, crash_log_date, LogRotateDate), + application:set_env(lager, crash_log_size, LogRotateSize), + application:set_env(lager, crash_log_count, LogRotateCount), + ejabberd:start_app(lager), + lists:foreach(fun(Handler) -> + lager:set_loghwm(Handler, LogRateLimit) + end, gen_event:which_handlers(lager_event)). + +restart() -> + Level = ejabberd_option:loglevel(), + application:stop(lager), + start(Level). + +reopen_log() -> + ok. + +rotate_log() -> + catch lager_crash_log ! rotate, + lists:foreach( + fun({lager_file_backend, File}) -> + whereis(lager_event) ! {rotate, File}; + (_) -> + ok + end, gen_event:which_handlers(lager_event)). + +get() -> + Handlers = get_lager_handlers(), + lists:foldl(fun(lager_console_backend, _Acc) -> + lager:get_loglevel(lager_console_backend); + (elixir_logger_backend, _Acc) -> + lager:get_loglevel(elixir_logger_backend); + (_, Acc) -> + Acc + end, + none, Handlers). + +set(N) when is_integer(N), N>=0, N=<5 -> + set(convert_loglevel(N)); +set(Level) when ?is_loglevel(Level) -> + case get() of + Level -> + ok; + _ -> + ConsoleLog = get_log_path(), + lists:foreach( + fun({lager_file_backend, File} = H) when File == ConsoleLog -> + lager:set_loglevel(H, Level); + (lager_console_backend = H) -> + lager:set_loglevel(H, Level); + (elixir_logger_backend = H) -> + lager:set_loglevel(H, Level); + (_) -> + ok + end, get_lager_handlers()) + end, + case Level of + debug -> xmpp:set_config([{debug, true}]); + _ -> xmpp:set_config([{debug, false}]) + end. + +get_lager_handlers() -> + case catch gen_event:which_handlers(lager_event) of + {'EXIT',noproc} -> + []; + Result -> + Result + end. + +-spec get_lager_version() -> string(). +get_lager_version() -> + Apps = application:loaded_applications(), + case lists:keyfind(lager, 1, Apps) of + {_, _, Vsn} -> Vsn; + false -> "0.0.0" + end. + +flush() -> + application:stop(lager). + +-else. +-include_lib("kernel/include/logger.hrl"). + +-spec start() -> ok | {error, term()}. +start() -> + start(info). + start(Level) -> EjabberdLog = get_log_path(), Dir = filename:dirname(EjabberdLog), @@ -120,14 +277,14 @@ start(Level) -> end, case logger:add_handler(ejabberd_log, logger_std_h, #{level => all, - config => Config#{type => {file, EjabberdLog}}, + config => Config#{file => EjabberdLog}, formatter => {logger_formatter, FileFmtConfig}}) of ok -> ok; {error, {already_exist, _}} -> ok end, case logger:add_handler(error_log, logger_std_h, #{level => error, - config => Config#{type => {file, ErrorLog}}, + config => Config#{file => ErrorLog}, formatter => {logger_formatter, FileFmtConfig}}) of ok -> ok; {error, {already_exist, _}} -> ok @@ -167,12 +324,10 @@ reopen_log() -> rotate_log() -> ok. --spec get() -> loglevel(). get() -> #{level := Level} = logger:get_primary_config(), Level. --spec set(0..5 | loglevel()) -> ok. set(N) when is_integer(N), N>=0, N=<5 -> set(convert_loglevel(N)); set(Level) when ?is_loglevel(Level) -> @@ -188,7 +343,6 @@ set(Level) when ?is_loglevel(Level) -> end end. --spec flush() -> ok. flush() -> lists:foreach( fun(#{id := HandlerId, module := logger_std_h}) -> @@ -198,3 +352,5 @@ flush() -> (_) -> ok end, logger:get_handler_config()). + +-endif. |