1 |
|
%%%------------------------------------------------------------------- |
2 |
|
%%% @author Michal Piotrowski <michal.piotrowski@erlang-solutions.com> |
3 |
|
%%% @copyright (C) 2013, Erlang Solutions Ltd. |
4 |
|
%%% @doc MongooseIM hooks for general metrics |
5 |
|
%%% |
6 |
|
%%% @end |
7 |
|
%%% Created : 23 Apr 2013 by Michal Piotrowski <michal.piotrowski@erlang-solutions.com> |
8 |
|
%%%------------------------------------------------------------------- |
9 |
|
-module(mongoose_metrics_hooks). |
10 |
|
|
11 |
|
-include("jlib.hrl"). |
12 |
|
|
13 |
|
-export([get_hooks/1]). |
14 |
|
|
15 |
|
%%------------------- |
16 |
|
%% Internal exports |
17 |
|
%%------------------- |
18 |
|
-export([sm_register_connection_hook/3, |
19 |
|
sm_remove_connection_hook/3, |
20 |
|
auth_failed/3, |
21 |
|
user_send_packet/3, |
22 |
|
user_open_session/3, |
23 |
|
xmpp_bounce_message/3, |
24 |
|
xmpp_stanza_dropped/3, |
25 |
|
xmpp_send_element/3, |
26 |
|
roster_get/3, |
27 |
|
roster_set/3, |
28 |
|
roster_push/3, |
29 |
|
roster_in_subscription/3, |
30 |
|
register_user/3, |
31 |
|
remove_user/3, |
32 |
|
privacy_iq_get/3, |
33 |
|
privacy_iq_set/3, |
34 |
|
privacy_check_packet/3, |
35 |
|
privacy_list_push/3 |
36 |
|
]). |
37 |
|
|
38 |
|
%%------------------- |
39 |
|
%% Implementation |
40 |
|
%%------------------- |
41 |
|
|
42 |
|
%% @doc Here will be declared which hooks should be registered |
43 |
|
-spec get_hooks(_) -> [gen_hook:hook_tuple(), ...]. |
44 |
|
get_hooks(HostType) -> |
45 |
503 |
[ {sm_register_connection_hook, HostType, fun ?MODULE:sm_register_connection_hook/3, #{}, 50}, |
46 |
|
{sm_remove_connection_hook, HostType, fun ?MODULE:sm_remove_connection_hook/3, #{}, 50}, |
47 |
|
{auth_failed, HostType, fun ?MODULE:auth_failed/3, #{}, 50}, |
48 |
|
{xmpp_stanza_dropped, HostType, fun ?MODULE:xmpp_stanza_dropped/3, #{}, 50}, |
49 |
|
{xmpp_bounce_message, HostType, fun ?MODULE:xmpp_bounce_message/3, #{}, 50}, |
50 |
|
{xmpp_send_element, HostType, fun ?MODULE:xmpp_send_element/3, #{}, 50}, |
51 |
|
{roster_get, HostType, fun ?MODULE:roster_get/3, #{}, 55}, |
52 |
|
{roster_set, HostType, fun ?MODULE:roster_set/3, #{}, 50}, |
53 |
|
{roster_push, HostType, fun ?MODULE:roster_push/3, #{}, 50}, |
54 |
|
{roster_in_subscription, HostType, fun ?MODULE:roster_in_subscription/3, #{}, 55}, |
55 |
|
{register_user, HostType, fun ?MODULE:register_user/3, #{}, 50}, |
56 |
|
{remove_user, HostType, fun ?MODULE:remove_user/3, #{}, 50}, |
57 |
|
{privacy_iq_get, HostType, fun ?MODULE:privacy_iq_get/3, #{}, 1}, |
58 |
|
{privacy_iq_set, HostType, fun ?MODULE:privacy_iq_set/3, #{}, 1}, |
59 |
|
{privacy_check_packet, HostType, fun ?MODULE:privacy_check_packet/3, #{}, 55}, |
60 |
|
{privacy_list_push, HostType, fun ?MODULE:privacy_list_push/3, #{}, 1} |
61 |
|
| c2s_hooks(HostType)]. |
62 |
|
|
63 |
|
-spec c2s_hooks(mongooseim:host_type()) -> gen_hook:hook_list(mongoose_c2s_hooks:fn()). |
64 |
|
c2s_hooks(HostType) -> |
65 |
503 |
[{user_send_packet, HostType, fun ?MODULE:user_send_packet/3, #{}, 50}, |
66 |
|
{user_open_session, HostType, fun ?MODULE:user_open_session/3, #{}, 50}]. |
67 |
|
|
68 |
|
-spec sm_register_connection_hook(Acc, Params, Extra) -> {ok, Acc} when |
69 |
|
Acc :: any(), |
70 |
|
Params :: map(), |
71 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
72 |
|
sm_register_connection_hook(Acc, _, #{host_type := HostType}) -> |
73 |
5899 |
mongoose_metrics:update(HostType, sessionSuccessfulLogins, 1), |
74 |
5899 |
mongoose_metrics:update(HostType, sessionCount, 1), |
75 |
5899 |
{ok, Acc}. |
76 |
|
|
77 |
|
-spec sm_remove_connection_hook(Acc, Params, Extra) -> {ok, Acc} when |
78 |
|
Acc :: mongoose_acc:t(), |
79 |
|
Params :: map(), |
80 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
81 |
|
sm_remove_connection_hook(Acc, _, #{host_type := HostType}) -> |
82 |
5895 |
mongoose_metrics:update(HostType, sessionLogouts, 1), |
83 |
5895 |
mongoose_metrics:update(HostType, sessionCount, -1), |
84 |
5895 |
{ok, Acc}. |
85 |
|
|
86 |
|
-spec auth_failed(Acc, Params, Extra) -> {ok, Acc} when |
87 |
|
Acc :: any(), |
88 |
|
Params :: #{server := jid:server()}, |
89 |
|
Extra :: map(). |
90 |
|
auth_failed(Acc, #{server := Server}, _) -> |
91 |
65 |
LServer = jid:nameprep(Server), |
92 |
65 |
{ok, HostType} = mongoose_domain_api:get_host_type(LServer), |
93 |
65 |
mongoose_metrics:update(HostType, sessionAuthFails, 1), |
94 |
65 |
{ok, Acc}. |
95 |
|
|
96 |
|
-spec user_send_packet(mongoose_acc:t(), mongoose_c2s_hooks:params(), map()) -> |
97 |
|
mongoose_c2s_hooks:result(). |
98 |
|
user_send_packet(Acc, _Params, #{host_type := HostType}) -> |
99 |
20503 |
mongoose_metrics:update(HostType, xmppStanzaSent, 1), |
100 |
20503 |
mongoose_metrics:update(HostType, xmppStanzaCount, 1), |
101 |
20503 |
El = mongoose_acc:element(Acc), |
102 |
20503 |
user_send_packet_type(HostType, El), |
103 |
20503 |
{ok, Acc}. |
104 |
|
|
105 |
|
-spec user_send_packet_type(HostType :: mongooseim:host_type(), |
106 |
|
Packet :: exml:element()) -> ok | {error, not_found}. |
107 |
|
user_send_packet_type(HostType, #xmlel{name = <<"message">>}) -> |
108 |
3663 |
mongoose_metrics:update(HostType, xmppMessageSent, 1); |
109 |
|
user_send_packet_type(HostType, #xmlel{name = <<"iq">>}) -> |
110 |
10437 |
mongoose_metrics:update(HostType, xmppIqSent, 1); |
111 |
|
user_send_packet_type(HostType, #xmlel{name = <<"presence">>}) -> |
112 |
6276 |
mongoose_metrics:update(HostType, xmppPresenceSent, 1); |
113 |
|
user_send_packet_type(_, _) -> |
114 |
127 |
ok. |
115 |
|
|
116 |
|
-spec xmpp_bounce_message(Acc, Params, Extra) -> {ok, Acc} when |
117 |
|
Acc :: mongoose_acc:t(), |
118 |
|
Params :: map(), |
119 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
120 |
|
xmpp_bounce_message(Acc, _, #{host_type := HostType}) -> |
121 |
33 |
mongoose_metrics:update(HostType, xmppMessageBounced, 1), |
122 |
33 |
{ok, Acc}. |
123 |
|
|
124 |
|
-spec xmpp_stanza_dropped(Acc, Params, Extra) -> {ok, Acc} when |
125 |
|
Acc :: mongoose_acc:t(), |
126 |
|
Params :: map(), |
127 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
128 |
|
xmpp_stanza_dropped(Acc, _, #{host_type := HostType}) -> |
129 |
73 |
mongoose_metrics:update(HostType, xmppStanzaDropped, 1), |
130 |
73 |
{ok, Acc}. |
131 |
|
|
132 |
|
-spec xmpp_send_element(Acc, Params, Extra) -> {ok, Acc} when |
133 |
|
Acc :: mongoose_acc:t(), |
134 |
|
Params :: map(), |
135 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
136 |
|
xmpp_send_element(Acc, _, #{host_type := HostType}) -> |
137 |
55948 |
case mongoose_acc:element(Acc) of |
138 |
|
#xmlel{name = Name} = El |
139 |
|
when Name == <<"iq">>; Name == <<"message">>; Name == <<"presence">> -> |
140 |
37605 |
mongoose_metrics:update(HostType, xmppStanzaCount, 1), |
141 |
37605 |
case exml_query:attr(El, <<"type">>) of |
142 |
|
<<"error">> -> |
143 |
562 |
mongoose_metrics:update(HostType, xmppErrorTotal, 1), |
144 |
562 |
xmpp_send_element_error(HostType, El); |
145 |
|
_ -> |
146 |
37043 |
mongoose_metrics:update(HostType, xmppStanzaReceived, 1), |
147 |
37043 |
xmpp_send_element_type(HostType, El) |
148 |
|
end; |
149 |
18343 |
_ -> ok |
150 |
|
end, |
151 |
55948 |
{ok, Acc}. |
152 |
|
|
153 |
|
-spec xmpp_send_element_error(HostType :: mongooseim:host_type(), |
154 |
|
Packet :: exml:element()) -> ok | {error, not_found}. |
155 |
|
xmpp_send_element_error(HostType, #xmlel{name = <<"message">>}) -> |
156 |
191 |
mongoose_metrics:update(HostType, xmppErrorMessage, 1); |
157 |
|
xmpp_send_element_error(HostType, #xmlel{name = <<"iq">>}) -> |
158 |
315 |
mongoose_metrics:update(HostType, xmppErrorIq, 1); |
159 |
|
xmpp_send_element_error(HostType, #xmlel{name = <<"presence">>}) -> |
160 |
56 |
mongoose_metrics:update(HostType, xmppErrorPresence, 1). |
161 |
|
|
162 |
|
-spec xmpp_send_element_type(HostType :: mongooseim:host_type(), |
163 |
|
Packet :: exml:element()) -> ok | {error, not_found}. |
164 |
|
xmpp_send_element_type(HostType, #xmlel{name = <<"message">>}) -> |
165 |
11562 |
mongoose_metrics:update(HostType, xmppMessageReceived, 1); |
166 |
|
xmpp_send_element_type(HostType, #xmlel{name = <<"iq">>}) -> |
167 |
16896 |
mongoose_metrics:update(HostType, xmppIqReceived, 1); |
168 |
|
xmpp_send_element_type(HostType, #xmlel{name = <<"presence">>}) -> |
169 |
8585 |
mongoose_metrics:update(HostType, xmppPresenceReceived, 1). |
170 |
|
|
171 |
|
-spec user_open_session(mongoose_acc:t(), mongoose_c2s_hooks:params(), map()) -> |
172 |
|
mongoose_c2s_hooks:result(). |
173 |
|
user_open_session(Acc, _Params, #{host_type := HostType}) -> |
174 |
5880 |
mongoose_metrics:update(HostType, xmppStanzaSent, 1), |
175 |
5880 |
mongoose_metrics:update(HostType, xmppStanzaCount, 1), |
176 |
5880 |
mongoose_metrics:update(HostType, xmppIqSent, 1), |
177 |
5880 |
{ok, Acc}. |
178 |
|
|
179 |
|
%% Roster |
180 |
|
|
181 |
|
-spec roster_get(Acc, Params, Extra) -> {ok, Acc} when |
182 |
|
Acc :: term(), |
183 |
|
Params :: map(), |
184 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
185 |
|
roster_get(Acc, _, #{host_type := HostType}) -> |
186 |
186 |
mongoose_metrics:update(HostType, modRosterGets, 1), |
187 |
186 |
{ok, Acc}. |
188 |
|
|
189 |
|
-spec roster_set(Acc, Params, Extra) -> {ok, Acc} when |
190 |
|
Acc :: any(), |
191 |
|
Params :: #{from := jid:jid()}, |
192 |
|
Extra :: map(). |
193 |
|
roster_set(Acc, #{from := #jid{lserver = LServer}}, _) -> |
194 |
31 |
{ok, HostType} = mongoose_domain_api:get_host_type(LServer), |
195 |
31 |
mongoose_metrics:update(HostType, modRosterSets, 1), |
196 |
31 |
{ok, Acc}. |
197 |
|
|
198 |
|
-spec roster_in_subscription(Acc, Params, Extra) -> {ok, Acc} when |
199 |
|
Acc :: mongoose_acc:t(), |
200 |
|
Params :: #{type := mod_roster:sub_presence()}, |
201 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
202 |
|
roster_in_subscription(Acc, #{type := subscribed}, #{host_type := HostType}) -> |
203 |
163 |
mongoose_metrics:update(HostType, modPresenceSubscriptions, 1), |
204 |
163 |
{ok, Acc}; |
205 |
|
roster_in_subscription(Acc, #{type := unsubscribed}, #{host_type := HostType}) -> |
206 |
94 |
mongoose_metrics:update(HostType, modPresenceUnsubscriptions, 1), |
207 |
94 |
{ok, Acc}; |
208 |
|
roster_in_subscription(Acc, _, _) -> |
209 |
256 |
{ok, Acc}. |
210 |
|
|
211 |
|
-spec roster_push(Acc, Params, Extra) -> {ok, Acc} when |
212 |
|
Acc :: any(), |
213 |
|
Params :: map(), |
214 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
215 |
|
roster_push(HookAcc, _, #{host_type := HostType}) -> |
216 |
772 |
mongoose_metrics:update(HostType, modRosterPush, 1), |
217 |
772 |
{ok, HookAcc}. |
218 |
|
|
219 |
|
%% Register |
220 |
|
|
221 |
|
%% #rh |
222 |
|
-spec register_user(Acc, Params, Extra) -> {ok, Acc} when |
223 |
|
Acc :: any(), |
224 |
|
Params :: #{jid := jid:jid()}, |
225 |
|
Extra :: map(). |
226 |
|
register_user(Acc, #{jid := #jid{lserver = LServer}}, _) -> |
227 |
5459 |
{ok, HostType} = mongoose_domain_api:get_host_type(LServer), |
228 |
5459 |
mongoose_metrics:update(HostType, modRegisterCount, 1), |
229 |
5459 |
{ok, Acc}. |
230 |
|
|
231 |
|
-spec remove_user(Acc, Params, Extra) -> {ok, Acc} when |
232 |
|
Acc :: mongoose_acc:t(), |
233 |
|
Params :: map(), |
234 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
235 |
|
remove_user(Acc, _, #{host_type := HostType}) -> |
236 |
5433 |
mongoose_metrics:update(HostType, modUnregisterCount, 1), |
237 |
5433 |
{ok, Acc}. |
238 |
|
|
239 |
|
%% Privacy |
240 |
|
|
241 |
|
-spec privacy_iq_get(Acc, Params, Extra) -> {ok, Acc} when |
242 |
|
Acc :: mongoose_acc:t(), |
243 |
|
Params :: map(), |
244 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
245 |
|
privacy_iq_get(Acc, _, #{host_type := HostType}) -> |
246 |
62 |
mongoose_metrics:update(HostType, modPrivacyGets, 1), |
247 |
62 |
{ok, Acc}. |
248 |
|
|
249 |
|
-spec privacy_iq_set(Acc, Params, Extra) -> {ok, Acc} when |
250 |
|
Acc :: mongoose_acc:t(), |
251 |
|
Params :: #{iq := jlib:iq()}, |
252 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
253 |
|
privacy_iq_set(Acc, #{iq := #iq{sub_el = SubEl}}, #{host_type := HostType}) -> |
254 |
139 |
#xmlel{children = Els} = SubEl, |
255 |
139 |
case xml:remove_cdata(Els) of |
256 |
|
[#xmlel{name = <<"active">>}] -> |
257 |
44 |
mongoose_metrics:update(HostType, modPrivacySetsActive, 1); |
258 |
|
[#xmlel{name = <<"default">>}] -> |
259 |
16 |
mongoose_metrics:update(HostType, modPrivacySetsDefault, 1); |
260 |
|
_ -> |
261 |
79 |
ok |
262 |
|
end, |
263 |
139 |
mongoose_metrics:update(HostType, modPrivacySets, 1), |
264 |
139 |
{ok, Acc}. |
265 |
|
|
266 |
|
-spec privacy_list_push(Acc, Params, Extra) -> {ok, Acc} when |
267 |
|
Acc :: any(), |
268 |
|
Params :: #{session_count := non_neg_integer()}, |
269 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
270 |
|
privacy_list_push(Acc, #{session_count := SessionCount}, #{host_type := HostType}) -> |
271 |
78 |
mongoose_metrics:update(HostType, modPrivacyPush, SessionCount), |
272 |
78 |
{ok, Acc}. |
273 |
|
|
274 |
|
-spec privacy_check_packet(Acc, Params, Extra) -> {ok, Acc} when |
275 |
|
Acc :: mongoose_acc:t(), |
276 |
|
Params :: map(), |
277 |
|
Extra :: #{host_type := mongooseim:host_type()}. |
278 |
|
privacy_check_packet(Acc, _, #{host_type := HostType}) -> |
279 |
3456 |
mongoose_metrics:update(HostType, modPrivacyStanzaAll, 1), |
280 |
3456 |
case mongoose_acc:get(privacy, check, allow, Acc) of |
281 |
|
deny -> |
282 |
:-( |
mongoose_metrics:update(HostType, modPrivacyStanzaDenied, 1); |
283 |
|
block -> |
284 |
:-( |
mongoose_metrics:update(HostType, modPrivacyStanzaBlocked, 1); |
285 |
|
allow -> |
286 |
3456 |
ok |
287 |
|
end, |
288 |
3456 |
{ok, Acc}. |
289 |
|
|
290 |
|
%%% vim: set sts=4 ts=4 sw=4 et filetype=erlang foldmarker=%%%',%%%. foldmethod=marker: |