log4j-1.2 无法翻转(未创建新文件)

时间:2021-02-25 21:47:49

标签: java log4j

当我的应用程序在翻转时有“打开的文件太多”时会出现此问题

java.lang.NullPointerException at 
      org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:310)

即使 FD 可用,这也不会恢复(就像在未创建的新文件中一样)。 当 FD 可用时,有没有办法从这个问题中自动恢复(即创建新文件并发出日志)?我可以做某种异常处理来解决这个问题吗? 注意:对于我的案例,我不想增加 FD 限制。

1 个答案:

答案 0 :(得分:1)

如果您查看 WriterAppender 中的 javadocs,会显示与引发错误的方法相关的内容:

<块引用>

protected void subAppend(LoggingEvent event)

实际写作发生在这里。 WriterAppender 的大多数子类都需要覆盖 这种方法

正如您所评论的, DailyRollingFileAppender 覆盖了它,但也调用了 super ,在最后调用了 WriterAppendersubAppend()其执行 (Source code)


DailyRollingFileAppender

enter image description here


WriteAppender

enter image description here

我的猜测是黄色标记线对此负责,因为 event 或其某些字段是 null


可能的解决方案

您可以实现自己的 DailyRollingFileAppender 扩展,以检查空值或将其包含在 try-catch 块中以避免您当前的情况:异常不会被捕获并传播直到停止整个过程。

这只是一个示例,您必须根据自己的需要和对错误的了解来实现它;所以就拿它作为基础。

重点是从 appender 扩展并覆盖 subAppend 方法。这样,您就可以正确管理异常。

public class FailHandlerRollingAppender extends DailyRollingFileAppender 
{     
    @Override
    protected void subAppend(LoggingEvent event) 
    { 
       try
       {    
          boolean correctEvent=false;
         /*check if event is null, or any field is null, for example.
          If needed, also modify the event as you wish, before calling super.
          Enclosing it in a try-catch block would avoid the uncontrolled exception.
          All your logic you need to include here.*/
         
          if (correctEvent)
              super.subAppend(event);
        }  
        catch (Exception e) 
        {
           e.printStackTrace(); 
           //...
        }
     }    
}

最后一步是在您的配置文件中将其声明为 appender(这取决于所使用的 log4j 版本,但在某种程度上类似)。举个例子:

 //...
<appender name="FailHandlerRollingAppender" class="x.y.pack.FailHandlerRollingAppender">
     <param name="Append" value="true"/>
     <param name="datePattern" value="'.'yyyy-MM-dd"/>
     <param name="File" value="mine.log"/>
     <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d %-5p (%x) [%t] %c{1} - %m%n" />
     </layout>
 </appender>
 <root>
    <priority value="info"/>
    <appender-ref ref="FailHandlerRollingAppender"/>
 </root>
 //...

覆盖有问题的 subAppend() 应该可以让您管理这种情况;至少,您可以避免非托管异常传播,并从那里处理特定的容易出错的场景。

相关问题