25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-20 16:15:59 +01:00

Replace lager with built-in new logging API

This change requires Erlang/OTP-21.0 or higher.
The commit also deprecates the following options:
  - log_rotate_date
  - log_rate_limit

Furthermore, these options have no effect. The logger now fully
relies on log_rotate_size, that cannot be 0 anymore.

The loglevel option now accepts levels in literal formats.
Those are: none, emergency, alert, critical, error, warning, notice, info, debug.
Old integer values (0-5) are still supported and automatically converted
into literal format.
This commit is contained in:
Evgeny Khramtsov 2019-10-18 19:12:32 +03:00
parent b1d458999a
commit e4a8afb15d
18 changed files with 175 additions and 274 deletions

View File

@ -1,9 +1,8 @@
language: erlang language: erlang
otp_release: otp_release:
- 19.3 - 21.0
- 20.3 - 22.1
- 21.2
services: services:
- redis-server - redis-server

View File

@ -107,7 +107,7 @@ To compile ejabberd you need:
- GCC. - GCC.
- Libexpat ≥ 1.95. - Libexpat ≥ 1.95.
- Libyaml ≥ 0.1.4. - Libyaml ≥ 0.1.4.
- Erlang/OTP ≥ 19.1. - Erlang/OTP ≥ 21.0.
- OpenSSL ≥ 1.0.0. - OpenSSL ≥ 1.0.0.
- Zlib ≥ 1.2.3, for Stream Compression support (XEP-0138). Optional. - Zlib ≥ 1.2.3, for Stream Compression support (XEP-0138). Optional.
- PAM library. Optional. For Pluggable Authentication Modules (PAM). - PAM library. Optional. For Pluggable Authentication Modules (PAM).

View File

@ -3,7 +3,7 @@
AC_PREREQ(2.53) AC_PREREQ(2.53)
AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 0.0` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd]) AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 0.0` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
REQUIRE_ERLANG_MIN="8.1 (Erlang/OTP 19.1)" REQUIRE_ERLANG_MIN="10.0 (Erlang/OTP 21.0)"
REQUIRE_ERLANG_MAX="100.0.0 (No Max)" REQUIRE_ERLANG_MAX="100.0.0 (No Max)"
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])

View File

@ -17,11 +17,7 @@
hosts: hosts:
- localhost - localhost
loglevel: 4 loglevel: info
log_rotate_size: 10485760
log_rotate_date: ""
log_rotate_count: 1
log_rate_limit: 100
## If you already have certificates, list them here ## If you already have certificates, list them here
# certfiles: # certfiles:

View File

@ -17,24 +17,24 @@
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. %%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%% %%%
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
-include_lib("kernel/include/logger.hrl").
-define(PRINT(Format, Args), io:format(Format, Args)). -define(PRINT(Format, Args), io:format(Format, Args)).
-compile([{parse_transform, lager_transform}]).
-define(DEBUG(Format, Args), -define(DEBUG(Format, Args),
begin lager:debug(Format, Args), ok end). begin ?LOG_DEBUG(Format, Args), ok end).
-define(INFO_MSG(Format, Args), -define(INFO_MSG(Format, Args),
begin lager:info(Format, Args), ok end). begin ?LOG_INFO(Format, Args), ok end).
-define(WARNING_MSG(Format, Args), -define(WARNING_MSG(Format, Args),
begin lager:warning(Format, Args), ok end). begin ?LOG_WARNING(Format, Args), ok end).
-define(ERROR_MSG(Format, Args), -define(ERROR_MSG(Format, Args),
begin lager:error(Format, Args), ok end). begin ?LOG_ERROR(Format, Args), ok end).
-define(CRITICAL_MSG(Format, Args), -define(CRITICAL_MSG(Format, Args),
begin lager:critical(Format, Args), ok end). begin ?LOG_CRITICAL(Format, Args), ok end).
%% Use only when trying to troubleshoot test problem with ExUnit %% Use only when trying to troubleshoot test problem with ExUnit
-define(EXUNIT_LOG(Format, Args), -define(EXUNIT_LOG(Format, Args),

View File

@ -18,8 +18,7 @@
%%% %%%
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
{deps, [{lager, ".*", {git, "https://github.com/erlang-lager/lager", "3.6.10"}}, {deps, [{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.16"}}},
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.16"}}},
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.20"}}}, {cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.20"}}},
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.1.2"}}}, {fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.1.2"}}},
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.17"}}}, {stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.17"}}},

