Add log() method to typed Logging API #24648

This commit is contained in:
Thomas Smith 2018-03-05 09:10:14 +01:00 committed by Johan Andrén
parent 1574faf180
commit c9969b0bea
3 changed files with 165 additions and 3 deletions

View file

@ -48,13 +48,16 @@ class ActorLoggingSpec extends ActorTestKit with TypedAkkaSpec {
"pass markers to the log" in {
EventFilter.custom({
case event: LogEventWithMarker if event.marker == marker true
}, occurrences = 5).intercept(
}, occurrences = 9).intercept(
spawn(Behaviors.setup[Any] { ctx
ctx.log.debug(marker, "whatever")
ctx.log.info(marker, "whatever")
ctx.log.warning(marker, "whatever")
ctx.log.error(marker, "whatever")
ctx.log.error(marker, cause, "whatever")
Logging.AllLogLevels.foreach(level {
ctx.log.log(level, marker, "whatever")
})
Behaviors.stopped
})
)
@ -78,7 +81,7 @@ class ActorLoggingSpec extends ActorTestKit with TypedAkkaSpec {
EventFilter.custom({
case _ true // any is fine, we're just after the right count of statements reaching the listener
}, occurrences = 72).intercept {
}, occurrences = 120).intercept {
spawn(Behaviors.setup[String] { ctx
ctx.log.debug("message")
ctx.log.debug("{}", "arg1")
@ -158,6 +161,22 @@ class ActorLoggingSpec extends ActorTestKit with TypedAkkaSpec {
ctx.log.error(marker, cause, "{} {} {} {}", "arg1", "arg2", "arg3", "arg4")
ctx.log.error(marker, cause, "{} {} {} {} {}", Array("arg1", "arg2", "arg3", "arg4", "arg5"))
Logging.AllLogLevels.foreach(level {
ctx.log.log(level, "message")
ctx.log.log(level, "{}", "arg1")
ctx.log.log(level, "{} {}", "arg1", "arg2")
ctx.log.log(level, "{} {} {}", "arg1", "arg2", "arg3")
ctx.log.log(level, "{} {} {} {}", "arg1", "arg2", "arg3", "arg4")
ctx.log.log(level, "{} {} {} {} {}", Array("arg1", "arg2", "arg3", "arg4", "arg5"))
ctx.log.log(level, marker, "message")
ctx.log.log(level, marker, "{}", "arg1")
ctx.log.log(level, marker, "{} {}", "arg1", "arg2")
ctx.log.log(level, marker, "{} {} {}", "arg1", "arg2", "arg3")
ctx.log.log(level, marker, "{} {} {} {}", "arg1", "arg2", "arg3", "arg4")
ctx.log.log(level, marker, "{} {} {} {} {}", Array("arg1", "arg2", "arg3", "arg4", "arg5"))
})
Behaviors.stopped
})
}

View file

@ -4,6 +4,7 @@
package akka.actor.typed
import akka.annotation.{ DoNotInherit, InternalApi }
import akka.event.Logging.{ ErrorLevel, WarningLevel, InfoLevel, DebugLevel, LogLevel }
/**
* A log marker is an additional metadata tag supported by some logging backends to identify "special" log events.
@ -94,6 +95,19 @@ abstract class Logger private[akka] () {
*/
def isDebugEnabled: Boolean
/**
* Whether a log level is enabled on the actor system level, may not represent the setting all the way to the
* logger implementation, but when it does it allows avoiding unnecessary resource usage for log entries that
* will not actually end up in any logger output.
*/
def isLevelEnabled(logLevel: LogLevel): Boolean = logLevel match {
case ErrorLevel isErrorEnabled
case WarningLevel isWarningEnabled
case InfoLevel isInfoEnabled
case DebugLevel isDebugEnabled
case _ false
}
// message only error logging
/**
@ -556,4 +570,85 @@ abstract class Logger private[akka] () {
*/
def debug(marker: LogMarker, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit
// message any level logging
/**
* Log message at the specified level.
*
* @see [[Logger]]
*/
def log(level: LogLevel, message: String): Unit
/**
* Message template with 1 replacement argument.
*
* If `arg1` is an `Array` it will be expanded into replacement arguments, which is useful when
* there are more than four arguments.
*
* @see [[Logger]]
*/
def log(level: LogLevel, template: String, arg1: Any): Unit
/**
* Message template with 2 replacement arguments.
*
* @see [[Logger]]
*/
def log(level: LogLevel, template: String, arg1: Any, arg2: Any): Unit
/**
* Message template with 3 replacement arguments.
*
* @see [[Logger]]
*/
def log(level: LogLevel, template: String, arg1: Any, arg2: Any, arg3: Any): Unit
/**
* Message template with 4 replacement arguments. For more parameters see the single replacement version of this method.
*
* @see [[Logger]]
*/
def log(level: LogLevel, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit
// marker logging at any level
/**
* Log message at the specified level.
*
* The marker argument can be picked up by various logging frameworks such as slf4j to mark this log statement as "special".
*
* @see [[Logger]]
*/
def log(level: LogLevel, marker: LogMarker, message: String): Unit
/**
* Message template with 1 replacement argument.
*
* The marker argument can be picked up by various logging frameworks such as slf4j to mark this log statement as "special".
*
* If `arg1` is an `Array` it will be expanded into replacement arguments, which is useful when
* there are more than four arguments.
*
* @see [[Logger]]
*/
def log(level: LogLevel, marker: LogMarker, template: String, arg1: Any): Unit
/**
* Message template with 2 replacement arguments.
*
* The marker argument can be picked up by various logging frameworks such as slf4j to mark this log statement as "special".
*
* @see [[Logger]]
*/
def log(level: LogLevel, marker: LogMarker, template: String, arg1: Any, arg2: Any): Unit
/**
* Message template with 3 replacement arguments.
*
* The marker argument can be picked up by various logging frameworks such as slf4j to mark this log statement as "special".
*
* @see [[Logger]]
*/
def log(level: LogLevel, marker: LogMarker, template: String, arg1: Any, arg2: Any, arg3: Any): Unit
/**
* Message template with 4 replacement arguments. For more parameters see the single replacement version of this method.
*
* The marker argument can be picked up by various logging frameworks such as slf4j to mark this log statement as "special".
*
* @see [[Logger]]
*/
def log(level: LogLevel, marker: LogMarker, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit
}

View file

@ -5,7 +5,7 @@ package akka.actor.typed.internal.adapter
import akka.actor.typed.{ LogMarker, Logger }
import akka.annotation.InternalApi
import akka.event.Logging.{ Debug, Error, Info, Warning }
import akka.event.Logging.{ Debug, DebugLevel, Error, ErrorLevel, Info, InfoLevel, LogLevel, Warning, WarningLevel }
import akka.event.{ LoggingBus, LoggingFilter, LogMarker UntypedLM }
import akka.util.OptionVal
@ -262,6 +262,46 @@ private[akka] class LoggerAdapterImpl(bus: LoggingBus, logClass: Class[_], logSo
if (isDebugEnabled) notifyDebug(format(template, arg1, arg2, arg3, arg4), OptionVal.Some(marker))
}
override def log(level: LogLevel, message: String): Unit = {
if (isLevelEnabled(level)) notify(level, message, OptionVal.None)
}
override def log(level: LogLevel, template: String, arg1: Any): Unit = {
if (isLevelEnabled(level)) notify(level, format(template, arg1), OptionVal.None)
}
override def log(level: LogLevel, template: String, arg1: Any, arg2: Any): Unit = {
if (isLevelEnabled(level)) notify(level, format(template, arg1, arg2), OptionVal.None)
}
override def log(level: LogLevel, template: String, arg1: Any, arg2: Any, arg3: Any): Unit = {
if (isLevelEnabled(level)) notify(level, format(template, arg1, arg2, arg3), OptionVal.None)
}
override def log(level: LogLevel, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit = {
if (isLevelEnabled(level)) notify(level, format(template, arg1, arg2, arg3, arg4), OptionVal.None)
}
override def log(level: LogLevel, marker: LogMarker, message: String): Unit = {
if (isLevelEnabled(level)) notify(level, message, OptionVal.Some(marker))
}
override def log(level: LogLevel, marker: LogMarker, template: String, arg1: Any): Unit = {
if (isLevelEnabled(level)) notify(level, format(template, arg1), OptionVal.Some(marker))
}
override def log(level: LogLevel, marker: LogMarker, template: String, arg1: Any, arg2: Any): Unit = {
if (isLevelEnabled(level)) notify(level, format(template, arg1, arg2), OptionVal.Some(marker))
}
override def log(level: LogLevel, marker: LogMarker, template: String, arg1: Any, arg2: Any, arg3: Any): Unit = {
if (isLevelEnabled(level)) notify(level, format(template, arg1, arg2, arg3), OptionVal.Some(marker))
}
override def log(level: LogLevel, marker: LogMarker, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit = {
if (isLevelEnabled(level)) notify(level, format(template, arg1, arg2, arg3, arg4), OptionVal.Some(marker))
}
protected def notifyError(message: String, cause: OptionVal[Throwable], marker: OptionVal[LogMarker]): Unit = {
val error = cause match {
case OptionVal.Some(cause)
@ -309,6 +349,14 @@ private[akka] class LoggerAdapterImpl(bus: LoggingBus, logClass: Class[_], logSo
bus.publish(debug)
}
protected def notify(level: LogLevel, message: String, marker: OptionVal[LogMarker]): Unit = level match {
case ErrorLevel notifyDebug(message, marker)
case WarningLevel notifyWarning(message, marker, OptionVal.None)
case InfoLevel notifyInfo(message, marker)
case DebugLevel notifyDebug(message, marker)
case _ ()
}
/**
* If `arg` is an `Array` it will be expanded into replacement arguments, which is useful when
* there are more than four arguments.