【问题标题】:How to customize java log file to contain at most N log records only instead of size in bytes如何自定义 java 日志文件以最多仅包含 N 条日志记录,而不是以字节为单位的大小
【发布时间】:2018-05-30 09:57:35
【问题描述】:
我正在使用java.util.logging 来生成日志文件。它利用 FileHandler 将写入记录写入日志文件。
FileHandler 类包含限制参数来决定在当前日志文件的大小(以字节为单位)超过限制的情况下何时创建新文件。
有什么方法可以覆盖将文件处理程序限制为其他参数而不是大小的行为? like - 每个日志文件中最多 N 条记录。如果出现第 (N+1) 个记录,则会生成一个新的文件日志文件。
如果使用标准 java.logging 无法实现,是否有任何其他开源实现此行为(如 log4j 或任何其他开源记录器)?
【问题讨论】:
标签:
java
log4j
java.util.logging
【解决方案1】:
通过覆盖setLevel 方法,可以扩展 FileHandler 以侦听旋转。然后通过将限制设置为一个字节来强制 FileHandler 始终旋转,然后在不满足条件时防止旋转发生。
这是一个示例解决方案:
import java.io.File;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
public class CountingFileHandler extends FileHandler {
private static final RuntimeException PREVENT_ROTATE = new RuntimeException();
private final long maxRecords;
private long count;
public CountingFileHandler(String pattern, long maxRecords, int files) throws IOException {
super(pattern, 1, files, false);
this.maxRecords = maxRecords;
}
@Override
public synchronized void setLevel(Level lvl) {
if (Level.OFF.equals(lvl)) { //Rotation sets the level to OFF.
if (++count < maxRecords) {
throw PREVENT_ROTATE;
}
count = 0L;
}
super.setLevel(lvl);
}
@Override
public synchronized void publish(LogRecord record) {
try {
super.publish(record);
} catch (RuntimeException re) {
if (re != PREVENT_ROTATE) {
throw re;
}
}
}
public static void main(String[] args) throws Exception {
System.out.println(new File(".").getCanonicalPath());
CountingFileHandler cfh = new CountingFileHandler("test%g.log", 2, 5);
cfh.setFormatter(new SimpleFormatter());
for (int i = 0; i < 10; i++) {
cfh.publish(new LogRecord(Level.SEVERE, Integer.toString(i)));
}
cfh.close();
}
}
否则,如果您只想为单个日志文件设置一些最大限制,您可以安装com.sun.mail.util.logging.DurationFilter,持续时间为Long.MAX_VALUE。该过滤器包含在javax.mail.jar or the logging-mailhandler.jar 中。此解决方案不会提供您想要的旋转。