./ct_report/coverage/mongoose_log_filter.COVER.html

1 -module(mongoose_log_filter).
2 -export([fill_metadata_filter/2]).
3 -export([format_c2s_state_filter/2]).
4 -export([format_acc_filter/2]).
5 -export([format_packet_filter/2]).
6 -export([format_stacktrace_filter/2]).
7 -export([format_term_filter/2]).
8 -export([preserve_acc_filter/2]).
9 -export([remove_fields_filter/2]).
10 -export([filter_module/2]).
11
12 -ignore_xref([filter_module/2, format_acc_filter/2, format_c2s_state_filter/2,
13 format_packet_filter/2, format_stacktrace_filter/2, format_term_filter/2,
14 preserve_acc_filter/2, remove_fields_filter/2]).
15
16 -include("mongoose.hrl").
17 -include_lib("jid/include/jid.hrl").
18 -include("ejabberd_c2s.hrl").
19
20 %% The templater in flatlog works with meta fields.
21 %% So, we would need a filter, that takes the interesting fields
22 %% from msg to metadata.
23 -spec fill_metadata_filter(logger:log_event(), term()) -> logger:filter_return().
24 fill_metadata_filter(Event=#{msg := {report, Msg}, meta := Meta}, Fields) ->
25 19559 FieldMap = maps:with(Fields, Msg),
26 %% Remove the fields to not print them twice
27 19559 Msg2 = maps:without(Fields, Msg),
28 19559 Event#{meta => maps:merge(FieldMap, Meta), msg => {report, Msg2}};
29 fill_metadata_filter(Event, _) ->
30 926 Event.
31
32 format_c2s_state_filter(Event=#{msg := {report, Msg=#{c2s_state := State}}}, _) ->
33 210 StateMap = filter_undefined(c2s_state_to_map(State)),
34 %% C2S fields have lower priority, if the field is already present in msg.
35 210 Msg2 = maps:merge(StateMap, maps:remove(c2s_state, Msg)),
36 210 Event#{msg => {report, Msg2}};
37 format_c2s_state_filter(Event, _) ->
38 10033 Event.
39
40 format_acc_filter(Event=#{msg := {report, Msg=#{acc := Acc}}}, _) ->
41 1257 FormattedAcc = format_acc(Acc),
42 1257 Msg2 = maps:merge(FormattedAcc, maps:remove(acc, Msg)),
43 1257 Event#{msg => {report, Msg2}};
44 format_acc_filter(Event, _) ->
45 8986 Event.
46
47 %% Encodes exml_packet
48 format_packet_filter(Event=#{msg := {report, Msg=#{exml_packet := Packet}}}, _) ->
49
:-(
BinPacket = exml:to_binary(Packet),
50
:-(
Msg2 = maps:put(packet, BinPacket, maps:remove(exml_packet, Msg)),
51
:-(
Event#{msg => {report, Msg2}};
52 format_packet_filter(Event, _) ->
53 10243 Event.
54
55 format_stacktrace_filter(Event=#{msg := {report, Msg=#{stacktrace := S}}}, _) ->
56 58 FmtArgs = format_stacktrace_args(S),
57 58 Msg2 = case FmtArgs of
58 58 <<>> -> Msg;
59
:-(
_ -> Msg#{stacktrace_args => FmtArgs}
60 end,
61 58 Msg3 = case format_stacktrace(S) of
62
:-(
<<>> -> Msg2;
63 58 FmtStack -> Msg2#{stacktrace => FmtStack}
64 end,
65 58 Event#{msg => {report, Msg3 }};
66 format_stacktrace_filter(Event, _) ->
67 10185 Event.
68
69 format_term_filter(Event = #{msg := {report, Msg}}, Keys) ->
70 9780 FormattedMsg = lists:foldl(fun format_value/2, Msg, Keys),
71 9780 Event#{msg => {report, FormattedMsg}};
72 format_term_filter(Event, _) ->
73 463 Event.
74
75 format_value(Key, Msg) ->
76 9780 case maps:find(Key, Msg) of
77
:-(
{ok, Value} -> Msg#{Key := format_term(Value)};
78 9780 error -> Msg
79 end.
80
81 format_acc(#{origin_pid := OriginPid, timestamp := TS, stanza := StanzaMap}) ->
82 1211 Map = format_stanza_map(StanzaMap),
83 1211 Map#{acc_timestamp => format_microseconds(TS),
84 origin_pid => format_term(OriginPid)};
85 format_acc(_) ->
86 46 #{}.
87
88 format_stanza_map(#{element := Elem, from_jid := From, to_jid := To}) ->
89 1211 #{packet => exml:to_binary(Elem),
90 from_jid => jid:to_binary(From),
91 to_jid => jid:to_binary(To)};
92 format_stanza_map(_) ->
93
:-(
#{}.
94
95 preserve_acc_filter(Event=#{msg := {report, Msg=#{acc := Acc}}}, _) ->
96
:-(
Event#{msg => {report, Msg#{acc_original => format_term(Acc)}}};
97 preserve_acc_filter(Event, _) ->
98
:-(
Event.
99
100 remove_fields_filter(Event=#{msg := {report, Msg=#{}}}, FieldNames) ->
101 9780 Msg2 = maps:without(FieldNames, Msg),
102 9780 Event#{msg => {report, Msg2}};
103 remove_fields_filter(Event, _) ->
104 463 Event.
105
106
107 c2s_state_to_map(#state{socket = Socket, streamid = StreamId,
108 jid = Jid, sid = Sid}) ->
109 210 SocketMap = ejabberd_socket:format_socket(Socket),
110 210 SocketMap#{
111 streamid => StreamId,
112 jid => maybe_jid_to_binary(Jid),
113 user => maybe_jid_to_luser(Jid),
114 server => maybe_jid_to_lserver(Jid),
115 resource => maybe_jid_to_lresource(Jid),
116 session_started => maybe_sid_to_timestamp(Sid)}.
117
118 1211 format_term(X) -> iolist_to_binary(io_lib:format("~0p", [X])).
119
120 210 maybe_jid_to_binary(Jid = #jid{}) -> jid:to_binary(Jid);
121
:-(
maybe_jid_to_binary(_) -> undefined.
122
123 210 maybe_jid_to_luser(#jid{luser = LUser}) -> LUser;
124
:-(
maybe_jid_to_luser(_) -> undefined.
125
126 210 maybe_jid_to_lserver(#jid{lserver = LServer}) -> LServer;
127
:-(
maybe_jid_to_lserver(_) -> undefined.
128
129 210 maybe_jid_to_lresource(#jid{lresource = LResource}) -> LResource;
130
:-(
maybe_jid_to_lresource(_) -> undefined.
131
132 209 maybe_sid_to_timestamp({Timestamp, _Pid}) -> format_microseconds(Timestamp);
133 1 maybe_sid_to_timestamp(_) -> undefined.
134
135 format_microseconds(N) ->
136 1420 calendar:system_time_to_rfc3339(N, [{unit, microsecond},
137 {offset, 0},
138 {time_designator, $T}]).
139
140 format_stacktrace_args([{_Mod,_Fun,Args,_Info}|_]) when is_list(Args) ->
141
:-(
iolist_to_binary(io_lib:format("~p", [Args]));
142 format_stacktrace_args(_) ->
143 58 <<>>.
144
145 format_stacktrace(Stacktrace) ->
146 58 iolist_to_binary(do_format_stacktrace(Stacktrace)).
147
148 do_format_stacktrace([{Mod,Fun,Args,Info}|T]) when is_list(Args) ->
149
:-(
Arity = length(Args),
150
:-(
do_format_stacktrace([{Mod,Fun,Arity,Info}|T]);
151 do_format_stacktrace([{Mod,Fun,Arity,Info}|T]) ->
152 392 Line = proplists:get_value(line, Info, 0),
153 392 H = io_lib:format("~p:~p/~p:~p", [Mod, Fun, Arity, Line]),
154 392 more_format_stacktrace(H, T);
155 do_format_stacktrace([Other|T]) ->
156
:-(
H = io_lib:format("~p", [Other]),
157
:-(
more_format_stacktrace(H, T);
158 do_format_stacktrace([]) ->
159
:-(
[].
160
161 more_format_stacktrace(H, []) ->
162 58 [H];
163 more_format_stacktrace(H, T) ->
164 334 [H, " "|do_format_stacktrace(T)].
165
166 filter_undefined(Map) ->
167 210 maps:filter(fun(_, V) -> V =/= undefined end, Map).
168
169 filter_module(Event = #{meta := #{mfa := {M,_,_}}}, Modules) when is_list(Modules) ->
170
:-(
case lists:member(M, Modules) of
171 true ->
172
:-(
Event;
173 false ->
174
:-(
stop
175 end;
176 filter_module(_Event, _Modules) ->
177
:-(
stop. %% module unknown, drop
Line Hits Source