Implement basic event logging

This commit is contained in:
Eugene Yokota 2017-01-23 16:38:14 -05:00
parent 857dbf97fe
commit 08e9ce9526
5 changed files with 54 additions and 2 deletions

View File

@ -252,8 +252,9 @@ class ConsoleAppender private[ConsoleAppender] (
}
def objectToString(o: AnyRef): String =
o match {
case x: ChannelLogEntry => x.message
case _ => o.toString
case x: ChannelLogEntry => x.message
case x: ObjectLogEntry[_] => x.message.toString
case _ => o.toString
}
def messageColor(level: Level.Value) = RESET

View File

@ -3,6 +3,7 @@ package sbt.internal.util
import sbt.util._
import org.apache.logging.log4j.{ Logger => XLogger }
import org.apache.logging.log4j.message.ObjectMessage
import sjsonnew.JsonFormat
/**
* Delegates log events to the associated LogExchange.
@ -22,4 +23,20 @@ class ManagedLogger(
)
}
override def success(message: => String): Unit = xlogger.info(message)
final def debugEvent[A: JsonFormat](event: => A): Unit = logEvent(Level.Debug, event)
final def infoEvent[A: JsonFormat](event: => A): Unit = logEvent(Level.Info, event)
final def warnEvent[A: JsonFormat](event: => A): Unit = logEvent(Level.Warn, event)
final def errorEvent[A: JsonFormat](event: => A): Unit = logEvent(Level.Error, event)
def logEvent[A: JsonFormat](level: Level.Value, event: => A): Unit =
{
val v: A = event
val clazz: Class[A] = v.getClass.asInstanceOf[Class[A]]
val ev = LogExchange.getOrElseUpdateJsonCodec(clazz, implicitly[JsonFormat[A]])
val entry: ObjectLogEntry[A] = new ObjectLogEntry(level, v, channelName, execId, ev, clazz)
xlogger.log(
ConsoleAppender.toXLevel(level),
new ObjectMessage(entry)
)
}
}

View File

@ -0,0 +1,17 @@
package sbt
package internal
package util
import sbt.util.Level
import sjsonnew.JsonFormat
final class ObjectLogEntry[A](
val level: Level.Value,
val message: A,
val channelName: Option[String],
val execId: Option[String],
val ev: JsonFormat[A],
val clazz: Class[A]
) extends Serializable {
}

View File

@ -6,6 +6,8 @@ import org.apache.logging.log4j.core._
import org.apache.logging.log4j.core.appender.AsyncAppender
import org.apache.logging.log4j.core.config.{ AppenderRef, LoggerConfig }
import scala.collection.JavaConverters._
import scala.collection.concurrent
import sjsonnew.JsonFormat
// http://logging.apache.org/log4j/2.x/manual/customconfig.html
// https://logging.apache.org/log4j/2.x/log4j-core/apidocs/index.html
@ -13,6 +15,7 @@ import scala.collection.JavaConverters._
sealed abstract class LogExchange {
private[sbt] lazy val context: LoggerContext = init()
private[sbt] lazy val asyncStdout: AsyncAppender = buildAsyncStdout
private[sbt] val jsonCodecs: concurrent.Map[Class[_], JsonFormat[_]] = concurrent.TrieMap()
def logger(name: String): ManagedLogger = logger(name, None, None)
def logger(name: String, channelName: Option[String], execId: Option[String]): ManagedLogger = {
@ -43,6 +46,13 @@ sealed abstract class LogExchange {
val config = ctx.getConfiguration
config.getLoggerConfig(loggerName)
}
def jsonCodec[A](clazz: Class[A]): Option[JsonFormat[A]] =
jsonCodecs.get(clazz) map { _.asInstanceOf[JsonFormat[A]] }
def hasJsonCodec[A](clazz: Class[A]): Boolean =
jsonCodecs.contains(clazz)
def getOrElseUpdateJsonCodec[A](clazz: Class[A], v: JsonFormat[A]): JsonFormat[A] =
jsonCodecs.getOrElseUpdate(clazz, v).asInstanceOf[JsonFormat[A]]
private[sbt] def buildAsyncStdout: AsyncAppender = {
val ctx = XLogManager.getContext(false) match { case x: LoggerContext => x }
val config = ctx.getConfiguration

View File

@ -13,6 +13,13 @@ class ManagedLoggerSpec extends FlatSpec with Matchers {
log.debug("test")
}
it should "support event logging" in {
import sjsonnew.BasicJsonProtocol._
val log = LogExchange.logger("foo")
LogExchange.bindLoggerAppenders("foo", List(LogExchange.asyncStdout -> Level.Info))
log.infoEvent(1)
}
"global logging" should "log immediately after initialization" in {
// this is passed into State normally
val global0 = initialGlobalLogging