如何使用 debug/warning/error 从命令和控制日志级别登录?

How to log from command and control log level using debug/warning/error?

看了SBT中的documentation about logging,知道了如何通过streams.value.log从任务中登录。我广泛地这样做。但是从自定义命令记录呢?

在命令中我们可以使用 state, and the only interesting thing for logging is globalLogging,但我不知道如何使用它。

一种方法是使用 println(),但您无法控制日志级别(debugwarningerror)。

tl;dr 我主要是在猜测,但评论部分也不合适。

sbt 0.13.8-M2 这里。

我在 build.sbt 中使用以下 hello 命令到达 streams.value.log:

val hello: Command = Command.command("hello") { (s: State) =>
    val extracted: Extracted = Project.extract(s)
    import extracted._

    // streams.value.log
    val Value(v) = Project.evaluateTask(streams in currentRef, s).get
    println(v.log)
    s
}

commands += hello

但是,v 已初始化,似乎为时已晚,无法使用它或不适用于命令,因此出现以下堆栈跟踪:

[sbt-learning-space]> hello
java.lang.RuntimeException: Streams for '{file:/Users/jacek/dev/sandbox/sbt-learning-space/}sbt-learning-space/*:streams' have been closed.
    at scala.sys.package$.error(package.scala:27)
    at sbt.std.Streams$$anon$$anon.checkOpen(Streams.scala:146)
    at sbt.std.Streams$$anon$$anon.make(Streams.scala:127)
    at sbt.std.Streams$$anon$$anon.text(Streams.scala:113)
    at sbt.std.Streams$$anon$$anon.log(Streams.scala:124)
    at 9b92cf2e7230691a78$$anonfun.apply(build.sbt:71)
    at 9b92cf2e7230691a78$$anonfun.apply(build.sbt:64)
    at sbt.Command$$anonfun$command$$anonfun$apply.apply(Command.scala:29)
    at sbt.Command$$anonfun$command$$anonfun$apply.apply(Command.scala:29)
    at sbt.Command$.process(Command.scala:92)
    at sbt.MainLoop$$anonfun$$anonfun$apply.apply(MainLoop.scala:98)
    at sbt.MainLoop$$anonfun$$anonfun$apply.apply(MainLoop.scala:98)
    at sbt.State$$anon.process(State.scala:184)
    at sbt.MainLoop$$anonfun.apply(MainLoop.scala:98)
    at sbt.MainLoop$$anonfun.apply(MainLoop.scala:98)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
    at sbt.MainLoop$.next(MainLoop.scala:98)
    at sbt.MainLoop$.run(MainLoop.scala:91)
    at sbt.MainLoop$$anonfun$runWithNewLog.apply(MainLoop.scala:70)
    at sbt.MainLoop$$anonfun$runWithNewLog.apply(MainLoop.scala:65)
    at sbt.Using.apply(Using.scala:24)
    at sbt.MainLoop$.runWithNewLog(MainLoop.scala:65)
    at sbt.MainLoop$.runAndClearLast(MainLoop.scala:48)
    at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:32)
    at sbt.MainLoop$.runLogged(MainLoop.scala:24)
    at sbt.StandardMain$.runManaged(Main.scala:53)
    at sbt.xMain.run(Main.scala:28)
    at xsbt.boot.Launch$$anonfun$run.apply(Launch.scala:109)
    at xsbt.boot.Launch$.withContextLoader(Launch.scala:128)
    at xsbt.boot.Launch$.run(Launch.scala:109)
    at xsbt.boot.Launch$$anonfun$apply.apply(Launch.scala:35)
    at xsbt.boot.Launch$.launch(Launch.scala:117)
    at xsbt.boot.Launch$.apply(Launch.scala:18)
    at xsbt.boot.Boot$.runImpl(Boot.scala:41)
    at xsbt.boot.Boot$.main(Boot.scala:17)
    at xsbt.boot.Boot.main(Boot.scala)
[error] Streams for '{file:/Users/jacek/dev/sandbox/sbt-learning-space/}sbt-learning-space/*:streams' have been closed.
[error] Use 'last' for the full log.

我的理解是命令不在 streams.value.log 的范围内,因为它们要配置 state 进行设置。

State class 有一个 log 成员,通过一些隐含的魔法添加,您可以使用。如果没有隐式魔法,您可以使用显式 globalLogging 成员来访问 full 记录器。

示例:

def hello = Command.command("hello") { state =>
  // These are equivalent
  state.log.info("Hello!")
  state.globalLogging.full.info("Hello!")

  state
}