2

我正在使用 log4j AsyncAppender。我编写了自己的附加程序来自定义记录器,如下所示。

公共类 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 配置:

<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 邮件 API 发送这些详细信息。正如我正在使用AsyncAppender的那样,它不会阻塞现有的正在运行的线程,并且 MyAppender 逻辑是异步执行的。我的问题是,如果主线程在逻辑完成之前完成它的执行,那么即使主线程也能MyAppender保证逻辑将完成MyAppender完成执行?

谢谢!

4

2 回答 2

2

已经一年了,但我会为了我之后的其他人的利益而回答。安全关闭所有附加程序并确保您的 JVM 在日志记录完成之前不会关闭的正确方法是调用LogManager.shutdown();. 我还没有确认,但这在 Log4j 2 中显然不是必需的,因为它会自动向 JVM 注册一个关闭挂钩。

于 2015-01-07T21:24:20.667 回答
0

只是快速浏览了一下AsyncAppender源代码。似乎异步处理日志事件的线程被设置为守护线程。因此,当主线程退出时,日志线程也会退出,可能队列中有未处理的日志请求。

setDaemon(true)调用上方还有一条注释:在退出之前关闭附加程序是用户的责任。(这意味着在关闭记录器线程时将完成其排队的记录事件,请参阅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);
    }
    ...
  }
于 2013-10-18T07:31:02.107 回答