在Akka中记录收到的消息 [英] Logging received messages in 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屋!