2015-09-17 64 views
3

我使用從Java內部阿卡演員,我試圖打開消息記錄。基於documentation,似乎設置akka.actor.debug.receive應導致所有消息被記錄。以下測試應記錄正在發送和接收的"hello"消息。記錄收到的消息在阿卡

import akka.actor.AbstractLoggingActor; 
import akka.actor.ActorRef; 
import akka.actor.ActorSystem; 
import akka.actor.Props; 
import akka.japi.pf.ReceiveBuilder; 
import akka.pattern.Patterns; 
import akka.testkit.JavaTestKit; 
import com.typesafe.config.Config; 
import com.typesafe.config.ConfigFactory; 
import io.scalac.amqp.Persistent$; 
import org.hamcrest.CoreMatchers; 
import org.junit.After; 
import org.junit.Assert; 
import org.junit.Before; 
import org.junit.Test; 
import scala.concurrent.duration.Duration$; 

public class LoggingTest 
{ 
    @Before 
    public void createActorSystem() { 
     Config config = ConfigFactory.parseString(
       "akka: {" + 
       " actor: { debug: { receive: on, fsm: on, unhandled: on, autoreceive: on }}," + 
       " log-config-on-start: off" + 
       " ,loglevel: DEBUG" + 
       " ,stdout-loglevel: DEBUG" + 
       "}"); 
     system = ActorSystem.create(getClass().getSimpleName(), 
            config); 

    } 

    @After 
    public void shutdownActorSystem() { 
     JavaTestKit.shutdownActorSystem(system); 
    } 

    private static class TestActorWithLogging extends AbstractLoggingActor { 
     public TestActorWithLogging(ActorRef target) { 
      receive(ReceiveBuilder. 
        matchAny(msg -> target.tell(msg, self())). 
        build()); 
     } 
    } 

    @Test 
    public void messageLogging() { 
     new JavaTestKit(system) {{ 
      system.log().debug("Running messageLogging"); 

      ActorRef actor = system.actorOf(Props.create(TestActorWithLogging.class, getRef())); 
      send(actor, "hello"); 
      expectMsgEquals("hello"); 
     }}; 
    } 


    private ActorSystem system; 
} 

當我運行測試時,我得到以下輸出。生命週期消息被記錄,所以配置正在被應用。但是,我沒有看到有關"hello"消息的任何日誌消息。

Running LoggingTest 
[DEBUG] [09/17/2015 16:49:48.893] [main] [EventStream] StandardOutLogger started 
[DEBUG] [09/17/2015 16:49:49.020] [main] [EventStream(akka://LoggingTest)] logger log1-Logging$DefaultLogger started 
[DEBUG] [09/17/2015 16:49:49.020] [main] [EventStream(akka://LoggingTest)] logger log1-Logging$DefaultLogger started 
[DEBUG] [09/17/2015 16:49:49.023] [main] [EventStream(akka://LoggingTest)] Default Loggers started 
[DEBUG] [09/17/2015 16:49:49.023] [main] [EventStream(akka://LoggingTest)] Default Loggers started 
[DEBUG] [09/17/2015 16:49:49.050] [main] [akka.actor.ActorSystemImpl(LoggingTest)] Running messageLogging 
[DEBUG] [09/17/2015 16:49:49.103] [LoggingTest-akka.actor.default-dispatcher-4] [akka://LoggingTest/system] received AutoReceiveMessage Envelope(Terminated(Actor[akka://LoggingTest/user]),Actor[akka://LoggingTest/user]) 
[DEBUG] [09/17/2015 16:49:49.104] [LoggingTest-akka.actor.default-dispatcher-4] [EventStream] shutting down: StandardOutLogger started 
[DEBUG] [09/17/2015 16:49:49.104] [LoggingTest-akka.actor.default-dispatcher-4] [EventStream] shutting down: StandardOutLogger started 
[DEBUG] [09/17/2015 16:49:49.106] [LoggingTest-akka.actor.default-dispatcher-4] [EventStream] all default loggers stopped 
[DEBUG] [09/17/2015 16:49:49.111] [LoggingTest-akka.actor.default-dispatcher-3] [akka://LoggingTest/] received AutoReceiveMessage Envelope(Terminated(Actor[akka://LoggingTest/system]),Actor[akka://LoggingTest/system]) 
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.33 sec 

我該怎麼做才能記錄消息?

回答

3

你提到的設置,akka.actor.debug.receive只對Scala的API的演員。這是因爲在Scala中如何調用receivePartialFunction。在Scala中,演員框架首先使用isDefinedAt來查看是否存在爲輸入消息定義的case。如果該消息定義的case,那麼它會呼籲PartialFunctionapply和消息的處理。但如果消息沒有被處理,則不會調用apply。爲了將所有消息記錄,處理或以其他方式,斯卡拉框架所需要的設施,以環繞PartialFunction評價,無論登錄,並且該設施是這樣的設置加上LoggingReceive工具,包裝了receivePartialFunction並使用該設置來控制日誌記錄。

在Java世界中,你沒有這個「檢查然後應用」的語義。所有消息都是onReceive方法,在那裏,您的instanceof處理將確定消息是否處理。因此,定義一個實現onReceive的抽象基類Java並相應地進行日誌記錄(可能基於相同的設置),然後再委託給實際消息評估和處理的子類方法,這非常容易。

+1

它看起來像消息通過'aroundReceive',不'onReceive'。但除此之外,這是有效的。 –