./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 19082 FieldMap = maps:with(Fields, Msg),
26 %% Remove the fields to not print them twice
27 19082 Msg2 = maps:without(Fields, Msg),
28 19082 Event#{meta => maps:merge(FieldMap, Meta), msg => {report, Msg2}};
29 fill_metadata_filter(Event, _) ->
30 584 Event.
31
32 format_c2s_state_filter(Event=#{msg := {report, Msg=#{c2s_state := State}}}, _) ->
33 212 StateMap = filter_undefined(c2s_state_to_map(State)),
34 %% C2S fields have lower priority, if the field is already present in msg.
35 212 Msg2 = maps:merge(StateMap, maps:remove(c2s_state, Msg)),
36 212 Event#{msg => {report, Msg2}};
37 format_c2s_state_filter(Event, _) ->
38 9621 Event.
39
40 format_acc_filter(Event=#{msg := {report, Msg=#{acc := Acc}}}, _) ->
41 1279 FormattedAcc = format_acc(Acc),
42 1279 Msg2 = maps:merge(FormattedAcc, maps:remove(acc, Msg)),
43 1279 Event#{msg => {report, Msg2}};
44 format_acc_filter(Event, _) ->
45 8554 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 9833 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 56 <<>> -> Msg;
59 2 _ -> 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 9775 Event.
68
69 format_term_filter(Event = #{msg := {report, Msg}}, Keys) ->
70 9541 FormattedMsg = lists:foldl(fun format_value/2, Msg, Keys),
71 9541 Event#{msg => {report, FormattedMsg}};
72 format_term_filter(Event, _) ->
73 292 Event.
74
75 format_value(Key, Msg) ->
76 9541 case maps:find(Key, Msg) of
77
:-(
{ok, Value} -> Msg#{Key := format_term(Value)};
78 9541 error -> Msg
79 end.
80
81 format_acc(#{origin_pid := OriginPid, timestamp := TS, stanza := StanzaMap}) ->
82 1233 Map = format_stanza_map(StanzaMap),
83 1233 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 1233 #{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 9541 Msg2 = maps:without(FieldNames, Msg),
102 9541 Event#{msg => {report, Msg2}};
103 remove_fields_filter(Event, _) ->
104 292 Event.
105
106
107 c2s_state_to_map(#state{socket = Socket, streamid = StreamId,
108 jid = Jid, sid = Sid}) ->
109 212 SocketMap = ejabberd_socket:format_socket(Socket),
110 212 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 1233 format_term(X) -> iolist_to_binary(io_lib:format("~0p", [X])).
119
120 212 maybe_jid_to_binary(Jid = #jid{}) -> jid:to_binary(Jid);
121
:-(
maybe_jid_to_binary(_) -> undefined.
122
123 212 maybe_jid_to_luser(#jid{luser = LUser}) -> LUser;
124
:-(
maybe_jid_to_luser(_) -> undefined.
125
126 212 maybe_jid_to_lserver(#jid{lserver = LServer}) -> LServer;
127
:-(
maybe_jid_to_lserver(_) -> undefined.
128
129 212 maybe_jid_to_lresource(#jid{lresource = LResource}) -> LResource;
130
:-(
maybe_jid_to_lresource(_) -> undefined.
131
132 211 maybe_sid_to_timestamp({Timestamp, _Pid}) -> format_microseconds(Timestamp);
133 1 maybe_sid_to_timestamp(_) -> undefined.
134
135 format_microseconds(N) ->
136 1444 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 2 iolist_to_binary(io_lib:format("~p", [Args]));
142 format_stacktrace_args(_) ->
143 56 <<>>.
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 2 Arity = length(Args),
150 2 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 212 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