mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-20 17:27:00 +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:
parent
b1d458999a
commit
e4a8afb15d
@ -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
|
||||||
|
14
README.md
14
README.md
@ -14,24 +14,24 @@ solutions very cost effectively.
|
|||||||
Key Features
|
Key Features
|
||||||
------------
|
------------
|
||||||
|
|
||||||
- **Cross-platform**
|
- **Cross-platform**
|
||||||
ejabberd runs under Microsoft Windows and Unix-derived systems such as
|
ejabberd runs under Microsoft Windows and Unix-derived systems such as
|
||||||
Linux, FreeBSD and NetBSD.
|
Linux, FreeBSD and NetBSD.
|
||||||
|
|
||||||
- **Distributed**
|
- **Distributed**
|
||||||
You can run ejabberd on a cluster of machines and all of them will serve the
|
You can run ejabberd on a cluster of machines and all of them will serve the
|
||||||
same XMPP domain(s). When you need more capacity you can simply add a new
|
same XMPP domain(s). When you need more capacity you can simply add a new
|
||||||
cheap node to your cluster. Accordingly, you do not need to buy an expensive
|
cheap node to your cluster. Accordingly, you do not need to buy an expensive
|
||||||
high-end machine to support tens of thousands concurrent users.
|
high-end machine to support tens of thousands concurrent users.
|
||||||
|
|
||||||
- **Fault-tolerant**
|
- **Fault-tolerant**
|
||||||
You can deploy an ejabberd cluster so that all the information required for
|
You can deploy an ejabberd cluster so that all the information required for
|
||||||
a properly working service will be replicated permanently on all nodes. This
|
a properly working service will be replicated permanently on all nodes. This
|
||||||
means that if one of the nodes crashes, the others will continue working
|
means that if one of the nodes crashes, the others will continue working
|
||||||
without disruption. In addition, nodes also can be added or replaced ‘on
|
without disruption. In addition, nodes also can be added or replaced ‘on
|
||||||
the fly’.
|
the fly’.
|
||||||
|
|
||||||
- **Administrator-friendly**
|
- **Administrator-friendly**
|
||||||
ejabberd is built on top of the Open Source Erlang. As a result you do not
|
ejabberd is built on top of the Open Source Erlang. As a result you do not
|
||||||
need to install an external database, an external web server, amongst others
|
need to install an external database, an external web server, amongst others
|
||||||
because everything is already included, and ready to run out of the box.
|
because everything is already included, and ready to run out of the box.
|
||||||
@ -44,13 +44,13 @@ Key Features
|
|||||||
- Can integrate with existing authentication mechanisms.
|
- Can integrate with existing authentication mechanisms.
|
||||||
- Capability to send announce messages.
|
- Capability to send announce messages.
|
||||||
|
|
||||||
- **Internationalized**
|
- **Internationalized**
|
||||||
ejabberd leads in internationalization. Hence it is very well suited in a
|
ejabberd leads in internationalization. Hence it is very well suited in a
|
||||||
globalized world. Related features are:
|
globalized world. Related features are:
|
||||||
- Translated to 25 languages.
|
- Translated to 25 languages.
|
||||||
- Support for IDNA.
|
- Support for IDNA.
|
||||||
|
|
||||||
- **Open Standards**
|
- **Open Standards**
|
||||||
ejabberd is the first Open Source Jabber server claiming to fully comply to
|
ejabberd is the first Open Source Jabber server claiming to fully comply to
|
||||||
the XMPP standard.
|
the XMPP standard.
|
||||||
- Fully XMPP-compliant.
|
- Fully XMPP-compliant.
|
||||||
@ -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).
|
||||||
|
@ -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])
|
||||||
|
@ -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:
|
||||||
|
@ -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),
|
||||||
|
@ -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"}}},
|
||||||
|
@ -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, []}}]}.
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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) ->
|
||||||
|
@ -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).
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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];
|
||||||
|
@ -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.
|
|
||||||
|
@ -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}).
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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 ->
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user