From 39e0f10b1b9e3d449568b0763155aee5523938e8 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Fri, 12 Jan 2024 23:02:12 -0800 Subject: [PATCH 1/2] airspec (feature): Support setting log level with -l (loglevel) --- .../src/main/scala/wvlet/log/Logger.scala | 2 +- .../wvlet/airspec/runner/AirSpecLogger.scala | 2 ++ .../airspec/runner/AirSpecSbtRunner.scala | 34 +++++++++++++------ docs/airspec.md | 9 ++++- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/airframe-log/src/main/scala/wvlet/log/Logger.scala b/airframe-log/src/main/scala/wvlet/log/Logger.scala index 7ce4141045..d5c4688fc7 100644 --- a/airframe-log/src/main/scala/wvlet/log/Logger.scala +++ b/airframe-log/src/main/scala/wvlet/log/Logger.scala @@ -256,7 +256,7 @@ object Logger { def apply(loggerName: String): Logger = { loggerCache.getOrElseUpdate(loggerName, new Logger(loggerName, jl.Logger.getLogger(loggerName))) } - + def getDefaultLogLevel: LogLevel = rootLogger.getLogLevel def setDefaultLogLevel(level: LogLevel): Unit = { diff --git a/airspec/src/main/scala/wvlet/airspec/runner/AirSpecLogger.scala b/airspec/src/main/scala/wvlet/airspec/runner/AirSpecLogger.scala index c1770cc205..3518e771a8 100644 --- a/airspec/src/main/scala/wvlet/airspec/runner/AirSpecLogger.scala +++ b/airspec/src/main/scala/wvlet/airspec/runner/AirSpecLogger.scala @@ -52,6 +52,8 @@ private[airspec] class AirSpecLogger() extends AnsiColorPalette { private val airSpecLogger = { // Use a different spec logger for each AirSpecRunner val l = Logger(f"wvlet.airspec.runner.AirSpecLogger_${hashCode()}%x") + // Airspec logger needs to report at least INFO level log regardless of the global log level + l.setLogLevel(wvlet.log.LogLevel.INFO) l.setFormatter(BareFormatter) l } diff --git a/airspec/src/main/scala/wvlet/airspec/runner/AirSpecSbtRunner.scala b/airspec/src/main/scala/wvlet/airspec/runner/AirSpecSbtRunner.scala index 853d6a7bfa..3bdb78f041 100644 --- a/airspec/src/main/scala/wvlet/airspec/runner/AirSpecSbtRunner.scala +++ b/airspec/src/main/scala/wvlet/airspec/runner/AirSpecSbtRunner.scala @@ -15,7 +15,7 @@ package wvlet.airspec.runner import sbt.testing.{Task, TaskDef} import wvlet.airspec.runner.AirSpecSbtRunner.AirSpecConfig -import wvlet.log.{LogSupport, Logger} +import wvlet.log.{LogSupport, Logger, LogLevel} import scala.util.matching.Regex @@ -39,6 +39,7 @@ private[airspec] class AirSpecSbtRunner(config: AirSpecConfig, val remoteArgs: A // use airframe's code before sbt detaches the class loader taskLogger.clearHandlers Logger.clearAllHandlers + Logger.setDefaultLogLevel(LogLevel.INFO) "" } @@ -55,18 +56,31 @@ private[airspec] class AirSpecSbtRunner(config: AirSpecConfig, val remoteArgs: A private[airspec] object AirSpecSbtRunner extends LogSupport { def newRunner(args: Array[String], remoteArgs: Array[String], testClassLoader: ClassLoader): AirSpecSbtRunner = { - // Set log levels given in the command line args: -L(package)=(log level) - args.filter(_.startsWith("-L")).foreach { l => - l.stripPrefix("-L").split("=") match { - case Array(pkg, level) => - val logLevel = wvlet.log.LogLevel(level) - wvlet.log.Logger(pkg).setLogLevel(logLevel) - case _ => - warn(s"Ignoring invalid argument: ${l}. Use -L(package)=(log level) to set log levels") + // Set log level with -l (log level) + val remaining = Array.newBuilder[String] + var i = 0 + var logLevel: LogLevel = Logger.getDefaultLogLevel + while (i < args.length) { + args(i) match { + case "-l" if i < args.length - 1 => + val logLevel = LogLevel(args(i + 1)) + Logger.setDefaultLogLevel(logLevel) + i += 1 + case arg if arg.startsWith("-L") => + arg.stripPrefix("-L").split("=") match { + case Array(pkg, level) => + val logLevel = LogLevel(level) + Logger(pkg).setLogLevel(logLevel) + case _ => + warn(s"Ignoring invalid argument: ${arg}. Use -L(package)=(log level) to set log levels") + } + case other => + remaining += other } + i += 1 } - new AirSpecSbtRunner(AirSpecConfig(args), remoteArgs, testClassLoader) + new AirSpecSbtRunner(AirSpecConfig(remaining.result()), remoteArgs, testClassLoader) } case class AirSpecConfig(args: Array[String]) { diff --git a/docs/airspec.md b/docs/airspec.md index 37a90bef5a..e45255266f 100644 --- a/docs/airspec.md +++ b/docs/airspec.md @@ -170,6 +170,7 @@ $ sbt > testOnly -- (pattern)/(pattern) # Run nested tests matching the nested pattern (/ is a dlimiter) # Configure log levels of airframe-log +> testOnly -- -l (level) # Set the default log level > testOnly -- -L(package):(level) # Set log level for a package # sbt's default test functionalities: @@ -192,7 +193,13 @@ Test names will be checked as case-insensitive partial match, so you only need t ### Configure Log Levels -AirSpec natively supports [airframe-log](https://wvlet.org/airframe/docs/airframe-log.html) for logging. To temporally change the log level of your test classes, use `-L` option: +AirSpec natively supports [airframe-log](https://wvlet.org/airframe/docs/airframe-log.html) for logging. To temporally change the log level, use `-l (log level)` option: + +```scala +> testOnly -- -l debug +``` + +To change the log level only for a specific package or a class, use `-L(package or class)=(log level)` option: ```scala > testOnly -- -Lorg.mydomain.myapp:debug From 15b48c0ffd660082b416579fca7ce1ac8fc24bda Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Fri, 12 Jan 2024 23:08:12 -0800 Subject: [PATCH 2/2] reformat --- airframe-log/src/main/scala/wvlet/log/Logger.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airframe-log/src/main/scala/wvlet/log/Logger.scala b/airframe-log/src/main/scala/wvlet/log/Logger.scala index d5c4688fc7..7ce4141045 100644 --- a/airframe-log/src/main/scala/wvlet/log/Logger.scala +++ b/airframe-log/src/main/scala/wvlet/log/Logger.scala @@ -256,7 +256,7 @@ object Logger { def apply(loggerName: String): Logger = { loggerCache.getOrElseUpdate(loggerName, new Logger(loggerName, jl.Logger.getLogger(loggerName))) } - + def getDefaultLogLevel: LogLevel = rootLogger.getLogLevel def setDefaultLogLevel(level: LogLevel): Unit = {