每次调用logger.info/debug/warn()时,只使用log4j记录一次

时间:2015-07-14 07:10:42

标签: java hadoop logging log4j

我有一个场景,可能会多次打印特定的日志消息(可能是数百万)。例如,如果我们为缺少字段的每个记录记录(使用logger.warn()方法),我们最终可能会记录很多情况,其中输入文件包含大量缺少字段的记录(例如, HDFS上的大文件)。这会快速填满磁盘空间。

为了避免这种情况,我试图为每个(例如)1000个缺少字段的记录记录一次。我可以在log4j包之外实现所有这些逻辑,但我想知道是否有更简洁的方法来执行此操作。理想情况下,所有这些逻辑都将进入log4j代码。

这似乎是一个常见的问题,但几乎没有任何信息。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

Log4J无法开箱即用。但是,您可以尝试编写自己的侦听器。如果要切换到Logback作为日志记录框架,则会有一个名为DuplicateMessageFilter的过滤器在重复一段时间后丢弃消息。您应该考虑这一点,因为大量的日志记录肯定会影响您的性能。 Logback的配置方式与Log4J相同,并支持开箱即用的SLF4J。

答案 1 :(得分:0)

您可以使用计数器并以编程方式设置日志级别。不是最好的软件设计,但如果你只想在某一点上进行这种记录就足够了。

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class LogExample {

    private static final Logger LOG = Logger.getLogger(LogExample.class);

    private static final Level DEFAULT_LOG_LEVEL = Level.ERROR;

    public static void main(final String[] args) {
        int count = 0;
        LOG.setLevel(DEFAULT_LOG_LEVEL);
        for (int i = 1; i < 1000000; i++) {
            count++;
            final boolean logInfo = (count % 1000) == 0;
            if (logInfo) {
                LOG.setLevel(Level.INFO);
            }
            LOG.info("test: " + i);
            if (logInfo) {
                LOG.setLevel(DEFAULT_LOG_LEVEL);
            }
        }
    }
}