如何使用 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()
,但您无法控制日志级别(debug
、warning
、error
)。
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
}
看了SBT中的documentation about logging,知道了如何通过streams.value.log
从任务中登录。我广泛地这样做。但是从自定义命令记录呢?
在命令中我们可以使用 state, and the only interesting thing for logging is globalLogging,但我不知道如何使用它。
一种方法是使用 println()
,但您无法控制日志级别(debug
、warning
、error
)。
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
}