diff options
author | Tim Watson <tim@rabbitmq.com> | 2014-03-20 14:04:32 +0000 |
---|---|---|
committer | Tim Watson <tim@rabbitmq.com> | 2014-03-20 14:04:32 +0000 |
commit | 53e244503f748b76c94142d879e9d51470f37a04 (patch) | |
tree | 108d3a103710b9e83ad3a46c0e52b7ae98d4f96a /src | |
parent | 357fcc0b63d32f563736afffc142781631ba49dc (diff) | |
download | rabbitmq-server-53e244503f748b76c94142d879e9d51470f37a04.tar.gz |
Initial stab at limiting term size during logging
Diffstat (limited to 'src')
-rw-r--r-- | src/rabbit_error_logger.erl | 5 | ||||
-rw-r--r-- | src/rabbit_sasl_report_file_h.erl | 9 | ||||
-rw-r--r-- | src/rabbit_trunc_term.erl | 76 |
3 files changed, 86 insertions, 4 deletions
diff --git a/src/rabbit_error_logger.erl b/src/rabbit_error_logger.erl index 313cc865..e921925e 100644 --- a/src/rabbit_error_logger.erl +++ b/src/rabbit_error_logger.erl @@ -87,9 +87,12 @@ publish1(RoutingKey, Format, Data, LogExch) -> %% 0-9-1 says the timestamp is a "64 bit POSIX timestamp". That's %% second resolution, not millisecond. Timestamp = rabbit_misc:now_ms() div 1000, + + %% TODO: is 'Data' ever in crash report format? I think not, but check... + Args = [rabbit_trunc_term:truncate_log_event(A) || A <- Data], {ok, _DeliveredQPids} = rabbit_basic:publish(LogExch, RoutingKey, #'P_basic'{content_type = <<"text/plain">>, timestamp = Timestamp}, - list_to_binary(io_lib:format(Format, Data))), + list_to_binary(io_lib:format(Format, Args))), ok. diff --git a/src/rabbit_sasl_report_file_h.erl b/src/rabbit_sasl_report_file_h.erl index 823816c0..1b950c23 100644 --- a/src/rabbit_sasl_report_file_h.erl +++ b/src/rabbit_sasl_report_file_h.erl @@ -66,13 +66,16 @@ init_file({File, Type}) -> end. handle_event(Event, State) -> - sasl_report_file_h:handle_event(Event, State). + Event2 = rabbit_trunc_term:truncate_log_event(Event), + sasl_report_file_h:handle_event(Event2, State). handle_info(Event, State) -> - sasl_report_file_h:handle_info(Event, State). + Event2 = rabbit_trunc_term:truncate_log_event(Event), + sasl_report_file_h:handle_info(Event2, State). handle_call(Event, State) -> - sasl_report_file_h:handle_call(Event, State). + Event2 = rabbit_trunc_term:truncate_log_event(Event), + sasl_report_file_h:handle_call(Event2, State). terminate(Reason, State) -> sasl_report_file_h:terminate(Reason, State). diff --git a/src/rabbit_trunc_term.erl b/src/rabbit_trunc_term.erl new file mode 100644 index 00000000..f519aad5 --- /dev/null +++ b/src/rabbit_trunc_term.erl @@ -0,0 +1,76 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (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.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and +%% limitations under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developer of the Original Code is GoPivotal, Inc. +%% Copyright (c) 2007-2014 GoPivotal, Inc. All rights reserved. +%% + +-module(rabbit_trunc_term). + +-export([truncate_log_event/1, shrink_term/1]). + +truncate_log_event({Type, GL, {Pid, Format, Args}}) + when Type =:= error orelse + Type =:= info_msg orelse + Type =:= warning_msg -> + {Type, GL, {Pid, Format, [shrink_term(T) || T <- Args]}}; +truncate_log_event({Type, GL, {Pid, ReportType, Report}}) + when Type =:= error_report orelse + Type =:= info_report orelse + Type =:= warning_report -> + Report2 = case ReportType of + crash_report -> [[{K, shrink_term(V)} || {K, V} <- R] || + R <- Report]; + _ -> [{K, shrink_term(V)} || {K, V} <- Report] + end, + {Type, GL, {Pid, ReportType, Report2}}; +truncate_log_event(Event) -> + Event. + +shrink_term(T) -> shrink_term(T, 10). + +%% TODO: avoid copying +%% TODO: can we get away with using binary:part/3 (OTP vsn requirements)? +%% TODO: reconsider depth limit handling +shrink_term(T, 0) -> T; +shrink_term(T, N) when is_binary(T) andalso size(T) > N -> + case size(T) - N of + Sz when Sz >= 1 -> Head = binary:part(T, 0, N-3), + <<Head/binary, <<"...">>/binary>>; + _ -> T + end; +shrink_term([A|B], N) when not is_list(B) -> + shrink_term([A,B], N); +shrink_term(T, N) when is_list(T) -> + IsPrintable = io_lib:printable_list(T), + case length(T) > N of + true when IsPrintable -> + lists:append(lists:sublist(T, N-3), "..."); + true -> + lists:append([shrink_term(E, N-1) || E <- lists:sublist(T, N-1)], + ['...']); + false when IsPrintable -> + T; + false -> + [shrink_term(E, N-1) || E <- T] + end; +shrink_term(T, N) when is_tuple(T) -> + case tuple_size(T) > N of + true -> list_to_tuple( + lists:append([shrink_term(E, N-1) || + E <- lists:sublist(tuple_to_list(T), N-1)], + ['...'])); + false -> list_to_tuple([shrink_term(E, N-1) || + E <- tuple_to_list(T)]) + end; +shrink_term(T, _) -> T. + |