refactor: log formatter format mfa+line as m:f/a(line)

also improve json formatter when a field is iolist
This commit is contained in:
Zaiming (Stone) Shi 2023-09-25 12:20:54 +02:00
parent 6a557980e4
commit 5e6996dc05
4 changed files with 45 additions and 40 deletions

View File

@ -236,20 +236,24 @@ json(P, C) when is_port(P) -> json(port_to_list(P), C);
json(F, C) when is_function(F) -> json(erlang:fun_to_list(F), C); json(F, C) when is_function(F) -> json(erlang:fun_to_list(F), C);
json(B, Config) when is_binary(B) -> json(B, Config) when is_binary(B) ->
best_effort_unicode(B, Config); best_effort_unicode(B, Config);
json(L, Config) when is_list(L), is_integer(hd(L)) ->
best_effort_unicode(L, Config);
json(M, Config) when is_list(M), is_tuple(hd(M)), tuple_size(hd(M)) =:= 2 -> json(M, Config) when is_list(M), is_tuple(hd(M)), tuple_size(hd(M)) =:= 2 ->
best_effort_json_obj(M, Config); best_effort_json_obj(M, Config);
json(L, Config) when is_list(L) -> json(L, Config) when is_list(L) ->
[json(I, Config) || I <- L]; try unicode:characters_to_binary(L, utf8) of
B when is_binary(B) -> B;
_ -> [json(I, Config) || I <- L]
catch
_:_ ->
[json(I, Config) || I <- L]
end;
json(Map, Config) when is_map(Map) -> json(Map, Config) when is_map(Map) ->
best_effort_json_obj(Map, Config); best_effort_json_obj(Map, Config);
json(Term, Config) -> json(Term, Config) ->
do_format_msg("~p", [Term], Config). do_format_msg("~p", [Term], Config).
json_obj_root(Data0, Config) -> json_obj_root(Data0, Config) ->
Time = maps:get(time, Data0), Time = maps:get(time, Data0, undefined),
Level = maps:get(level, Data0), Level = maps:get(level, Data0, undefined),
Msg1 = Msg1 =
case maps:get(msg, Data0, undefined) of case maps:get(msg, Data0, undefined) of
undefined -> undefined ->
@ -264,28 +268,7 @@ json_obj_root(Data0, Config) ->
_ -> _ ->
json(Msg1, Config) json(Msg1, Config)
end, end,
Line = Mfal = emqx_utils:format_mfal(Data0),
case maps:get(line, Data0, undefined) of
undefined ->
<<"">>;
Num ->
iolist_to_binary([":", integer_to_list(Num)])
end,
Mfal =
case maps:get(mfa, Data0, undefined) of
{M, F, A} ->
<<
(atom_to_binary(M, utf8))/binary,
$:,
(atom_to_binary(F, utf8))/binary,
$/,
(integer_to_binary(A))/binary,
Line/binary
>>;
_ ->
unefined
end,
Data = Data =
maps:fold( maps:fold(
fun(K, V, D) -> fun(K, V, D) ->
@ -293,7 +276,9 @@ json_obj_root(Data0, Config) ->
[{K1, V1} | D] [{K1, V1} | D]
end, end,
[], [],
maps:without([time, gl, file, report_cb, msg, '$kind', mfa, level, line], Data0) maps:without(
[time, gl, file, report_cb, msg, '$kind', mfa, level, line, is_trace], Data0
)
), ),
lists:filter( lists:filter(
fun({_, V}) -> V =/= undefined end, fun({_, V}) -> V =/= undefined end,

View File

@ -56,8 +56,7 @@ enrich_report(ReportRaw, Meta) ->
end, end,
ClientId = maps:get(clientid, Meta, undefined), ClientId = maps:get(clientid, Meta, undefined),
Peer = maps:get(peername, Meta, undefined), Peer = maps:get(peername, Meta, undefined),
MFA = maps:get(mfa, Meta, undefined), MFA = emqx_utils:format_mfal(Meta),
Line = maps:get(line, Meta, undefined),
Msg = maps:get(msg, ReportRaw, undefined), Msg = maps:get(msg, ReportRaw, undefined),
%% turn it into a list so that the order of the fields is determined %% turn it into a list so that the order of the fields is determined
lists:foldl( lists:foldl(
@ -70,8 +69,7 @@ enrich_report(ReportRaw, Meta) ->
{topic, try_format_unicode(Topic)}, {topic, try_format_unicode(Topic)},
{clientid, try_format_unicode(ClientId)}, {clientid, try_format_unicode(ClientId)},
{peername, Peer}, {peername, Peer},
{line, Line}, {mfa, try_format_unicode(MFA)},
{mfa, mfa(MFA)},
{msg, Msg} {msg, Msg}
] ]
). ).
@ -84,7 +82,7 @@ try_format_unicode(Char) ->
case unicode:characters_to_list(Char) of case unicode:characters_to_list(Char) of
{error, _, _} -> error; {error, _, _} -> error;
{incomplete, _, _} -> error; {incomplete, _, _} -> error;
Binary -> Binary List1 -> List1
end end
catch catch
_:_ -> _:_ ->
@ -95,8 +93,8 @@ try_format_unicode(Char) ->
_ -> List _ -> List
end. end.
enrich_mfa({Fmt, Args}, #{mfa := Mfa, line := Line}) when is_list(Fmt) -> enrich_mfa({Fmt, Args}, Data) when is_list(Fmt) ->
{Fmt ++ " mfa: ~ts line: ~w", Args ++ [mfa(Mfa), Line]}; {Fmt ++ " mfa: ~ts", Args ++ [emqx_utils:format_mfal(Data)]};
enrich_mfa(Msg, _) -> enrich_mfa(Msg, _) ->
Msg. Msg.
@ -113,6 +111,3 @@ enrich_topic({Fmt, Args}, #{topic := Topic}) when is_list(Fmt) ->
{" topic: ~ts" ++ Fmt, [Topic | Args]}; {" topic: ~ts" ++ Fmt, [Topic | Args]};
enrich_topic(Msg, _) -> enrich_topic(Msg, _) ->
Msg. Msg.
mfa(undefined) -> undefined;
mfa({M, F, A}) -> [atom_to_list(M), ":", atom_to_list(F), "/" ++ integer_to_list(A)].

View File

@ -61,7 +61,8 @@
diff_lists/3, diff_lists/3,
merge_lists/3, merge_lists/3,
tcp_keepalive_opts/4, tcp_keepalive_opts/4,
format/1 format/1,
format_mfal/1
]). ]).
-export([ -export([
@ -529,6 +530,30 @@ tcp_keepalive_opts(OS, _Idle, _Interval, _Probes) ->
format(Term) -> format(Term) ->
iolist_to_binary(io_lib:format("~0p", [Term])). iolist_to_binary(io_lib:format("~0p", [Term])).
%% @doc Helper function for log formatters.
-spec format_mfal(map()) -> undefined | binary().
format_mfal(Data) ->
Line =
case maps:get(line, Data, undefined) of
undefined ->
<<"">>;
Num ->
["(", integer_to_list(Num), ")"]
end,
case maps:get(mfa, Data, undefined) of
{M, F, A} ->
iolist_to_binary([
atom_to_binary(M, utf8),
$:,
atom_to_binary(F, utf8),
$/,
integer_to_binary(A),
Line
]);
_ ->
undefined
end.
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
%% Internal Functions %% Internal Functions
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------

View File

@ -661,7 +661,7 @@ Can be one of:
- <code>utc</code>: the UTC time offset - <code>utc</code>: the UTC time offset
- <code>+-[hh]:[mm]</code>: user specified time offset, such as "-02:00" or "+00:00" - <code>+-[hh]:[mm]</code>: user specified time offset, such as "-02:00" or "+00:00"
Defaults to: <code>system</code>. Defaults to: <code>system</code>.
This config has no effect for when formatter is 'json' as the timestamp in JSON is miliseconds since epoch.""" This config has no effect for when formatter is 'json' as the timestamp in JSON is milliseconds since epoch."""
common_handler_time_offset.label: common_handler_time_offset.label:
"""Time Offset""" """Time Offset"""