2015-09-17 3 views
3

Я использую актеров Akka из Java и пытаюсь включить ведение журнала сообщений. Основываясь на documentation, кажется, что установка akka.actor.debug.receive должна приводить к регистрации всех сообщений. Следующий тест должен регистрировать отправленное и принятое сообщение "hello".Регистрация полученных сообщений в Akka

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; 
} 

Когда я запускаю тест, я получаю следующий вывод. Сообщения Lifecycle регистрируются, поэтому применяется настройка. Тем не менее, я не вижу никаких сообщений в журнале о сообщении "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 структура актера сначала видит, есть ли case, определенный для входного сообщения, используя isDefinedAt. Если для сообщения определено case, он будет вызывать apply на PartialFunction и обрабатывать сообщение. Но если сообщение не обрабатывается, то apply не вызывается. Для регистрации всех сообщений, обработанных или иным образом, для платформы Scala требуется средство для обертывания оценки PartialFunction для регистрации независимо, и этот объект является этим параметром плюс утилита LoggingReceive, которая обертывает receivePartialFunction и использует этот параметр для управления ведением журнала.

В мире Java у вас нет этой «проверки, а затем применить» семантику. Все сообщения попадают в метод onReceive, и там ваша обработка instanceof определит, обрабатывается ли сообщение или нет. Из-за этого довольно легко определить абстрактный базовый Java-класс, который реализует onReceive и регистрирует соответственно (возможно, на основе того же параметра) перед передачей методу подкласса для фактической оценки и обработки сообщений.

+1

Похоже, что сообщения проходят через 'aroundReceive', а не' onReceive'. Но кроме этого это работает. –

Смежные вопросы