Skip to content
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

[WIP] More flexible and convenient logging #23712

Closed
wants to merge 26 commits into from
Closed

Conversation

c42f
Copy link
Member

@c42f c42f commented Sep 14, 2017

Here's a WIP for making julia logging systematic, flexible and fast, as described in part in the logging julep, and currently being prototyped in MicroLogging.jl. It turns out that there's quite a few disparate mechanisms in use already for logging in Base, so this WIP is about looking at each use case in turn. Attacking depwarn has been particularly entertaining, and I think the result so far is faster and significantly more accurate. As a side effect of this work, I think we should be easily able to generate a depwarn report after any given julia run with a precise list of locations to fix.

As a whole this is probably not that close to merging yet, but a lot of the key pieces are in place. There's a design tracker over at c42f/MicroLogging.jl#5 with more detail on unanswered issues.

I've included only a bare minimum of log formatting machinery here with the idea that this is better done in a standard library package. With that in mind, I'd suggest checking out the MicroLogging master branch for logs which are actually formatted in a readable way for interactive work.

base/logging.jl Outdated
# itself.
struct LogState
min_enabled_level::LogLevel
logger::AbstractLogger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this not concretely typed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LogState itself is a leaf type; AbstractLogger is not. This is arranged so that some minimal part of the state (only min_enabled_level at the moment, but possibly some additional things) is accessible without generic dispatch.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I get it, you concretely typed as much as possible, but logger can't be concretely typed if you want to be able to change it easily?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. The design problem is to decide which aspects of log filtering are sufficiently useful and fast that every user defined logger must support them - those can be cached in the concretely typed log state, and inlined at the call site.

base/logging.jl Outdated
const _min_enabled_level = Ref(Debug)


# A concretely typed cache of data extracted from the logger, plus the logger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these comments look like they should be docstrings.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The convention I'm using is that implementation details have comments but no docstrings. How is this generally handled in Base? I don't want to give people the idea that Logging.LogState (for example) is part of the public API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems sensible. A quick browse shows me that there is a non-exported function in Enums.jl with a comment rather than a doc-string, so it seems similar to what you're doing.

@c42f
Copy link
Member Author

c42f commented Sep 24, 2017

Hmm, mysterious - it looks like #17997 broke something I was doing on this branch. I'm now getting odd errors regarding is_root_module during bootstrap even after rebasing locally and fixing some conflicts. [Edit - long since rebased & fixed]

@@ -219,13 +219,13 @@ function merge!(repo::GitRepo, anns::Vector{GitAnnotated}, fastforward::Bool;
elseif ffpref == Consts.MERGE_PREFERENCE_FASTFORWARD_ONLY
if isset(ma, Cint(Consts.MERGE_ANALYSIS_FASTFORWARD))
if length(anns) > 1
warn("Unable to perform Fast-Forward merge with mith multiple merge heads.")
@warn "Unable to perform Fast-Forward merge with mith multiple merge heads." repo
Copy link
Contributor

@helgee helgee Oct 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not your fault, but "with mith"? 😂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/with mith/mit

;) 🇩🇪

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

Some minor edits here to make things suitable for Base.
Use handle_message rather than dispatch_message, as not all message
handling is pure dispatch (the message may be stored rather than sent
elsewhere).

Reuse the name dispatch_message internally.
* Forward depwarn() calls to new backend
* Use caller frame pointer as message id.  This makes initial
  first-pass deduplication of depwarns quite a lot faster.
* Change --depwarn=error to --depwarn=throw for clarity
* Introduce defines for log levels into julia.h
Forward all frontend depwarn messages through to the julia logging
system for consistency of formatting and dispatch.  Deciding whether a
depwarn should appear as an thrown error is also now handled outside
flisp to keep this decision in one place where possible.

Detail:

* Ensure that deprecation-message forwards to the logging system.  Also
  include file and line number metadata
* Remove jl_parse_depwarn(), flisp *depwarn* and related scheme code as
  this can be handled on the julia side.
* Rename syntax_deprecation_warnings(false) to
  without_syntax_deprecations, as this was only ever used to turn syntax
  deprecations off.
* Ensure that all lowering depwarns with existing line number
  information get this passed through as accessible metadata rather than
  as a string.
* Use distinct functions for depwarns coming from the parser vs
  lowering, as these get line number information in a different way.

TODO:
* Figure out a decent `id` for the syntax and lowering depwarn messages
* Make without_syntax_deprecations filter only depwarn messages, rather
  than everything!
* Additional exports
* Fallback error message formatting
* Minor global logger init min level bug
For now this seems like the right thing as error and informational
reporting is a core requirement for a compiler - parts of the frontend
and runtime now call the logging system when it's available.
These can be used to transform a lot of printf()'s into log statements.
This allows users to control whether a custom logger type will catch
exceptions during message creation and log them, or simply allow them to
pass through.
Provides a general tool to log information from the flisp frontend code.
Make the syntax deprecations use this instead of using the purpose built
syntax_depwarn function on the julia side.

Also reinstate flisp-level awareness of the depwarn level.  It's just
simpler.
This is purely for implementation convenience.  It restricts the levels
artifically, but it's hard to imagine what anyone would do with more than
a million custom levels.
This can be handled in a much nicer way by installing a logger in-process.

TODO: Define such a logger and test it!
@StefanKarpinski
Copy link
Sponsor Member

Should we get some review on this?

@c42f
Copy link
Member Author

c42f commented Nov 4, 2017

Some high level feedback would be great. Particularly around how the system supports the various logging needs of base.

Just don't be too disturbed if there's a few details which are still broken here - it's definitely still a WIP, and I plan to pull it apart into several pieces for detailed review.

Port from MicroLogging refactoring

Also rearrange exports to avoid exporting AbstractLogger-related methods.
@ViralBShah
Copy link
Member

cc @tanmaykm

@c42f c42f mentioned this pull request Nov 6, 2017
6 tasks
@c42f
Copy link
Member Author

c42f commented Nov 7, 2017

Ok, I've pulled out what I think is a mostly coherent subset of these changes into #24490 . This WIP is still useful for the moment as context for the larger ongoing work.

@c42f c42f mentioned this pull request Dec 15, 2017
15 tasks
@c42f
Copy link
Member Author

c42f commented Jan 5, 2018

This is superseded now by #24490 and various follow on work.

@c42f c42f closed this Jan 5, 2018
@c42f c42f added the logging The logging framework label Jan 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
logging The logging framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants