Skip to content

Commit

Permalink
First step of changing to SL4J in Typed logging, #26537
Browse files Browse the repository at this point in the history
  • Loading branch information
franciscolopezsancho authored and patriknw committed Aug 28, 2019
1 parent 0fc70c5 commit b403f6f
Show file tree
Hide file tree
Showing 38 changed files with 1,168 additions and 1,650 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import akka.actor.typed.DispatcherSelector
import akka.actor.typed.Dispatchers
import akka.actor.typed.Extension
import akka.actor.typed.ExtensionId
import akka.actor.typed.Logger
import akka.actor.typed.Props
import akka.actor.typed.Scheduler
import akka.actor.typed.Settings
Expand All @@ -29,6 +28,8 @@ import scala.concurrent._
import akka.actor.ActorRefProvider
import akka.actor.typed.internal.InternalRecipientRef
import com.github.ghik.silencer.silent
import org.slf4j.Logger
import org.slf4j.helpers.SubstituteLoggerFactory

/**
* INTERNAL API
Expand Down Expand Up @@ -105,5 +106,7 @@ import com.github.ghik.silencer.silent
def hasExtension(ext: ExtensionId[_ <: Extension]): Boolean =
throw new UnsupportedOperationException("ActorSystemStub cannot register extensions")

def log: Logger = new StubbedLogger
val loggerFactory = new SubstituteLoggerFactory()

def log: Logger = loggerFactory.getLogger("StubbedLogger")
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private[akka] final class BehaviorTestKitImpl[T](_path: ActorPath, _initialBehav

override def getAllLogEntries(): util.List[CapturedLogEvent] = logEntries().asJava

override def logEntries(): immutable.Seq[CapturedLogEvent] = context.logEntries
override def logEntries(): immutable.Seq[CapturedLogEvent] = Nil

override def clearLog(): Unit = context.clearLog()
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@ package akka.actor.testkit.typed.internal

import akka.actor.typed._
import akka.actor.typed.internal._
import akka.actor.typed.internal.adapter.AbstractLogger
import akka.actor.testkit.typed.CapturedLogEvent
import akka.actor.testkit.typed.scaladsl.TestInbox
import akka.actor.{ ActorPath, InvalidMessageException }
import akka.annotation.InternalApi
import akka.event.Logging
import akka.util.{ Helpers, OptionVal }
import akka.util.Helpers
import akka.{ actor => untyped }
import java.util.concurrent.ThreadLocalRandom.{ current => rnd }

import scala.collection.immutable.TreeMap
import scala.concurrent.ExecutionContextExecutor
import scala.concurrent.duration.FiniteDuration

import akka.actor.ActorRefProvider
import org.slf4j.Logger
import org.slf4j.helpers.{ SubstituteLogger, SubstituteLoggerFactory }

/**
* INTERNAL API
Expand Down Expand Up @@ -54,108 +53,6 @@ private[akka] final class FunctionRef[-T](override val path: ActorPath, send: (T
def isTerminated: Boolean = false
}

/**
* INTERNAL API
*
* Captures log events for test inspection
*/
@InternalApi private[akka] final class StubbedLogger extends AbstractLogger {

private var logBuffer: List[CapturedLogEvent] = Nil

override def isErrorEnabled: Boolean = true
override def isWarningEnabled: Boolean = true
override def isInfoEnabled: Boolean = true
override def isDebugEnabled: Boolean = true

override def isErrorEnabled(marker: LogMarker): Boolean = true
override def isWarningEnabled(marker: LogMarker): Boolean = true
override def isInfoEnabled(marker: LogMarker): Boolean = true
override def isDebugEnabled(marker: LogMarker): Boolean = true

override private[akka] def notifyError(
message: String,
cause: OptionVal[Throwable],
marker: OptionVal[LogMarker]): Unit =
logBuffer = CapturedLogEvent(Logging.ErrorLevel, message, cause, marker, mdc) :: logBuffer
override private[akka] def notifyWarning(
message: String,
cause: OptionVal[Throwable],
marker: OptionVal[LogMarker]): Unit =
logBuffer = CapturedLogEvent(Logging.WarningLevel, message, OptionVal.None, marker, mdc) :: logBuffer

override private[akka] def notifyInfo(message: String, marker: OptionVal[LogMarker]): Unit =
logBuffer = CapturedLogEvent(Logging.InfoLevel, message, OptionVal.None, marker, mdc) :: logBuffer

override private[akka] def notifyDebug(message: String, marker: OptionVal[LogMarker]): Unit =
logBuffer = CapturedLogEvent(Logging.DebugLevel, message, OptionVal.None, marker, mdc) :: logBuffer

def logEntries: List[CapturedLogEvent] = logBuffer.reverse
def clearLog(): Unit = logBuffer = Nil

override def withMdc(mdc: Map[String, Any]): Logger = {
// we need to decorate to get log entries ending up the same logBuffer
val withMdc = new StubbedLoggerWithMdc(this)
withMdc.mdc = mdc
withMdc
}

// we don't care about log class and source here as we only track message, level and marker
def withLoggerClass(clazz: Class[_]): Logger = this
def withLogSource(logSource: String): Logger = this
}