View File

@ -6,7 +6,7 @@
{modules, []}, {modules, []},
{registered, []}, {registered, []},
{applications, [kernel, stdlib, sasl, ssl]}, {applications, [kernel, stdlib, sasl, ssl]},
{included_applications, [os_mon, lager, mnesia, inets, p1_utils, fast_yaml, fast_tls, pkix, xmpp, cache_tab, eimp]}, {included_applications, [os_mon, mnesia, inets, p1_utils, fast_yaml, fast_tls, pkix, xmpp, cache_tab, eimp]},
{env, [{enabled_backends, [@enabled_backends@]}]}, {env, [{enabled_backends, [@enabled_backends@]}]},
{mod, {ejabberd_app, []}}]}. {mod, {ejabberd_app, []}}]}.

View File

@ -49,8 +49,7 @@ stop() ->
application:stop(ejabberd). application:stop(ejabberd).
halt() -> halt() ->
_ = application:stop(lager), ejabberd_logger:flush(),
_ = application:stop(sasl),
erlang:halt(1, [{flush, true}]). erlang:halt(1, [{flush, true}]).
%% @spec () -> false | string() %% @spec () -> false | string()

View File

@ -142,20 +142,16 @@ get_commands_spec() ->
desc = "Get the current loglevel", desc = "Get the current loglevel",
module = ejabberd_logger, function = get, module = ejabberd_logger, function = get,
result_desc = "Tuple with the log level number, its keyword and description", result_desc = "Tuple with the log level number, its keyword and description",
result_example = {4, info, <<"Info">>}, result_example = warning,
args = [], args = [],
result = {leveltuple, {tuple, [{levelnumber, integer}, result = {levelatom, atom}},
{levelatom, atom},
{leveldesc, string}
]}}},
#ejabberd_commands{name = set_loglevel, tags = [logs, server], #ejabberd_commands{name = set_loglevel, tags = [logs, server],
desc = "Set the loglevel (0 to 5)", desc = "Set the loglevel",
module = ?MODULE, function = set_loglevel, module = ?MODULE, function = set_loglevel,
args_desc = ["Integer of the desired logging level, between 1 and 5"], args_desc = ["Desired logging level: none | emergency | alert | critical "
args_example = [5], "| error | warning | notice | info | debug"],
result_desc = "The type of logger module used", args_example = [debug],
result_example = lager, args = [{loglevel, string}],
args = [{loglevel, integer}],
result = {res, rescode}}, result = {res, rescode}},
#ejabberd_commands{name = update_list, tags = [server], #ejabberd_commands{name = update_list, tags = [server],
@ -410,15 +406,23 @@ status() ->
{Is_running, String1 ++ String2}. {Is_running, String1 ++ String2}.
reopen_log() -> reopen_log() ->
ejabberd_hooks:run(reopen_log_hook, []), ejabberd_hooks:run(reopen_log_hook, []).
ejabberd_logger:reopen_log().
rotate_log() -> rotate_log() ->
ejabberd_hooks:run(rotate_log_hook, []), ejabberd_hooks:run(rotate_log_hook, []).
ejabberd_logger:rotate_log().
set_loglevel(LogLevel) -> set_loglevel(LogLevel) ->
ejabberd_logger:set(LogLevel). try binary_to_existing_atom(iolist_to_binary(LogLevel), latin1) of
Level ->
case lists:member(Level, ejabberd_logger:loglevels()) of
true ->
ejabberd_logger:set(Level);
false ->
{error, "Invalid log level"}
end
catch _:_ ->
{error, "Invalid log level"}
end.
%%% %%%
%%% Stop Kindly %%% Stop Kindly

View File

