2013-02-19 11:29:17 +01:00
|
|
|
/**
|
|
|
|
|
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
|
|
|
|
|
*/
|
|
|
|
|
package akka.event
|
|
|
|
|
|
2013-02-20 14:36:49 +01:00
|
|
|
import akka.testkit._
|
|
|
|
|
import scala.concurrent.duration._
|
2013-02-19 11:29:17 +01:00
|
|
|
import com.typesafe.config.{ Config, ConfigFactory }
|
2013-02-20 14:36:49 +01:00
|
|
|
import akka.actor.{ ActorRef, Actor, ActorSystem }
|
2013-04-21 00:40:47 -07:00
|
|
|
import java.util.{ Date, GregorianCalendar, TimeZone, Calendar }
|
2013-02-19 11:29:17 +01:00
|
|
|
import org.scalatest.WordSpec
|
|
|
|
|
import org.scalatest.matchers.MustMatchers
|
2013-03-30 02:11:09 +01:00
|
|
|
import akka.serialization.SerializationExtension
|
|
|
|
|
import akka.event.Logging.{ Warning, LogEvent, LoggerInitialized, InitializeLogger }
|
2013-04-21 00:40:47 -07:00
|
|
|
import akka.util.Helpers
|
2013-02-19 11:29:17 +01:00
|
|
|
|
|
|
|
|
object LoggerSpec {
|
|
|
|
|
|
|
|
|
|
val defaultConfig = ConfigFactory.parseString("""
|
|
|
|
|
akka {
|
2013-02-20 10:07:45 +01:00
|
|
|
stdout-loglevel = "WARNING"
|
|
|
|
|
loglevel = "DEBUG"
|
2013-02-21 15:44:14 +01:00
|
|
|
loggers = ["akka.event.LoggerSpec$TestLogger1"]
|
2013-02-19 11:29:17 +01:00
|
|
|
}
|
|
|
|
|
""").withFallback(AkkaSpec.testConf)
|
|
|
|
|
|
|
|
|
|
val noLoggingConfig = ConfigFactory.parseString("""
|
|
|
|
|
akka {
|
2013-02-20 10:07:45 +01:00
|
|
|
stdout-loglevel = "OFF"
|
|
|
|
|
loglevel = "OFF"
|
2013-02-21 15:44:14 +01:00
|
|
|
loggers = ["akka.event.LoggerSpec$TestLogger1"]
|
2013-02-19 11:29:17 +01:00
|
|
|
}
|
|
|
|
|
""").withFallback(AkkaSpec.testConf)
|
2013-02-20 14:36:49 +01:00
|
|
|
|
2013-02-21 15:44:14 +01:00
|
|
|
val multipleConfig = ConfigFactory.parseString("""
|
|
|
|
|
akka {
|
|
|
|
|
stdout-loglevel = "OFF"
|
|
|
|
|
loglevel = "WARNING"
|
|
|
|
|
loggers = ["akka.event.LoggerSpec$TestLogger1", "akka.event.LoggerSpec$TestLogger2"]
|
|
|
|
|
}
|
|
|
|
|
""").withFallback(AkkaSpec.testConf)
|
|
|
|
|
|
2013-03-30 02:11:09 +01:00
|
|
|
val ticket3165Config = ConfigFactory.parseString("""
|
|
|
|
|
akka {
|
|
|
|
|
stdout-loglevel = "WARNING"
|
|
|
|
|
loglevel = "DEBUG"
|
|
|
|
|
loggers = ["akka.event.LoggerSpec$TestLogger1"]
|
|
|
|
|
actor {
|
|
|
|
|
serialize-messages = on
|
|
|
|
|
serialization-bindings {
|
|
|
|
|
"akka.event.Logging$LogEvent" = bytes
|
|
|
|
|
"java.io.Serializable" = java
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
""").withFallback(AkkaSpec.testConf)
|
|
|
|
|
|
2013-02-21 15:44:14 +01:00
|
|
|
case class SetTarget(ref: ActorRef, qualifier: Int)
|
2013-02-20 14:36:49 +01:00
|
|
|
|
2013-02-21 15:44:14 +01:00
|
|
|
class TestLogger1 extends TestLogger(1)
|
|
|
|
|
class TestLogger2 extends TestLogger(2)
|
|
|
|
|
abstract class TestLogger(qualifier: Int) extends Actor with Logging.StdOutLogger {
|
2013-02-20 14:36:49 +01:00
|
|
|
var target: Option[ActorRef] = None
|
|
|
|
|
override def receive: Receive = {
|
|
|
|
|
case InitializeLogger(bus) ⇒
|
|
|
|
|
bus.subscribe(context.self, classOf[SetTarget])
|
|
|
|
|
sender ! LoggerInitialized
|
2013-02-21 15:44:14 +01:00
|
|
|
case SetTarget(ref, `qualifier`) ⇒
|
2013-02-20 14:36:49 +01:00
|
|
|
target = Some(ref)
|
|
|
|
|
ref ! ("OK")
|
|
|
|
|
case event: LogEvent ⇒
|
|
|
|
|
print(event)
|
|
|
|
|
target foreach { _ ! event.message }
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-02-19 11:29:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner])
|
|
|
|
|
class LoggerSpec extends WordSpec with MustMatchers {
|
|
|
|
|
|
|
|
|
|
import LoggerSpec._
|
|
|
|
|
|
2013-02-20 14:36:49 +01:00
|
|
|
private def createSystemAndLogToBuffer(name: String, config: Config, shouldLog: Boolean) = {
|
2013-02-19 11:29:17 +01:00
|
|
|
val out = new java.io.ByteArrayOutputStream()
|
|
|
|
|
Console.withOut(out) {
|
2013-02-20 14:36:49 +01:00
|
|
|
implicit val system = ActorSystem(name, config)
|
2013-02-19 11:29:17 +01:00
|
|
|
try {
|
2013-02-20 14:36:49 +01:00
|
|
|
val probe = TestProbe()
|
2013-02-21 15:44:14 +01:00
|
|
|
system.eventStream.publish(SetTarget(probe.ref, qualifier = 1))
|
2013-02-20 14:36:49 +01:00
|
|
|
probe.expectMsg("OK")
|
2013-02-19 11:29:17 +01:00
|
|
|
system.log.error("Danger! Danger!")
|
2013-02-20 14:36:49 +01:00
|
|
|
// since logging is asynchronous ensure that it propagates
|
|
|
|
|
if (shouldLog) {
|
|
|
|
|
probe.fishForMessage(0.5.seconds.dilated) {
|
|
|
|
|
case "Danger! Danger!" ⇒ true
|
|
|
|
|
case _ ⇒ false
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
probe.expectNoMsg(0.5.seconds.dilated)
|
|
|
|
|
}
|
2013-02-19 11:29:17 +01:00
|
|
|
} finally {
|
2013-05-02 17:12:36 +02:00
|
|
|
TestKit.shutdownActorSystem(system)
|
2013-02-19 11:29:17 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
out
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"A normally configured actor system" must {
|
|
|
|
|
|
|
|
|
|
"log messages to standard output" in {
|
2013-02-20 14:36:49 +01:00
|
|
|
val out = createSystemAndLogToBuffer("defaultLogger", defaultConfig, true)
|
2013-02-19 11:29:17 +01:00
|
|
|
out.size must be > (0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"An actor system configured with the logging turned off" must {
|
|
|
|
|
|
|
|
|
|
"not log messages to standard output" in {
|
2013-02-20 14:36:49 +01:00
|
|
|
val out = createSystemAndLogToBuffer("noLogging", noLoggingConfig, false)
|
2013-02-19 11:29:17 +01:00
|
|
|
out.size must be(0)
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-02-21 15:44:14 +01:00
|
|
|
|
|
|
|
|
"An actor system configured with multiple loggers" must {
|
|
|
|
|
|
|
|
|
|
"use several loggers" in {
|
|
|
|
|
Console.withOut(new java.io.ByteArrayOutputStream()) {
|
|
|
|
|
implicit val system = ActorSystem("multipleLoggers", multipleConfig)
|
|
|
|
|
try {
|
|
|
|
|
val probe1 = TestProbe()
|
|
|
|
|
val probe2 = TestProbe()
|
|
|
|
|
system.eventStream.publish(SetTarget(probe1.ref, qualifier = 1))
|
|
|
|
|
probe1.expectMsg("OK")
|
|
|
|
|
system.eventStream.publish(SetTarget(probe2.ref, qualifier = 2))
|
|
|
|
|
probe2.expectMsg("OK")
|
|
|
|
|
|
|
|
|
|
system.log.warning("log it")
|
|
|
|
|
probe1.expectMsg("log it")
|
|
|
|
|
probe2.expectMsg("log it")
|
|
|
|
|
} finally {
|
2013-05-02 17:12:36 +02:00
|
|
|
TestKit.shutdownActorSystem(system)
|
2013-02-21 15:44:14 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-03-30 02:11:09 +01:00
|
|
|
|
2013-04-21 00:40:47 -07:00
|
|
|
"Ticket 3080" must {
|
|
|
|
|
"format currentTimeMillis to a valid UTC String" in {
|
|
|
|
|
val timestamp = System.currentTimeMillis
|
|
|
|
|
val c = new GregorianCalendar(TimeZone.getTimeZone("UTC"))
|
|
|
|
|
c.setTime(new Date(timestamp))
|
|
|
|
|
val hours = c.get(Calendar.HOUR_OF_DAY)
|
|
|
|
|
val minutes = c.get(Calendar.MINUTE)
|
|
|
|
|
val seconds = c.get(Calendar.SECOND)
|
|
|
|
|
val ms = c.get(Calendar.MILLISECOND)
|
|
|
|
|
Helpers.currentTimeMillisToUTCString(timestamp) must be(f"$hours%02d:$minutes%02d:$seconds%02d.$ms%03dUTC")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-30 02:11:09 +01:00
|
|
|
"Ticket 3165 - serialize-messages and dual-entry serialization of LogEvent" must {
|
|
|
|
|
"not cause StackOverflowError" in {
|
|
|
|
|
implicit val s = ActorSystem("foo", ticket3165Config)
|
|
|
|
|
try {
|
|
|
|
|
SerializationExtension(s).serialize(Warning("foo", classOf[String]))
|
|
|
|
|
} finally {
|
2013-05-02 17:12:36 +02:00
|
|
|
TestKit.shutdownActorSystem(s)
|
2013-03-30 02:11:09 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-02-19 11:29:17 +01:00
|
|
|
}
|