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

uurity8g  于 2021-05-29  发布在  Hadoop
关注(0)|答案(2)|浏览(409)

我有一个场景,其中一个特定的日志消息可能会被打印很多次(可能是数百万次)。例如,如果我们记录(使用 logger.warn() 方法)对于每个缺少字段的记录,我们可能会记录很多情况,其中输入文件有很多缺少字段的记录(例如,hdfs上的大文件)。这会很快填满磁盘空间。
为了避免这种情况,我尝试为每1000条缺少字段的记录记录记录一次。我可以在log4j包之外实现所有这些逻辑,但是我想知道是否有更干净的方法来实现这一点。理想情况下,所有这些逻辑都将进入log4j代码。
这似乎是一个常见的问题,但几乎没有任何信息。有什么想法吗?

v440hwme

v440hwme1#

log4j不能在开箱即用。但是你可以试着写你自己的听众。如果您想切换到logback作为您的日志框架,那么有一个名为duplicatemessagefilter的过滤器,它会在特定的重复之后删除消息。您应该认真考虑这一点,因为日志记录太多肯定会影响您的性能。logback的配置方式与log4j相同,支持slf4j开箱即用。

x6h2sr28

x6h2sr282#

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

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);
            }
        }
    }
}

相关问题