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

Debug logging in context #674

Merged
merged 10 commits into from
Oct 29, 2018
Merged

Debug logging in context #674

merged 10 commits into from
Oct 29, 2018

Conversation

ioleo
Copy link
Contributor

@ioleo ioleo commented Oct 14, 2018

Supersedes #638, implements #333.

Copy link
Contributor

@jvican jvican left a comment

Choose a reason for hiding this comment

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

This looks good 👍 I've had a first quick look, but I'm gonna let @tues go through it in detail. Could we add a new log context test suite to check that we don't regress and only show logs corresponding to a given context?

@jvican jvican added enhancement cli ergonomics Any change that affects developer ergonomics and the easiness of use of bloop. community Any change or proposal that is contributed by the Open Source Community. labels Oct 14, 2018
@ioleo
Copy link
Contributor Author

ioleo commented Oct 14, 2018

@jvican Yeah, definately. I just wanted to push this out to get some feedback. Also I'm new to bloop, so please review to make sure all logs are tied to the right context.

Copy link
Contributor

@jvican jvican left a comment

Choose a reason for hiding this comment

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

@tues Can you review this? I'd like to merge this PR soon since it'll be a blocker for supporting originId in BSP.


object Timer {
@inline def timed[T](logger: Logger, prefix: Option[String] = None)(op: => T): T = {
val start = System.nanoTime()
try op
finally {
val elapsed = (System.nanoTime() - start).toDouble / 1e6
logger.debug(s"Elapsed ${prefix.map(s => s"($s)").getOrElse("")}: $elapsed ms")
logger.debugInContext(s"Elapsed ${prefix.map(s => s"($s)").getOrElse("")}: $elapsed ms")(LogContext.All)
Copy link
Contributor

Choose a reason for hiding this comment

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

We may want to take the log context as an optional parameter like prefix, defaulting on LogContext.All if none is provided.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem is, we can't change the Logger interface. I've played around with implicit shadowing technique and it works for simple scenarios (I've presented POC to @tues on slack), but again, we've got cases where we have nested loggers, where we'd have to resolve to reflection to call the underlaying loggers "non-shadowed" (original) method. Also, its a bit hacky - I'm not sure you'd want that kind of solution in the library.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have force pushed a solution to this problem. The solution requires to know how the rules for ambiguous overloads work, but after some plumbing here and there I've managed to replace debugInContext by debug. I've also intentionally removed the default parameters for the implicit because I want the use of debug to be as explicit as possible and if developers of bloop call debug in a place where there's no implicit log context, they have to pass it manually.

I've also added a test case to make sure it works. Check it out, please. /cc @tues

}

object LogContext {

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's remove this new line 😄

jvican and others added 5 commits October 23, 2018 17:04
The solution required to do this change without modifying
sbt.testing.Logger's interface relies on the linearization order and the
check for ambiguous overloads. Typically, if two methods are defined in
an interface and they have the same public interface, except that one
takes an implicit and the other one doesn't, the compiler fails with an
ambiguous overload error when one of the methods is used (e.g.
`logger.debug(msg)` refers to `logger.debug(msg)(implicit ctx)` or
`logger.debug(msg)`?).

To fix this problem, we override the version that doesn't take a
parameter in a super class of `BloopLogger`, which is the common logging
interface across bloop and is implemented by many different types of
bloop loggers. Then, we add two abstract methods that must be
implemented by subclasses:

1. An implementation of a `private[logging] def printDebug`, which is
   used by the overridden simple `debug` in `BaseSbtLogger`.
2. An implementation of the long debug method that we want the compiler
   to select for every use of `logger.debug(msg)`.

This trick helps us remove `debugInContext` and simplify the logger API.
From now on, everyone will be forced to use `debug` and provide a
context if there is not an implicit one.
We didn't run this before, but now we add a way to test that all the
commands in the doc generator are correctly parsed by bloop.
A debug filter can be selected by the user by typing `--debug $FILTER`
in the command-line bloop tool. Users can now select several debug
filters.

They are called debug filters instead of log contexts because the latter
name can be misleading. A log context is currently only used for
debugging purposes, so it's better to keep its semantics as precise as
possible.

This commit also makes `--debug` enable verbose debugging automatically,
which before required the user to pass `--verbose` to see the logs.
@jvican
Copy link
Contributor

jvican commented Oct 24, 2018

I've just added another commits to:

  1. Rename LogContext to DebugFilter (i've left some names ctx around as I don't really bother about their name, but the important thing is that the type has the correct name to avoid confusion).
  2. Use a list of DebugFilters in the CLI so that the user can pass several --debug compilation --debug test to debug both compilation and test.
  3. Add a bunch of tests to check for subsumption in isEnabled and check that the parser works for our debug invocations.

The PR is ready to review by either @tues or @ioleo.

@ioleo
Copy link
Contributor Author

ioleo commented Oct 25, 2018

@jvican good job, I'm glad you've worked around the API issue. I'm really curious about the solution - I've spent a better part of one evening trying to figure it out 👍 I'll try to find some time for review soon.

@jvican
Copy link
Contributor

jvican commented Oct 25, 2018

@ioleo The solution is not obvious, so I'm planning to write a blog post about it. If @tues cannot review today, I'll probably merge this PR right away because I'm blocked by it to implement some BSP features, but I would still love that someone goes through the diff and let me know their feedback -- I would be happy to follow up with another PR addressing it.

@jvican
Copy link
Contributor

jvican commented Oct 26, 2018

@ioleo I wrote a blog post describing the technique I used for the design of the overloaded debug https://jvican.github.io/post/implicit-parameter-overload/

I haven’t yet tweeted about it but feel free to proof read it and let me know if I can improve something.

@jvican
Copy link
Contributor

jvican commented Oct 29, 2018

I'm gonna go ahead and merge this 😄 I'm happy to address feedback on a follow-up PR.

@jvican jvican merged commit e7cbd16 into scalacenter:master Oct 29, 2018
@ioleo
Copy link
Contributor Author

ioleo commented Oct 29, 2018

@jvican sure 👍, sorry I'm just loaded with work currently, had no time to look into it, but I will eventually get back to you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cli community Any change or proposal that is contributed by the Open Source Community. enhancement ergonomics Any change that affects developer ergonomics and the easiness of use of bloop.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants