在Akka中记录收到的消息

时间:2015-09-17 21:03:44

标签: java akka

我正在使用Java中的Akka actor,并且我正在尝试打开消息的日志记录。基于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

我应该怎么做才能记录消息?

1 个答案:

答案 0 :(得分:4)

您提到的设置akka.actor.debug.receive仅适用于演员的Scala API。这是因为在Scala中调用receive PartialFunction的方式的性质。在Scala中,actor框架首先看到是否使用case为输入消息定义了isDefinedAt。如果为邮件定义了case,则会在apply上调用PartialFunction并处理邮件。但是如果未处理该消息,则不会调用apply。为了记录所有消息,无论是处理还是其他消息,Scala框架都需要一个工具来绕过PartialFunction评估来记录,而该设施就是这个设置加上LoggingReceive实用程序来包装{{ 1}} receive并使用该设置来控制日志记录。

在Java世界中,您没有“检查然后应用”语义。所有邮件都会点击PartialFunction方法,在那里,您的onReceive处理将确定邮件是否已被处理。因此,在委托子类方法进行实际的消息评估和处理之前,定义一个实现instanceof的抽象基类Java类并相应地记录(可能基于相同的设置)非常容易。