sbt / sbt

sbt, the interactive build tool
https://scala-sbt.org
Apache License 2.0
4.81k stars 937 forks source link

State.log doesn't properly honor logLevel #4097

Open eatkins opened 6 years ago

eatkins commented 6 years ago

I was working on fixing #3869 and found that state.log doesn't work correctly.

steps

This minimal build.sbt illustrates the issue

lazy val testLog = taskKey[Unit]("Log")
testLog := {
  state.value.log.debug("foo")
  state.value.log.info("info")
}

problem

If I run debug, warn, error, etc. in the console, "info" is always printed no matter what. The "foo" debug line is never printed.

expectation

That "foo" is logged after debug and that neither is logged for levels above info

notes

I get the expected behavior with sbt 0.13.17. I suspect the issue is related to one of the TODOs in https://github.com/sbt/sbt/pull/2907/files @eed3si9n sbt version: 1.1.x

dwijnand commented 5 years ago

It's a shame this regression from sbt 0.13 is still present.

Here's my workaround:

final class PoorMansDebugLogger(log: Logger) extends Logger {
  val isDebugEnabled = log match {
    case x: AbstractLogger => x.atLevel(Level.Debug)
    case x: sbt.internal.util.ManagedLogger => {
      val field = classOf[sbt.internal.util.ManagedLogger].getDeclaredField("xlogger")
      field.setAccessible(true)
      val logger = field.get(x).asInstanceOf[org.apache.logging.log4j.Logger]
      logger.isDebugEnabled
    }
  }

  def trace(t: => Throwable): Unit = log.trace(t)
  def success(message: =>String): Unit = log.success(message)

  def log(level: Level.Value, message: =>String): Unit = {
    if (level == Level.Debug && isDebugEnabled)
      println(s"[debug] $message")
    else
      log.log(level, message)
  }
}