我有一个使用Logback并启用了SizeBased Rolling Policy的Dropwizard应用程序。但是,在推出当前日志文件后,该进程仍会保持打开旧文件的FD链接。因此,磁盘使用率爆炸。深入研究源代码,我遇到了这个函数,它在Rollover时被调用。
*设置并打开日志输出的文件 会去。指定的*文件必须是可写的。 * *
* 如果已经打开了文件,则关闭上一个文件 第一。 * *
* 请勿直接使用此方法。要配置FileAppender或其子类之一,请设置它 属性一个接一个,然后调用start()。
- @param file_name
- 日志文件的路径。
public void openFile(String file_name) throws IOException {
lock.lock();
try {
File file = new File(file_name);
if (FileUtil.isParentDirectoryCreationRequired(file)) {
boolean result = FileUtil.createMissingParentDirectories(file);
if (!result) {
addError("Failed to create parent directories for ["
+ file.getAbsolutePath() + "]");
}
}
ResilientFileOutputStream resilientFos = new ResilientFileOutputStream(
file, append);
resilientFos.setContext(context);
setOutputStream(resilientFos);
} finally {
lock.unlock();
}
}
文档说明" 如果已经打开了文件,则先关闭上一个文件"
任何人都可以准确地告诉上述函数的哪一部分处理关闭文件?而且,问题的可能解决方案。
答案 0 :(得分:1)
如果你深入挖掘,你的最后一个电话是:
setOutputStream(resilientFos);
该电话的内容如下所示:
/**
* <p>
* Sets the @link OutputStream} where the log output will go. The specified
* <code>OutputStream</code> must be opened by the user and be writable. The
* <code>OutputStream</code> will be closed when the appender instance is
* closed.
*
* @param outputStream
* An already opened OutputStream.
*/
public void setOutputStream(OutputStream outputStream) {
lock.lock();
try {
// close any previously opened output stream
closeOutputStream();
this.outputStream = outputStream;
if (encoder == null) {
addWarn("Encoder has not been set. Cannot invoke its init method.");
return;
}
encoderInit();
} finally {
lock.unlock();
}
}
closeOutputStream()将关闭上一个流。
查看impl,FileAppender只有一个流。每当调用setOutputStream或者只是完全关闭appender时它就会关闭。看来你的问题可能在其他地方。
希望有所帮助,
阿图尔