在Akka中记录收到的消息 [英] Logging received messages in Akka

查看:141
本文介绍了在Akka中记录收到的消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Java中使用Akka actor,并且我正在尝试打开消息的日志记录。基于文档,似乎设置 akka.actor.debug.receive 应该导致记录所有消息。以下测试应记录发送和接收的hello消息。

I am using Akka actors from within Java and am trying to turn on the logging of messages. Based on the documentation, it seems that setting akka.actor.debug.receive should cause all messages to be logged. The following test should log the "hello" message being sent and received.

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消息的任何日志声明。

When I run the test, I get the following output. Lifecycle messages are logged, so the config is being applied. However, I don't see any log statements about the "hello" message.

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

我应该做什么记录消息?

What should I be doing to log the messages?

推荐答案

你提到的设置, akka.actor.debug.receive 仅适用于演员的Scala API。这是因为在Scala中调用接收 PartialFunction 的性质。在Scala中,actor框架首先看到是否使用 isDefinedAt 为输入消息定义了 case 。如果为消息定义了 case ,那么它将在 PartialFunction上调用 apply 并处理该消息。但是如果没有处理消息,则不会调用 apply 。为了记录所有消息,无论是处理还是其他消息,Scala框架都需要一个工具来包装 PartialFunction 评估以便记录,而该设施是这个设置加上 LoggingReceive 实用程序包装 receive PartialFunction 并使用该设置来控制log。

The setting you mention, akka.actor.debug.receive is only for the Scala API for actors. This is because of the nature of how the receive PartialFunction is invoked in Scala. In Scala, the actor framework first sees if there is a case defined for the input message using isDefinedAt. If there is a case defined for the message, then it will call apply on the PartialFunction and the message is handled. But if the message is not handled, then apply is not called. In order to log all messages, handled or otherwise, the Scala framework needed a facility to wrap around the PartialFunction evaluation to log regardless, and that facility is this setting plus the LoggingReceive utility that wraps the receive PartialFunction and uses that setting to control logging.

在Java世界中,你没有这个check then apply语义。所有邮件都会点击 onReceive 方法,在那里,您的 instanceof 处理将确定邮件是否被处理。因此,在委托实际消息的子类方法之前,很容易定义实现 onReceive 的抽象基类Java类并相应地记录(可能基于相同的设置)评估和处理。

In the Java world, you don't have this "check then apply" semantic. All messages hit the onReceive method and in there, your instanceof handling will determine if the message is handled or not. Because of this, it's pretty easy to define an abstract base Java class that implements onReceive and logs accordingly (possibly based on that same setting) before delegating to a subclass method for actual message evaluation and handling.

这篇关于在Akka中记录收到的消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