为什么要使用Akka事件处理程序进行日志记录

12
在下面的文档中,事件处理程序被描述为取代日志记录的位置。http://akka.io/docs/akka/1.2/general/event-handler.html

Akka中有一个事件处理程序取代了日志记录系统:

akka.event.EventHandler

具体来说,这个链接提供了一个使用slf4j的例子:http://akka.io/docs/akka/1.2/general/slf4j.html 我的问题是:“这样做有什么优势?为什么要这样做而不是使用标准模式下的日志记录器?”
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
private static Logger log = LoggerFactory.getLogger(MyActor.class);
...
log.info("doing something");

我是否可以从使用事件处理程序而不是上述日志记录模式中看到线程或调度程序内部的某种潜在好处?如果没有,那么为了日志记录而使用事件处理程序感觉像是没有明显理由偏离熟悉的模式。

感谢任何意见!

3个回答

11

日志通常意味着IO操作,这可能会减慢您的代码运行速度。在每个消息都必须在接收方法中单个处理的Actor上下文中,这种开销有时可能使该方法完成的时间差异达到一个或多个数量级。在基于Erlang的系统中,将日志记录移动到运行接受块的线程(或进程,在Erlang领域中)的控制流之外已经成为一种常见的模式。如果您的Actor不是严重依赖于接收块的时间,那么,如果标准日志记录模式可以使事情变得更容易,您总是可以退回到标准日志记录模式,但习惯于基于EventHandler的方法可能是一个好主意。


谢谢Thomas,这很有道理。我已经改变了我的演员日志记录,使用EventHandler.info()等方法。它似乎没有遵守我在log4j.xml文件中指定的模式布局,但至少我能看到我的INFO级别消息。 - D Parsin
1
异步记录日志听起来有些危险。我有什么保证,a)日志语句会按正确的顺序输出,并且b)如果事件处理程序无法跟上系统的其余部分(如果记录是系统中最慢的部分,则日志队列将不断增长,直到出现OutOfMemory),那么它能够跟上系统的其余部分。同步记录错误日志是否有意义? - Ant Kutschera
如果您依赖于特定的排序或有关顺序的保证,也许基于Actor的方法并不适合您。话虽如此,由于日志记录本身是由Actor处理的,并且Actor按照它们接收到消息的顺序接收消息,所以这不应该是一个问题。此外,Akka具有非常稳固的消息排队实现,也可以根据您的需要进行调整/调优。如果您担心缓冲区溢出(我不确定Akka默认的限制是什么),则可以使用有界消息队列并创建自己的日志处理程序来使用它。 - Thomas Lockney

0

在使用Akka 1.2中的Slf4jEventHandler时要小心。您会失去按类别设置日志级别的能力,而改为

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
private static Logger log = LoggerFactory.getLogger(MyActor.class);
...
log.info("doing something");

原因是Slf4jEventHandler仅使用一个名为"akka.event.slf4j.Slf4jEventHandler"的记录器。


0

@DParsin,你需要在类路径中拥有application.conf文件,并至少包含以下内容:

akka {
    event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
    loglevel = DEBUG
    stdout-loglevel = INFO
}

当然,还要确保你正在使用logback(或slf4j-log4j等)。 如果你的类路径中有logback-classic-1.0.0.jar,请确保你的类路径中没有任何其他SLF4J适配器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接