我正在使用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
我应该怎么做才能记录消息?
答案 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类并相应地记录(可能基于相同的设置)非常容易。