depth in logger_formatter and io_lib

Martin Björklund mbj+erl@REDACTED
Wed Nov 17 08:15:42 CET 2021

We're experimenting with the `depth` parameter to logger, which
translates to a depth on io:fwrite ~P/W.  The reason is that we want
to avoid too large printouts in e.g., crash reports, but still
get relevant info.

But the result is a bit surprising (to us).  Compare:

1> io:put_chars(io_lib:format("~P~n", ["hello world", 2])).
"hello world"
2> io:put_chars(io_lib:format("~P~n", [<<"hello world">>, 2])).

It turns out that printable lists are printed as a whole, but for
printable binaries, 4 characters cost 1 depth.

Why are printable binaries treated differently than printable lists?

We're using binaries for strings.  Let's say that "useful" data from
such a binary is 128 characters.  This means that we have to have
a depth of at least 32 (in reality much larger).  But this also means
that other terms (tuples, maps etc) will be printed with a larger
depth than we want.

I think that it is unfortunate that the depth parameter controls both
the intuitive definition of "depth", and the length of printable

So I implemented an option to io_lib:format (and logger_formatter)
that controls the length of printable strings.  It is used for both
lists and binaries:

3> io:put_chars(io_lib:format("~P~n", [<<"hello world">>, 2], [{printable_string_limit, 10}])).
<<"hello worl"...>>
4> io:put_chars(io_lib:format("~P~n", ["hello world", 2], [{printable_string_limit, 10}])).    
"hello worl"...

With this, we can configure logger:

     {handler, default, logger_std_h,
      #{formatter =>
             #{single_line => false,
               depth => 24,
               printable_string_limit => 128,
               time_designator => $\s,
               time_offset => []}}}},

If there is interest from OTP, I can create a PR.

Another, simpler, option could be to simply treat printable binaries
the same way that printable lists are treated today.  That's a much
smaller fix, but it changes current behavior.  Also, with that fix, if
the list/binary happens to be very large and printable (perhaps it
contains base64-encoded data) then everything will be printed.


More information about the erlang-questions mailing list