@InternalApi private[akka] final class StubbedLoggerWithMdc(actual: StubbedLogger) extends AbstractLogger {
override def isErrorEnabled: Boolean = actual.isErrorEnabled
override def isWarningEnabled: Boolean = actual.isWarningEnabled
override def isInfoEnabled: Boolean = actual.isInfoEnabled
override def isDebugEnabled: Boolean = actual.isDebugEnabled
override def withMdc(mdc: Map[String, Any]): Logger = actual.withMdc(mdc)

override def isErrorEnabled(marker: LogMarker): Boolean = actual.isErrorEnabled(marker)
override def isWarningEnabled(marker: LogMarker): Boolean = actual.isWarningEnabled(marker)
override def isInfoEnabled(marker: LogMarker): Boolean = actual.isInfoEnabled(marker)
override def isDebugEnabled(marker: LogMarker): Boolean = actual.isDebugEnabled(marker)

override private[akka] def notifyError(
message: String,
cause: OptionVal[Throwable],
marker: OptionVal[LogMarker]): Unit = {
val original = actual.mdc
actual.mdc = mdc
actual.notifyError(message, cause, marker)
actual.mdc = original
}

override private[akka] def notifyWarning(
message: String,
cause: OptionVal[Throwable],
marker: OptionVal[LogMarker]): Unit = {
val original = actual.mdc
actual.mdc = mdc
actual.notifyWarning(message, cause, marker)
actual.mdc = original
}

override private[akka] def notifyInfo(message: String, marker: OptionVal[LogMarker]): Unit = {
val original = actual.mdc
actual.mdc = mdc
actual.notifyInfo(message, marker)
actual.mdc = original
}

override private[akka] def notifyDebug(message: String, marker: OptionVal[LogMarker]): Unit = {
val original = actual.mdc
actual.mdc = mdc
actual.notifyDebug(message, marker)
actual.mdc = original
}

// we don't care about log class and source here as we only track message, level and marker
def withLoggerClass(clazz: Class[_]): Logger = this
def withLogSource(logSource: String): Logger = this
}

/**
* INTERNAL API
*
Expand All @@ -179,7 +76,8 @@ private[akka] final class FunctionRef[-T](override val path: ActorPath, send: (T
override val system = new ActorSystemStub("StubbedActorContext")
private var _children = TreeMap.empty[String, BehaviorTestKitImpl[_]]
private val childName = Iterator.from(0).map(Helpers.base64(_))
private val loggingAdapter = new StubbedLogger
private val loggingAdapter: SubstituteLogger =
new SubstituteLoggerFactory().getLogger("StubbedLoggingAdapter").asInstanceOf[SubstituteLogger]
private var unhandled: List[T] = Nil

override def children: Iterable[ActorRef[Nothing]] = _children.values.map(_.context.self)
Expand Down Expand Up @@ -289,12 +187,12 @@ private[akka] final class FunctionRef[-T](override val path: ActorPath, send: (T
* The log entries logged through context.log.{debug, info, warn, error} are captured and can be inspected through
* this method.
*/
def logEntries: List[CapturedLogEvent] = loggingAdapter.logEntries
def logEntries: List[CapturedLogEvent] = ???

/**
* Clear the log entries.
*/
def clearLog(): Unit = loggingAdapter.clearLog()
def clearLog(): Unit = ???

override private[akka] def onUnhandled(msg: T): Unit =
unhandled = msg :: unhandled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.scalatest.junit.JUnitSuite;
import org.slf4j.event.LoggingEvent;

public class SyncTestingExampleTest extends JUnitSuite {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ class SyncTestingExampleSpec extends WordSpec with Matchers {
val testKit = BehaviorTestKit(myBehavior)
val inbox = TestInbox[String]("Inboxer")
testKit.run(LogAndSayHello(inbox.ref))

testKit.logEntries() shouldBe Seq(CapturedLogEvent(Logging.InfoLevel, "Saying hello to Inboxer"))
//#test-check-logging
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void loggingProvidesMDC() {
Behaviors.withMdc(
null,
(message) -> {
Map<String, Object> mdc = new HashMap<>();
Map<String, String> mdc = new HashMap<>();
mdc.put("txId", message.getTransactionId());
return mdc;
},
Expand Down
27 changes: 27 additions & 0 deletions akka-actor-typed-tests/src/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date{ISO8601} %-5level %logger %X{akkaSource} %X{sourceThread} - %msg%n</pattern>
</encoder>
</appender>
<appender name="INTERCEPTOR" class="akka.actor.typed.testkit.TestAppender">
<encoder>
<pattern>%date{ISO8601} %-5level %logger %X{akkaSource} %X{sourceThread} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>log-${byDay}.txt</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<logger name="akka.actor.typed.scaladsl.ActorLoggingSpec" level="DEBUG">
<appender-ref ref="INTERCEPTOR"/>
</logger>
<root level="DEBUG">
<appender-ref ref="FILE"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Loading

0 comments on commit b403f6f

Please sign in to comment.