简体   繁体   English

每次对logger.info/debug/warn()调用进行多次调用时,仅使用log4j记录一次

[英]Logging with log4j only once every so many calls to logger.info/debug/warn() calls

I have a scenario where a particular log message might get printed a lot of times (may be in millions). 我有一种情况,一条特定的日志消息可能会打印很多次(可能以百万计)。 For example, if we log (using logger.warn() method)for every record with the missing field(s), we might end up logging a lot-cases where input file has a lot of records with missing fields(for example, large files on HDFS). 例如,如果我们记录(使用logger.warn()方法)以查找每个缺少字段的记录,则最终可能会记录很多情况,其中输入文件包含很多记录而缺少字段(例如, HDFS上的大文件)。 This quickly fills up the disk space. 这样可以快速填满磁盘空间。

To avoid this situation, I am trying to log once for every (for example) 1000 records with missing fields. 为了避免这种情况,我尝试为每个(例如)缺少字段的1000条记录记录一次。 I can implement all of this logic outside of the log4j package, but I was wondering if there is a cleaner way to do this. 我可以在log4j包之外实现所有这些逻辑,但是我想知道是否有更干净的方法可以做到这一点。 Ideally, all of this logic would go into the log4j code. 理想情况下,所有这些逻辑都应纳入log4j代码中。

This seems like a commonly encountered problem, but there is hardly any info on this. 这似乎是一个经常遇到的问题,但是几乎没有任何信息。 Any thoughts? 有什么想法吗?

Log4J cant do that out of the box. Log4J不能开箱即用。 However you may try to write your own listener. 但是,您可以尝试编写自己的侦听器。 If you want to switch to Logback as your logging framework, there is a Filter called DuplicateMessageFilter that drops messages after a certain repetition. 如果要切换为Logback作为日志记录框架,则有一个名为DuplicateMessageFilter的过滤器,该过滤器在重复一定次数后会丢弃消息。 You should really consider this, because that much logging will surely impact on your performance. 您应该真正考虑这一点,因为太多的日志记录肯定会影响您的性能。 Logback is configured the same way as Log4J and supports SLF4J out of the box. Logback的配置方式与Log4J相同,并且开箱即用地支持SLF4J。

You can use a counter and set the log level programmatically. 您可以使用计数器并以编程方式设置日志级别。 Not the best software design, but enough if you want to do this kind of logging only at one point. 不是最好的软件设计,但是如果您只想一次进行这种记录就足够了。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM