refactor(trace): hash non-printable or too long names

This commit is contained in:
Zaiming Shi 2021-11-22 16:49:58 +01:00
parent 1c64a9d95d
commit 0f52824872
2 changed files with 65 additions and 21 deletions

View File

@ -160,22 +160,16 @@ filter_ip_address(#{meta := #{peername := Peername}} = Log, {IP, _Name}) ->
filter_ip_address(_Log, _ExpectId) -> ignore. filter_ip_address(_Log, _ExpectId) -> ignore.
install_handler(Who = #{name := Name, type := Type}, Level, LogFile) -> install_handler(Who = #{name := Name, type := Type}, Level, LogFile) ->
case handler_id(Name, Type) of HandlerId = handler_id(Name, Type),
{ok, HandlerId} -> Config = #{ level => Level,
Config = #{
level => Level,
formatter => ?FORMAT, formatter => ?FORMAT,
filter_default => stop, filter_default => stop,
filters => filters(Who), filters => filters(Who),
config => ?CONFIG(LogFile) config => ?CONFIG(LogFile)
}, },
Res = logger:add_handler(HandlerId, logger_disk_log_h, Config), Res = logger:add_handler(HandlerId, logger_disk_log_h, Config),
show_prompts(Res, Who, "Start trace"), show_prompts(Res, Who, "Start trace"),
Res; Res.
{error, _Reason} = Error ->
show_prompts(Error, Who, "Start trace"),
Error
end.
filters(#{type := clientid, filter := Filter, name := Name}) -> filters(#{type := clientid, filter := Filter, name := Name}) ->
[{clientid, {fun ?MODULE:filter_clientid/2, {ensure_list(Filter), Name}}}]; [{clientid, {fun ?MODULE:filter_clientid/2, {ensure_list(Filter), Name}}}];
@ -197,17 +191,23 @@ filter_traces(#{id := Id, level := Level, dst := Dst, filters := Filters}, Acc)
end. end.
handler_id(Name, Type) -> handler_id(Name, Type) ->
TypeBin = atom_to_binary(Type), try
case io_lib:printable_unicode_list(binary_to_list(Name)) of do_handler_id(Name, Type)
true when byte_size(Name) < 256 -> catch
NameHash = base64:encode(crypto:hash(sha, Name)), _ : _ ->
{ok, binary_to_atom(<<"trace_", TypeBin/binary, "_", NameHash/binary>>)}; Hash = emqx_misc:bin2hexstr_a_f_lower(crypto:hash(md5, Name)),
true -> do_handler_id(Hash, Type)
{error, <<"Name length must < 256">>};
false ->
{error, <<"Name must printable unicode">>}
end. end.
%% Handler ID must be an atom.
do_handler_id(Name, Type) ->
TypeStr = atom_to_list(Type),
NameStr = unicode:characters_to_list(Name, utf8),
FullNameStr = "trace_" ++ TypeStr ++ "_" ++ NameStr,
true = io_lib:printable_unicode_list(FullNameStr),
FullNameBin = unicode:characters_to_binary(FullNameStr, utf8),
binary_to_atom(FullNameBin, utf8).
ensure_bin(List) when is_list(List) -> iolist_to_binary(List); ensure_bin(List) when is_list(List) -> iolist_to_binary(List);
ensure_bin(Bin) when is_binary(Bin) -> Bin. ensure_bin(Bin) when is_binary(Bin) -> Bin.

View File

@ -0,0 +1,44 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%--------------------------------------------------------------------
-module(emqx_trace_handler_tests).
-include_lib("eunit/include/eunit.hrl").
handler_id_test_() ->
[{"normal_printable",
fun() ->
?assertEqual(trace_topic_t1, emqx_trace_handler:handler_id("t1", topic))
end},
{"normal_unicode",
fun() ->
?assertEqual('trace_topic_主题', emqx_trace_handler:handler_id("主题", topic))
end
},
{"not_printable",
fun() ->
?assertEqual('trace_topic_93b885adfe0da089cdf634904fd59f71',
emqx_trace_handler:handler_id("\0", topic))
end
},
{"too_long",
fun() ->
T = lists:duplicate(250, $a),
?assertEqual('trace_topic_1bdbdf1c9087c796394bcda5789f7206',
emqx_trace_handler:handler_id(T, topic))
end
}
].