@ -84,8 +84,6 @@ start_included_apps() ->
lists:foreach( lists:foreach(
fun(mnesia) -> fun(mnesia) ->
ok; ok;
(lager)->
ok;
(os_mon)-> (os_mon)->
ok; ok;
(App) -> (App) ->

View File

@ -522,7 +522,7 @@ read_erlang_file(File, _) ->
validate(Y1) -> validate(Y1) ->
case pre_validate(Y1) of case pre_validate(Y1) of
{ok, Y2} -> {ok, Y2} ->
set_loglevel(proplists:get_value(loglevel, Y2, 4)), set_loglevel(proplists:get_value(loglevel, Y2, info)),
case ejabberd_config_transformer:map_reduce(Y2) of case ejabberd_config_transformer:map_reduce(Y2) of
{ok, Y3} -> {ok, Y3} ->
Hosts = proplists:get_value(hosts, Y3), Hosts = proplists:get_value(hosts, Y3),
@ -763,7 +763,7 @@ set_shared_key() ->
set_node_start(UnixTime) -> set_node_start(UnixTime) ->
set_option(node_start, UnixTime). set_option(node_start, UnixTime).
-spec set_loglevel(0..5) -> ok. -spec set_loglevel(logger:level()) -> ok.
set_loglevel(Level) -> set_loglevel(Level) ->
ejabberd_logger:set(Level). ejabberd_logger:set(Level).

View File

@ -30,12 +30,6 @@ map_reduce(Y) ->
F = fun(Y1) -> F = fun(Y1) ->
Y2 = (validator())(Y1), Y2 = (validator())(Y1),
Y3 = transform(Y2), Y3 = transform(Y2),
if Y2 /= Y3 ->
?DEBUG("Transformed configuration:~ts~n",
[misc:format_val({yaml, Y3})]);
true ->
ok
end,
Y3 Y3
end, end,
econf:validate(F, Y). econf:validate(F, Y).
@ -148,6 +142,12 @@ filter(Host, Y, Acc) ->
filter(Host, Opt, Val, Acc) filter(Host, Opt, Val, Acc)
end, Y). end, Y).
filter(_Host, log_rotate_date, _, _) ->
warn_removed_option(log_rotate_date),
false;
filter(_Host, log_rate_limit, _, _) ->
warn_removed_option(log_rate_limit),
false;
filter(_Host, ca_path, _, _) -> filter(_Host, ca_path, _, _) ->
warn_removed_option(ca_path, ca_file), warn_removed_option(ca_path, ca_file),
false; false;

View File

@ -68,6 +68,7 @@
%%----------------------------- %%-----------------------------
start() -> start() ->
logger:set_primary_config(level, none),
[SNode, Timeout, Args] = case init:get_plain_arguments() of [SNode, Timeout, Args] = case init:get_plain_arguments() of
[SNode2, "--no-timeout" | Args2] -> [SNode2, "--no-timeout" | Args2] ->
[SNode2, infinity, Args2]; [SNode2, infinity, Args2];

View File

