diff options
Diffstat (limited to 'src/mod_stats.erl')
-rw-r--r-- | src/mod_stats.erl | 161 |
1 files changed, 60 insertions, 101 deletions
diff --git a/src/mod_stats.erl b/src/mod_stats.erl index 99059839a..34d1d4c10 100644 --- a/src/mod_stats.erl +++ b/src/mod_stats.erl @@ -5,7 +5,7 @@ %%% Created : 11 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2016 ProcessOne +%%% ejabberd, Copyright (C) 2002-2019 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -31,65 +31,41 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_local_iq/3, - mod_opt_type/1, depends/2]). +-export([start/2, stop/1, reload/3, process_iq/1, + mod_options/1, depends/2]). --include("ejabberd.hrl"). -include("logger.hrl"). --include("jlib.hrl"). +-include("xmpp.hrl"). +-include("translate.hrl"). -start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, - ?NS_STATS, ?MODULE, process_local_iq, IQDisc). +start(Host, _Opts) -> + gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS, + ?MODULE, process_iq). stop(Host) -> - gen_iq_handler:remove_iq_handler(ejabberd_local, Host, - ?NS_STATS). + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_STATS). + +reload(Host, NewOpts, _OldOpts) -> + start(Host, NewOpts). depends(_Host, _Opts) -> []. -process_local_iq(_From, To, - #iq{id = _ID, type = Type, xmlns = XMLNS, - sub_el = SubEl, lang = Lang} = - IQ) -> - case Type of - set -> - Txt = <<"Value 'set' of 'type' attribute is not allowed">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; - get -> - #xmlel{children = Els} = SubEl, - Node = str:tokens(fxml:get_tag_attr_s(<<"node">>, SubEl), - <<"/">>), - Names = get_names(Els, []), - case get_local_stats(To#jid.server, Node, Names, Lang) of - {result, Res} -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, XMLNS}], - children = Res}]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end +process_iq(#iq{type = set, lang = Lang} = IQ) -> + Txt = ?T("Value 'set' of 'type' attribute is not allowed"), + xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); +process_iq(#iq{type = get, to = To, lang = Lang, + sub_els = [#stats{} = Stats]} = IQ) -> + Node = str:tokens(Stats#stats.node, <<"/">>), + Names = [Name || #stat{name = Name} <- Stats#stats.list], + case get_local_stats(To#jid.server, Node, Names, Lang) of + {result, List} -> + xmpp:make_iq_result(IQ, Stats#stats{list = List}); + {error, Error} -> + xmpp:make_error(IQ, Error) end. -get_names([], Res) -> Res; -get_names([#xmlel{name = <<"stat">>, attrs = Attrs} - | Els], - Res) -> - Name = fxml:get_attr_s(<<"name">>, Attrs), - case Name of - <<"">> -> get_names(Els, Res); - _ -> get_names(Els, [Name | Res]) - end; -get_names([_ | Els], Res) -> get_names(Els, Res). - --define(STAT(Name), - #xmlel{name = <<"stat">>, attrs = [{<<"name">>, Name}], - children = []}). +-define(STAT(Name), #stat{name = Name}). get_local_stats(_Server, [], [], _Lang) -> {result, @@ -114,71 +90,58 @@ get_local_stats(_Server, [<<"running nodes">>, ENode], Names, Lang) -> case search_running_node(ENode) of false -> - Txt = <<"No running node found">>, - {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)}; + Txt = ?T("No running node found"), + {error, xmpp:err_item_not_found(Txt, Lang)}; Node -> {result, lists:map(fun (Name) -> get_node_stat(Node, Name) end, Names)} end; get_local_stats(_Server, _, _, Lang) -> - Txt = <<"No statistics found for this item">>, - {error, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)}. + Txt = ?T("No statistics found for this item"), + {error, xmpp:err_feature_not_implemented(Txt, Lang)}. --define(STATVAL(Val, Unit), - #xmlel{name = <<"stat">>, - attrs = - [{<<"name">>, Name}, {<<"units">>, Unit}, - {<<"value">>, Val}], - children = []}). +-define(STATVAL(Val, Unit), #stat{name = Name, units = Unit, value = Val}). -define(STATERR(Code, Desc), - #xmlel{name = <<"stat">>, attrs = [{<<"name">>, Name}], - children = - [#xmlel{name = <<"error">>, - attrs = [{<<"code">>, Code}], - children = [{xmlcdata, Desc}]}]}). + #stat{name = Name, + error = #stat_error{code = Code, reason = Desc}}). get_local_stat(Server, [], Name) when Name == <<"users/online">> -> case catch ejabberd_sm:get_vh_session_list(Server) of {'EXIT', _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); + ?STATERR(500, <<"Internal Server Error">>); Users -> - ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))), + ?STATVAL((integer_to_binary(length(Users))), <<"users">>) end; get_local_stat(Server, [], Name) when Name == <<"users/total">> -> case catch - ejabberd_auth:get_vh_registered_users_number(Server) + ejabberd_auth:count_users(Server) of {'EXIT', _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); + ?STATERR(500, <<"Internal Server Error">>); NUsers -> - ?STATVAL((iolist_to_binary(integer_to_list(NUsers))), + ?STATVAL((integer_to_binary(NUsers)), <<"users">>) end; get_local_stat(_Server, [], Name) when Name == <<"users/all-hosts/online">> -> - case catch mnesia:table_info(session, size) of - {'EXIT', _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); - Users -> - ?STATVAL((iolist_to_binary(integer_to_list(Users))), - <<"users">>) - end; + Users = ejabberd_sm:connected_users_number(), + ?STATVAL((integer_to_binary(Users)), <<"users">>); get_local_stat(_Server, [], Name) when Name == <<"users/all-hosts/total">> -> NumUsers = lists:foldl(fun (Host, Total) -> - ejabberd_auth:get_vh_registered_users_number(Host) + ejabberd_auth:count_users(Host) + Total end, - 0, ?MYHOSTS), - ?STATVAL((iolist_to_binary(integer_to_list(NumUsers))), + 0, ejabberd_option:hosts()), + ?STATVAL((integer_to_binary(NumUsers)), <<"users">>); get_local_stat(_Server, _, Name) -> - ?STATERR(<<"404">>, <<"Not Found">>). + ?STATERR(404, <<"Not Found">>). get_node_stat(Node, Name) when Name == <<"time/uptime">> -> @@ -186,11 +149,9 @@ get_node_stat(Node, Name) [wall_clock]) of {badrpc, _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); + ?STATERR(500, <<"Internal Server Error">>); CPUTime -> - ?STATVAL(list_to_binary( - io_lib:format("~.3f", - [element(1, CPUTime) / 1000])), + ?STATVAL(str:format("~.3f", [element(1, CPUTime) / 1000]), <<"seconds">>) end; get_node_stat(Node, Name) @@ -198,11 +159,9 @@ get_node_stat(Node, Name) case catch ejabberd_cluster:call(Node, erlang, statistics, [runtime]) of {badrpc, _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); + ?STATERR(500, <<"Internal Server Error">>); RunTime -> - ?STATVAL(list_to_binary( - io_lib:format("~.3f", - [element(1, RunTime) / 1000])), + ?STATVAL(str:format("~.3f", [element(1, RunTime) / 1000]), <<"seconds">>) end; get_node_stat(Node, Name) @@ -211,9 +170,9 @@ get_node_stat(Node, Name) dirty_get_my_sessions_list, []) of {badrpc, _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); + ?STATERR(500, <<"Internal Server Error">>); Users -> - ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))), + ?STATVAL((integer_to_binary(length(Users))), <<"users">>) end; get_node_stat(Node, Name) @@ -222,9 +181,9 @@ get_node_stat(Node, Name) [transaction_commits]) of {badrpc, _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); + ?STATERR(500, <<"Internal Server Error">>); Transactions -> - ?STATVAL((iolist_to_binary(integer_to_list(Transactions))), + ?STATVAL((integer_to_binary(Transactions)), <<"transactions">>) end; get_node_stat(Node, Name) @@ -233,9 +192,9 @@ get_node_stat(Node, Name) [transaction_failures]) of {badrpc, _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); + ?STATERR(500, <<"Internal Server Error">>); Transactions -> - ?STATVAL((iolist_to_binary(integer_to_list(Transactions))), + ?STATVAL((integer_to_binary(Transactions)), <<"transactions">>) end; get_node_stat(Node, Name) @@ -244,9 +203,9 @@ get_node_stat(Node, Name) [transaction_restarts]) of {badrpc, _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); + ?STATERR(500, <<"Internal Server Error">>); Transactions -> - ?STATVAL((iolist_to_binary(integer_to_list(Transactions))), + ?STATVAL((integer_to_binary(Transactions)), <<"transactions">>) end; get_node_stat(Node, Name) @@ -255,13 +214,13 @@ get_node_stat(Node, Name) [transaction_log_writes]) of {badrpc, _Reason} -> - ?STATERR(<<"500">>, <<"Internal Server Error">>); + ?STATERR(500, <<"Internal Server Error">>); Transactions -> - ?STATVAL((iolist_to_binary(integer_to_list(Transactions))), + ?STATVAL((integer_to_binary(Transactions)), <<"transactions">>) end; get_node_stat(_, Name) -> - ?STATERR(<<"404">>, <<"Not Found">>). + ?STATERR(404, <<"Not Found">>). search_running_node(SNode) -> search_running_node(SNode, @@ -274,5 +233,5 @@ search_running_node(SNode, [Node | Nodes]) -> _ -> search_running_node(SNode, Nodes) end. -mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; -mod_opt_type(_) -> [iqdisc]. +mod_options(_Host) -> + []. |