当我的应用程序在翻转时有“打开的文件太多”时会出现此问题
java.lang.NullPointerException at
org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:310)
即使 FD 可用,这也不会恢复(就像在未创建的新文件中一样)。 当 FD 可用时,有没有办法从这个问题中自动恢复(即创建新文件并发出日志)?我可以做某种异常处理来解决这个问题吗? 注意:对于我的案例,我不想增加 FD 限制。
答案 0 :(得分:1)
如果您查看 WriterAppender
中的 javadocs,会显示与引发错误的方法相关的内容:
protected void subAppend(LoggingEvent event)
实际写作发生在这里。 WriterAppender 的大多数子类都需要覆盖 这种方法。
正如您所评论的, DailyRollingFileAppender
覆盖了它,但也调用了 super ,在最后调用了 WriterAppender
的 subAppend()
其执行 (Source code)
DailyRollingFileAppender
WriteAppender
我的猜测是黄色标记线对此负责,因为 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()
应该可以让您管理这种情况;至少,您可以避免非托管异常传播,并从那里处理特定的容易出错的场景。