我正在使用log4j AsyncAppender
。我编写了自己的appender来自定义记录器,如下所示。
公共类MyAppender扩展了AppenderSkeleton {
@Override
public void close() {
}
@Override
public boolean requiresLayout() {
return false;
}
@Override
protected void append(LoggingEvent event) {
//Here am doing some logic which will connect database and fetch some records.
}
}
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<!-- Appenders -->
<appender name="stdout" class="com.sample.MyAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %p [%c] - %m%n"/>
</layout>
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="500"/>
<appender-ref ref="stdout"/>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="ASYNC" />
</root>
</log4j:configuration>
现在一切正常。我MyAppender
我将触发Select
查询并从表中获取一些详细信息,并使用java mail API发送这些详细信息。当我使用AsyncAppender
时,它不会阻止现有的运行线程并且MyAppender逻辑是异步执行的。我的问题是主线程是否在MyAppender
逻辑完成之前完成其执行然后是否有任何保证即使主线程完成执行,MyAppender
中的逻辑也会完成?
谢谢!
答案 0 :(得分:1)
已经过了一年,但我会在我之后回答别人的利益。安全关闭所有appender并确保在日志记录完成之前JVM没有关闭的正确方法是调用LogManager.shutdown();
。我还没有确认,但在Log4j 2中显然没有必要,因为它会自动向JVM注册一个关闭钩子。
答案 1 :(得分:0)
快速查看AsyncAppender
班source code。似乎异步处理日志记录事件的线程被设置为守护程序线程。因此,当主线程退出日志记录线程时也会退出,可能是队列中未处理的日志记录请求。
setDaemon(true)
调用上方还有一条评论:用户有责任在退出前关闭appender。(意味着关闭记录器线程后将完成其排队的记录事件,请参阅close()
方法代码段
public AsyncAppender() {
appenders = new AppenderAttachableImpl();
aai = appenders;
dispatcher = new Thread(new Dispatcher(this, buffer, discardMap, appenders));
// It is the user's responsibility to close appenders before
// exiting.
dispatcher.setDaemon(true);
// set the dispatcher priority to lowest possible value
// dispatcher.setPriority(Thread.MIN_PRIORITY);
dispatcher.setName("AsyncAppender-Dispatcher-" + dispatcher.getName());
dispatcher.start();
}
//Close this AsyncAppender by interrupting the dispatcher
//thread which will process all pending events before exiting.
public void close() {
...
try {
dispatcher.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
org.apache.log4j.helpers.LogLog.error(
"Got an InterruptedException while waiting for the "
+ "dispatcher to finish.", e);
}
...
}