-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ConsoleLogger for more fully featured log printing #25370
Conversation
Great! One thing that I wanted to do also is to remove the "exception = " prefix, which IMO looks a bit funny. I think it would look nicer with something like the following: julia> @info "An error while creating the log event" sqrt(-1)
┌ Error: Exception while generating log record in module Main at REPL[1]:1
│ DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
└ @ Main REPL[1]:1 |
Perhaps turn off the line info by default? Also, why are we printing |
I'd prefer to keep the |
[Edit: moving to another issue...] |
The formatting of stacktraces is very non related to this PR here. Please open a new issue for that discussion. |
stdlib/Logging/src/ConsoleLogger.jl
Outdated
dsize = displaysize(logger.stream) | ||
width = dsize[2] | ||
locationstr = string(levelstr, " @ ", _module, " ", basename(filepath), ":", line) | ||
singlelinewidth = 2 + length(msglines[1]) + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it guaranteed that msglines
has at least one element? (split("")
gives an empty array in 0.6)
stdlib/Logging/src/ConsoleLogger.jl
Outdated
singlelinewidth = 2 + length(msglines[1]) + | ||
(prefixwithlevel ? length(levelstr) + 2 : 0) + | ||
length(locationstr) | ||
if length(msglines) + length(kwargs) == 1 && singlelinewidth <= width |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If length(msglines) == 0
and length(kwargs) == 1
, kwarg would not be printed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, this is also a bug in SimpleLogger
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually no - split("", '\n')
gives an array of length 1, so this is actually fine. I'll add a corresponding test case.
end | ||
end | ||
end | ||
print_with_color(color, iob, "└ ", bold=true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with single line mode, locationstr
could be printed at the last message/kwarg line if it fits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be nice. It does complicate the implementation significantly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'll punt on this for now. Getting right justification correct in general seems to involve removing ANSI escape sequences from the formatted values to determine the text width of the line prefix. It really seems somewhat messy.
Yes there's a bit of tension here between having general key value pairs and the specific, very useful case of transporting an exception as context for a message. I'm not sure what to do about that; it seems a little less than ideal to give no indication of the key. But it also seems redundant and noisy to have the |
The same backtrace filtering as the REPL does should likely be done here as well. |
But in the case failure when generating the message the key |
Piggybacking on the It is a big difference between an exception getting thrown when creating the logging message and just capturing an exception with the |
I think we should fix this by setting the But I think worrying about this is a bit of a distraction: these types of messages should not be something you'll see often, and I'd like to focus this PR on getting the formatting as readable as possible in the common case. For that, I think markdown based formatting of the log message is probably the next thing to tackle (in addition to cleaning up various issues people have pointed out above). |
The underlying issue is there's currently no distinction between keys which have special meaning to the system (currently |
Start of a ConsoleLogger optimized for viewing log records in the REPL. This is the SimpleLogger code copied and modified to: * Provide configurable metadata formatting * Right justify some of the metadata * Use show() and showerror() for formatting values in ConsoleLogger key value pairs. * Set the :limit IOContext key to sensibly show approximations of large data structures Also make this the default logger type so that users can get interface improvements by upgrading the stdlib Logging library rather than being bound to Base.
This is to allow clean filtering of log event failures when these are automatically caught by the system.
305e519
to
63ecd06
Compare
Ok, I think I've got a much cleaner implementation of metadata printing: there's now a Latest default format: Regarding the reporting of exceptions generated within the system, I've modified the group to I think this is probably useful enough to merge now. Further changes like markdown handling and more sophisticated key value pair printing can come later. |
Looks very nice! |
CI failures look unrelated - freebsd failed when cloning a git repo, win32 failed when building deps. |
well, all CI failed on master: |
Ok. What. That's extremely bad, but also confusing given that CI succeeded on Travis, circleci, appveyor (win64). I'm looking into it immediately. |
Ah, I'm not going crazy. This was a clash with changes introduced by #25289 which was merged after the tests were run. |
Why was right justification included? It looks messy and it's hard to visually match info to line numbers when the terminal is set to wide. |
So does the option of having the metadata mixed with the messages. If you want to see the message 90% of the time and the metadata 10% of the time it's better to put it out of the way where it's not distracting. We can add an option for the maximum right justification of the metadata - set it to 80 columns or something by default. |
Can we just make right justification opt-in? |
The design goal I'm trying to follow for My guess is the average user wants to see output more like |
ex,bt = e | ||
showerror(io, ex, bt; backtrace = bt!=nothing) | ||
end | ||
showvalue(io, ex::Exception) = showvalue(io, (ex,catch_backtrace())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should do this --- there's no way to know whether the result of catch_backtrace
corresponds to the given exception. This mechanism is already pretty fragile and can cause quite a bit of confusion, e.g. #19979
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One alternative is to have people pass it explicitly everywhere:
try
# do stuff
catch ex
@error "Extra information about something bad" exception=ex,catch_backtrace()
end
This might be an acceptable syntax burden?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On further thought, to be completely safe from the problems of #19979 the pattern would have to look like
try
# do stuff
catch ex
bt = catch_backtrace()
@error "Extra information about something bad" exception=ex,bt
end
Hmm. This breaks the general principle that log events should be lazily generated.
Overall nice improvement! 👍 |
As a counterpoint, right justification strikes me as cleaner. (I tend to vertically split terminal windows on wide screens, making the separation a non-issue.) Best! |
@Sacha0 - interesting, this is how I use my terminals as well. Another option (suggested on slack) is to use something other than spaces as padding. Here's two examples with either full width or aligned to 100 columns. |
Some editors/terminals highlight the line under cursor.
Solid lines look a little bit too intrusive. |
I tried a lot of different variants of this with various characters. It's a little more light weight, but not substantially different. |
I find the horizontal lines quite distracting. Best! |
I really think the old behavior of printing the |
Also, I would add that reviewing these changes has been made rather difficult by the fact that there are major functional changes mixed in with aesthetic changes. I'm all on board with adding the ConsoleLogger here but aspect of the previous incarnation of the output format were preferable. |
Sorry about that, this could have been a bit better factored in a couple of places. The original intention was that this be entirely aesthetic changes. Jeff's |
Here I've taken
SimpleLogger
, copied it into the logging module, and started on some formatting features which will make it a lot nicer to use. I've also made it the default instead ofSimpleLogger
which we might consider making even simpler.Primarily, the printing of key value pairs has been beefed up so that large data structures are summarized with the
:limit=>true
IOContext setting (may be disabled with a setting), and exceptions are now printed usingshowerror
including a backtrace if it's supplied or inferred from the contents ofcatch_backtrace()
.Formatting of exceptions:
Show limiting:
I've also incorporated the right justification of metadata to get this out of the way, and removed the
Info
andDebug
prefix by default, but with a setting to control this. The current default style:@fredrikekre