Java 在程序运行期间重命名Log4J日志文件
我们最近从JUL(java.util.Logging)切换到Log4J,因为我想为不同的日志级别添加额外的日志文件 我们在程序中可以选择在程序执行结束时(出于所有目的)向日志文件名附加一个值和一个日期/时间戳 因为JUL似乎可以根据需要打开和关闭文件以写入文件,所以它没有被锁定,我们可以简单地使用.rename()来更改文件名 现在,使用Log4J,该文件保持打开状态并被锁定,从而阻止我们重命名该文件 在配置日志记录之前,我无法确定文件名,因为包含重命名选项的属性文件是在需要日志记录之后的一段时间(这就是我们在程序结束时重命名它的原因) 你对如何实现这一目标有什么建议吗 Logback和/或SLF4J会帮助还是阻碍这一点Java 在程序运行期间重命名Log4J日志文件,java,log4j,Java,Log4j,我们最近从JUL(java.util.Logging)切换到Log4J,因为我想为不同的日志级别添加额外的日志文件 我们在程序中可以选择在程序执行结束时(出于所有目的)向日志文件名附加一个值和一个日期/时间戳 因为JUL似乎可以根据需要打开和关闭文件以写入文件,所以它没有被锁定,我们可以简单地使用.rename()来更改文件名 现在,使用Log4J,该文件保持打开状态并被锁定,从而阻止我们重命名该文件 在配置日志记录之前,我无法确定文件名,因为包含重命名选项的属性文件是在需要日志记录之后的一段时
通过在log4j属性文件中使用系统参数,设置属性,然后重新加载属性文件,我已经解决了这个问题 这允许我在运行结束时将日志文件的名称更改为其他名称,然后重命名旧文件
这是不雅观的,而且非常混乱,因此我希望避免这种情况,因为它在运行后还会留下这些临时文件。考虑使用关闭挂钩,并在那里重命名文件
一种可靠的方法是实现您自己的log4j Appender,可能基于FileAppender()。添加您自己的专用API以请求重命名文件 我还没有尝试过这一点,但我会采取的策略是使用底层API设置文件(…): 例如:
public class RenamingFileAppender extends FileAppender {
...
/** fix concurrency issue in stock implementation **/
public synchronized void setFile(String file) {
super.setFile(file);
}
public synchronized void renameFile(String newName) {
// whole method is synchronized to avoid losing log messages
// implementation can be smarter in having a short term queue
// for any messages that arrive while file is being renamed
File currentFile = new File(this.fileName);
File newFile = new File(newName);
// do checks to ensure current file exists, can be renamed etc.
...
// create a temp file to use while current log gets renamed
File tempFile = File.createTempFile("renaming-appender", ".log");
tempFile.deleteOnExit();
// tell underlying impl to use temporary file, so current file is flushed and closed
super.setFile(tempFile.getAbsolutePath(), false, this.bufferedIO, this.bufferSize);
// rename the recently closed file
currentFile.renameTo(newFile);
// now go back to the original log contents under the new name. Note append=true
super.setFile(newFile.getAbsolutePath(), true, this.bufferedIO, this.bufferSize);
}
谢谢你的指点,但是Log4J似乎在关机的时候仍然保持文件打开。谢谢,我会看看这个,但是正如我上面所说的,除非它重命名文件位置,否则它不会真正帮助解决问题。谢谢你,这正是我想要的,比我的拙劣努力要优雅得多:)