1

我想在某个阈值之后记录我的应用程序的消息。在 10 条消息后说。我阅读了内存处理程序并使用了它。但是我发现它会立即记录消息,而不是像文档中所说的那样缓冲它们。这是代码

Handler h = new FileHandler('/var/tmp/process.log',Level.INFO);
Handler h2 = new MemoryHandler(h, 10, Level.ALL);
logger.addHandler(h2);

for(int i=0; i<10; i++) {
    logger.log(Level.INFO, "Sample message");
    Thread.sleep(1000);
}

此代码立即添加上述消息。我错过了什么?我的目的是不让太多的磁盘 I/O 发生。请帮忙

4

2 回答 2

2

第三个构造函数参数

Handler h2 = new MemoryHandler(h, 10, Level.ALL);

定义推送级别,即如果记录了给定级别或更高级别的消息,MemoryHandler 会将其推送到配置的下游处理程序(jdk 文档)。

我不认为 MemoryHandler 适合您想要实现的目的。您可以使用固定大小的缓冲区创建自己的 MemoryHandler 实现,该缓冲区在缓冲区已满时刷新。但是请考虑这种方法的缺点:当应用程序终止时日志消息可能会丢失,刷新可能涉及阻塞 I/O,并且您无法确定哪个线程必须执行该 I/O。

或者,您可以考虑使用另一个经过验证的日志框架,例如 logback 或 log4j2。这些通常提供更高级的功能。我建议寻找异步日志记录。

于 2013-10-11T19:59:10.987 回答
2

您必须扩展 MemoryHandler 以提供自定义推送行为。您可以通过将推送级别设置为ALL覆盖推送方法或将推送级别设置为OFF然后手动从发布方法发出推送来执行此操作。

如果您只想在看到许多日志记录后才开始记录,那么您需要创建如下内容:

public class PopoffHandler extends MemoryHandler {

    private long count;
    private final long size;

    public PopoffHandler(Handler target, int size) {
        super(target, size, Level.ALL);
        this.size = size;
    }

    @Override
    public synchronized void push() {
        if (count == size) {
            super.push();
        } else {
            ++count;
        }
    }

    @Override
    public void setPushLevel(Level newLevel) {
        if (newLevel == null) {
            throw new NullPointerException();
        }
        super.setPushLevel(Level.ALL);
    }
}

如果您想在组中记录记录,那么您需要执行以下操作:

public class ChunkedHandler extends MemoryHandler {

    private long count;
    private final long size;

    public ChunkedHandler(Handler target, int size) {
        super(target, size, Level.OFF);
        this.size = size;
    }

    @Override
    public synchronized void publish(LogRecord record) {
        super.publish(record);
        if (++count % size == 0L) {
            super.push();
        }
    }

    @Override
    public void setPushLevel(Level newLevel) {
        if (newLevel == null) {
            throw new NullPointerException();
        }
        super.setPushLevel(Level.OFF);
    }
}
于 2016-11-02T17:46:55.460 回答