@ -23,34 +23,30 @@
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
-module(ejabberd_logger). -module(ejabberd_logger).
-compile({no_auto_import, [get/0]}).
-include_lib("kernel/include/logger.hrl").
%% API %% API
-export([start/0, restart/0, reopen_log/0, rotate_log/0, get/0, set/1, -export([start/0, get/0, set/1, get_log_path/0, flush/0]).
get_log_path/0]). -export([convert_loglevel/1, loglevels/0]).
%% 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() :: 0 | 1 | 2 | 3 | 4 | 5. -define(is_loglevel(L),
-type lager_level() :: none | emergency | alert | critical | ((L == none) or (L == emergency) or (L == alert)
error | warning | notice | info | debug. or (L == critical) or (L == error) or (L == warning)
or (L == notice) or (L == info) or (L == debug))).
-spec start() -> ok.
-spec get_log_path() -> string().
-spec reopen_log() -> ok.
-spec rotate_log() -> ok.
-spec get() -> {loglevel(), atom(), string()}.
-spec set(loglevel()) -> ok.
%%%=================================================================== %%%===================================================================
%%% API %%% API
%%%=================================================================== %%%===================================================================
%% @doc Returns the full path to the ejabberd log file. -spec get_log_path() -> string().
%% It first checks for application configuration parameter 'log_path'.
%% If not defined it checks the environment variable EJABBERD_LOG_PATH.
%% And if that one is neither defined, returns the default value:
%% "ejabberd.log" in current directory.
%% Note: If the directory where to place the ejabberd log file to not exist,
%% it is not created and no log file will be generated.
%% @spec () -> string()
get_log_path() -> get_log_path() ->
case ejabberd_config:env_binary_to_list(ejabberd, log_path) of case ejabberd_config:env_binary_to_list(ejabberd, log_path) of
{ok, Path} -> {ok, Path} ->
@ -64,186 +60,113 @@ get_log_path() ->
end end
end. end.
-spec get_integer_env(atom(), T) -> T.
get_integer_env(Name, Default) -> get_integer_env(Name, Default) ->
case application:get_env(ejabberd, Name) of case application:get_env(ejabberd, Name) of
{ok, I} when is_integer(I), I>=0 -> {ok, I} when is_integer(I), I>0 ->
I; I;
undefined -> undefined ->
Default; Default;
{ok, Junk} -> {ok, Junk} ->
error_logger:error_msg("wrong value for ~ts: ~p; " ?LOG_ERROR("Wrong value for ~ts: ~p; "
"using ~p as a fallback~n", "using ~p as a fallback",
[Name, Junk, Default]), [Name, Junk, Default]),
Default
end.
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 Default
end. end.
%% @spec () -> ok -spec loglevels() -> [loglevel(), ...].
loglevels() ->
[none, emergency, alert, critical, error, warning, notice, info, debug].
-spec convert_loglevel(0..5) -> loglevel().
convert_loglevel(0) -> none;
convert_loglevel(1) -> critical;
convert_loglevel(2) -> error;
convert_loglevel(3) -> warning;
convert_loglevel(4) -> info;
convert_loglevel(5) -> debug.
-spec start() -> ok.
start() -> start() ->
start(4). start(info).
-spec start(loglevel()) -> ok. -spec start(loglevel()) -> ok.
start(Level) -> start(Level) ->
LLevel = get_lager_loglevel(Level), EjabberdLog = get_log_path(),
StartedApps = application:which_applications(5000), Dir = filename:dirname(EjabberdLog),
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(LLevel);
_ ->
do_start(LLevel)
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.
-spec do_start(atom()) -> 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"]), 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), LogRotateSize = get_integer_env(log_rotate_size, 10*1024*1024),
LogRotateCount = get_integer_env(log_rotate_count, 1), LogRotateCount = get_integer_env(log_rotate_count, 1),
LogRateLimit = get_integer_env(log_rate_limit, 100), Config = #{max_no_bytes => LogRotateSize,
ConsoleLevel = case get_lager_version() >= "3.6.0" of max_no_files => LogRotateCount,
true -> [{level, Level}]; filesync_repeat_interval => no_repeat,
false -> Level sync_mode_qlen => 1000,
end, drop_mode_qlen => 1000,
application:set_env(lager, error_logger_hwm, LogRateLimit), flush_qlen => 5000},
application:set_env( FmtConfig = #{legacy_header => false,
lager, handlers, time_designator => $ ,
[{lager_console_backend, ConsoleLevel}, max_size => 100*1024,
{lager_file_backend, [{file, ConsoleLog}, {level, Level}, {date, LogRotateDate}, single_line => false},
{count, LogRotateCount}, {size, LogRotateSize}]}, FileFmtConfig = FmtConfig#{template => file_template()},
{lager_file_backend, [{file, ErrorLog}, {level, error}, {date, LogRotateDate}, ConsoleFmtConfig = FmtConfig#{template => console_template()},
{count, LogRotateCount}, {size, LogRotateSize}]}]), logger:set_primary_config(level, Level),
application:set_env(lager, crash_log, CrashLog), logger:add_primary_filter(progress_report,
application:set_env(lager, crash_log_date, LogRotateDate), {fun logger_filters:progress/2, stop}),
application:set_env(lager, crash_log_size, LogRotateSize), logger:update_formatter_config(default, ConsoleFmtConfig),
application:set_env(lager, crash_log_count, LogRotateCount), logger:add_handler(ejabberd_log, logger_std_h,
ejabberd:start_app(lager), #{level => all,
lists:foreach(fun(Handler) -> config => Config#{file => EjabberdLog},
lager:set_loghwm(Handler, LogRateLimit) formatter => {logger_formatter, FileFmtConfig}}),
end, gen_event:which_handlers(lager_event)). logger:add_handler(error_log, logger_std_h,
#{level => error,
restart() -> config => Config#{file => ErrorLog},
Level = ejabberd_option:loglevel(), formatter => {logger_formatter, FileFmtConfig}}),
application:stop(lager), ok.
start(Level).
restart() ->
%% @spec () -> ok ok.
reopen_log() ->
%% Lager detects external log rotation automatically. console_template() ->
[time, " [", level, "] ", msg, io_lib:nl()].
file_template() ->
[time, " [", level, "] ", pid,
{mfa, ["@", mfa, {line, [":", line], []}], []}, " ", msg, io_lib:nl()].
reopen_log() ->
ok. ok.
%% @spec () -> ok
rotate_log() -> rotate_log() ->
catch lager_crash_log ! rotate, ok.
lists:foreach(
fun({lager_file_backend, File}) ->
whereis(lager_event) ! {rotate, File};
(_) ->
ok
end, gen_event:which_handlers(lager_event)).
%% @spec () -> {loglevel(), atom(), string()} -spec get() -> loglevel().
get() -> get() ->
case get_lager_loglevel() of #{level := Level} = logger:get_primary_config(),
none -> {0, no_log, "No log"}; Level.
emergency -> {1, critical, "Critical"};
alert -> {1, critical, "Critical"}; -spec set(0..5 | loglevel()) -> ok.
critical -> {1, critical, "Critical"}; set(N) when is_integer(N), N>=0, N=<5 ->
error -> {2, error, "Error"}; set(convert_loglevel(N));
warning -> {3, warning, "Warning"}; set(Level) when ?is_loglevel(Level) ->
notice -> {3, warning, "Warning"}; case get() of
info -> {4, info, "Info"}; Level -> ok;
debug -> {5, debug, "Debug"} PrevLevel ->
?LOG_NOTICE("Changing loglevel from '~s' to '~s'",
[PrevLevel, Level]),
logger:set_primary_config(level, Level),
case Level of
debug -> xmpp:set_config([{debug, true}]);
_ -> xmpp:set_config([{debug, false}])
end
end. end.
set(LogLevel) when is_integer(LogLevel) -> -spec flush() -> ok.
LagerLogLevel = get_lager_loglevel(LogLevel), flush() ->
case get_lager_loglevel() of lists:foreach(
LagerLogLevel -> fun(#{id := HandlerId, module := logger_std_h}) ->
ok; logger_std_h:filesync(HandlerId);
_ -> (#{id := HandlerId, module := logger_disk_log_h}) ->
ConsoleLog = get_log_path(), logger_disk_log_h:filesync(HandlerId);
lists:foreach( (_) ->
fun({lager_file_backend, File} = H) when File == ConsoleLog -> ok
lager:set_loglevel(H, LagerLogLevel); end, logger:get_handler_config()).
(lager_console_backend = H) ->
lager:set_loglevel(H, LagerLogLevel);
(elixir_logger_backend = H) ->
lager:set_loglevel(H, LagerLogLevel);
(_) ->
ok
end, get_lager_handlers())
end,
case LogLevel of
5 -> xmpp:set_config([{debug, true}]);
_ -> xmpp:set_config([{debug, false}])
end.
get_lager_loglevel() ->
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).
-spec get_lager_loglevel(loglevel()) -> lager_level().
get_lager_loglevel(LogLevel) ->
case LogLevel of
0 -> none;
1 -> critical;
2 -> error;
3 -> warning;
4 -> info;
5 -> debug
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.

View File

@ -69,9 +69,7 @@
-export([ldap_tls_verify/0, ldap_tls_verify/1]). -export([ldap_tls_verify/0, ldap_tls_verify/1]).
-export([ldap_uids/0, ldap_uids/1]). -export([ldap_uids/0, ldap_uids/1]).
-export([listen/0]). -export([listen/0]).
-export([log_rate_limit/0]).
-export([log_rotate_count/0]). -export([log_rotate_count/0]).
-export([log_rotate_date/0]).
-export([log_rotate_size/0]). -export([log_rotate_size/0]).
-export([loglevel/0]). -export([loglevel/0]).
-export([max_fsm_queue/0, max_fsm_queue/1]). -export([max_fsm_queue/0, max_fsm_queue/1]).
@ -556,23 +554,15 @@ ldap_uids(Host) ->
listen() -> listen() ->
ejabberd_config:get_option({listen, global}). ejabberd_config:get_option({listen, global}).
-spec log_rate_limit() -> 'undefined' | non_neg_integer(). -spec log_rotate_count() -> non_neg_integer().
log_rate_limit() ->
ejabberd_config:get_option({log_rate_limit, global}).
-spec log_rotate_count() -> 'undefined' | non_neg_integer().
log_rotate_count() -> log_rotate_count() ->
ejabberd_config:get_option({log_rotate_count, global}). ejabberd_config:get_option({log_rotate_count, global}).
-spec log_rotate_date() -> 'undefined' | string(). -spec log_rotate_size() -> 'infinity' | pos_integer().
log_rotate_date() ->
ejabberd_config:get_option({log_rotate_date, global}).
-spec log_rotate_size() -> 'undefined' | non_neg_integer().
log_rotate_size() -> log_rotate_size() ->
ejabberd_config:get_option({log_rotate_size, global}). ejabberd_config:get_option({log_rotate_size, global}).
-spec loglevel() -> 0 | 1 | 2 | 3 | 4 | 5. -spec loglevel() -> 'none' | logger:level().
loglevel() -> loglevel() ->
ejabberd_config:get_option({loglevel, global}). ejabberd_config:get_option({loglevel, global}).

View File

@ -198,18 +198,19 @@ opt_type(ldap_uids) ->
econf:map(econf:binary(), econf:binary(), [unique])); econf:map(econf:binary(), econf:binary(), [unique]));
opt_type(listen) -> opt_type(listen) ->
ejabberd_listener:validator(); ejabberd_listener:validator();
opt_type(log_rate_limit) ->
econf:non_neg_int();
opt_type(log_rotate_count) -> opt_type(log_rotate_count) ->
econf:non_neg_int(); econf:non_neg_int();
opt_type(log_rotate_date) ->
econf:string("^(\\$((D(([0-9])|(1[0-9])|(2[0-3])))|"
"(((W[0-6])|(M(([1-2][0-9])|(3[0-1])|([1-9]))))"
"(D(([0-9])|(1[0-9])|(2[0-3])))?)))?$");
opt_type(log_rotate_size) -> opt_type(log_rotate_size) ->
econf:non_neg_int(); econf:pos_int(infinity);
opt_type(loglevel) -> opt_type(loglevel) ->
econf:int(0, 5); fun(N) when is_integer(N) ->
(econf:and_then(
econf:int(0, 5),
fun ejabberd_logger:convert_loglevel/1))(N);
(Level) ->
(econf:enum([none, emergency, alert, critical,
error, warning, notice, info, debug]))(Level)
end;
opt_type(max_fsm_queue) -> opt_type(max_fsm_queue) ->
econf:pos_int(); econf:pos_int();
opt_type(modules) -> opt_type(modules) ->
@ -424,6 +425,7 @@ opt_type(jwt_auth_only_rule) ->
{websocket_origin, [binary()]} | {websocket_origin, [binary()]} |
{disable_sasl_mechanisms, [binary()]} | {disable_sasl_mechanisms, [binary()]} |
{s2s_zlib, boolean()} | {s2s_zlib, boolean()} |
{loglevel, none | logger:level()} |
{listen, [ejabberd_listener:listener()]} | {listen, [ejabberd_listener:listener()]} |
{modules, [{module(), gen_mod:opts(), integer()}]} | {modules, [{module(), gen_mod:opts(), integer()}]} |
{ldap_uids, [{binary(), binary()}]} | {ldap_uids, [{binary(), binary()}]} |
@ -443,7 +445,7 @@ opt_type(jwt_auth_only_rule) ->
options() -> options() ->
[%% Top-priority options [%% Top-priority options
hosts, hosts,
{loglevel, 4}, {loglevel, info},
{cache_life_time, timer:seconds(3600)}, {cache_life_time, timer:seconds(3600)},
{cache_missed, true}, {cache_missed, true},
{cache_size, 1000}, {cache_size, 1000},
@ -527,10 +529,8 @@ options() ->
{ldap_tls_verify, false}, {ldap_tls_verify, false},
{ldap_uids, [{<<"uid">>, <<"%u">>}]}, {ldap_uids, [{<<"uid">>, <<"%u">>}]},
{listen, []}, {listen, []},
{log_rate_limit, undefined}, {log_rotate_count, 1},
{log_rotate_count, undefined}, {log_rotate_size, 10*1024*1024},
{log_rotate_date, undefined},
{log_rotate_size, undefined},
{max_fsm_queue, undefined}, {max_fsm_queue, undefined},
{modules, []}, {modules, []},
{negotiation_timeout, timer:seconds(30)}, {negotiation_timeout, timer:seconds(30)},
@ -669,9 +669,7 @@ globals() ->
host_config, host_config,
listen, listen,
loglevel, loglevel,
log_rate_limit,
log_rotate_count, log_rotate_count,
log_rotate_date,
log_rotate_size, log_rotate_size,
negotiation_timeout, negotiation_timeout,
net_ticktime, net_ticktime,

View File

@ -36,9 +36,7 @@
-export([init/1, handle_event/2, handle_call/2, -export([init/1, handle_event/2, handle_call/2,
handle_info/2, terminate/2, code_change/3]). handle_info/2, terminate/2, code_change/3]).
%% We don't use ejabberd logger because lager can be overloaded -include("logger.hrl").
%% too and alarm_handler may get stuck.
%%-include("logger.hrl").
-define(CHECK_INTERVAL, timer:seconds(30)). -define(CHECK_INTERVAL, timer:seconds(30)).
@ -93,7 +91,7 @@ handle_event({clear_alarm, system_memory_high_watermark}, State) ->
handle_event({set_alarm, {process_memory_high_watermark, Pid}}, State) -> handle_event({set_alarm, {process_memory_high_watermark, Pid}}, State) ->
case proc_stat(Pid, get_app_pids()) of case proc_stat(Pid, get_app_pids()) of
#proc_stat{name = Name} = ProcStat -> #proc_stat{name = Name} = ProcStat ->
error_logger:warning_msg( ?WARNING_MSG(
"Process ~p consumes more than 5% of OS memory (~ts)~n", "Process ~p consumes more than 5% of OS memory (~ts)~n",
[Name, format_proc(ProcStat)]), [Name, format_proc(ProcStat)]),
handle_overload(State), handle_overload(State),
@ -104,7 +102,7 @@ handle_event({set_alarm, {process_memory_high_watermark, Pid}}, State) ->
handle_event({clear_alarm, process_memory_high_watermark}, State) -> handle_event({clear_alarm, process_memory_high_watermark}, State) ->
{ok, State}; {ok, State};
handle_event(Event, State) -> handle_event(Event, State) ->
error_logger:warning_msg("unexpected event: ~p~n", [Event]), ?WARNING_MSG("unexpected event: ~p~n", [Event]),
{ok, State}. {ok, State}.
handle_call(_Request, State) -> handle_call(_Request, State) ->
@ -114,7 +112,7 @@ handle_info({timeout, _TRef, handle_overload}, State) ->
handle_overload(State), handle_overload(State),
{ok, restart_timer(State)}; {ok, restart_timer(State)};
handle_info(Info, State) -> handle_info(Info, State) ->
error_logger:warning_msg("unexpected info: ~p~n", [Info]), ?WARNING_MSG("unexpected info: ~p~n", [Info]),
{ok, State}. {ok, State}.
terminate(_Reason, _State) -> terminate(_Reason, _State) ->
@ -137,7 +135,7 @@ handle_overload(_State, Procs) ->
MaxMsgs = ejabberd_option:oom_queue(), MaxMsgs = ejabberd_option:oom_queue(),
if TotalMsgs >= MaxMsgs -> if TotalMsgs >= MaxMsgs ->
SortedStats = lists:reverse(lists:keysort(#proc_stat.qlen, Stats)), SortedStats = lists:reverse(lists:keysort(#proc_stat.qlen, Stats)),
error_logger:warning_msg( ?WARNING_MSG(
"The system is overloaded with ~b messages " "The system is overloaded with ~b messages "
"queued by ~b process(es) (~b%) " "queued by ~b process(es) (~b%) "
"from the following applications: ~ts; " "from the following applications: ~ts; "
@ -272,7 +270,7 @@ do_kill(Stats, Threshold) ->
when Len >= Threshold -> when Len >= Threshold ->
case lists:member(App, excluded_apps()) of case lists:member(App, excluded_apps()) of
true -> true ->
error_logger:warning_msg( ?WARNING_MSG(
"Unable to kill process ~p from whitelisted " "Unable to kill process ~p from whitelisted "
"application ~p~n", [Name, App]), "application ~p~n", [Name, App]),
false; false;
@ -289,7 +287,7 @@ do_kill(Stats, Threshold) ->
end, Stats), end, Stats),
TotalKilled = length(Killed), TotalKilled = length(Killed),
if TotalKilled > 0 -> if TotalKilled > 0 ->
error_logger:error_msg( ?ERROR_MSG(
"Killed ~b process(es) consuming more than ~b message(s) each~n", "Killed ~b process(es) consuming more than ~b message(s) each~n",
[TotalKilled, Threshold]); [TotalKilled, Threshold]);
true -> true ->

View File

@ -367,16 +367,13 @@ depends(ServerHost, Opts) ->
%% <p>See {@link node_hometree:init/1} for an example implementation.</p> %% <p>See {@link node_hometree:init/1} for an example implementation.</p>
init_plugins(Host, ServerHost, Opts) -> init_plugins(Host, ServerHost, Opts) ->
TreePlugin = tree(Host, mod_pubsub_opt:nodetree(Opts)), TreePlugin = tree(Host, mod_pubsub_opt:nodetree(Opts)),
?DEBUG("** tree plugin is ~p", [TreePlugin]),
TreePlugin:init(Host, ServerHost, Opts), TreePlugin:init(Host, ServerHost, Opts),
Plugins = mod_pubsub_opt:plugins(Opts), Plugins = mod_pubsub_opt:plugins(Opts),
PepMapping = mod_pubsub_opt:pep_mapping(Opts), PepMapping = mod_pubsub_opt:pep_mapping(Opts),
?DEBUG("** PEP Mapping : ~p~n", [PepMapping]),
PluginsOK = lists:foldl( PluginsOK = lists:foldl(
fun (Name, Acc) -> fun (Name, Acc) ->
Plugin = plugin(Host, Name), Plugin = plugin(Host, Name),
apply(Plugin, init, [Host, ServerHost, Opts]), apply(Plugin, init, [Host, ServerHost, Opts]),
?DEBUG("** init ~ts plugin", [Name]),
[Name | Acc] [Name | Acc]
end, end,
[], Plugins), [], Plugins),
@ -385,7 +382,6 @@ init_plugins(Host, ServerHost, Opts) ->
terminate_plugins(Host, ServerHost, Plugins, TreePlugin) -> terminate_plugins(Host, ServerHost, Plugins, TreePlugin) ->
lists:foreach( lists:foreach(
fun (Name) -> fun (Name) ->
?DEBUG("** terminate ~ts plugin", [Name]),
Plugin = plugin(Host, Name), Plugin = plugin(Host, Name),
Plugin:terminate(Host, ServerHost) Plugin:terminate(Host, ServerHost)
end, end,