【问题标题】:Some messages getting logged multiple times in log4j multi-threading application在 log4j 多线程应用程序中多次记录一些消息
【发布时间】:2013-11-11 07:39:16
【问题描述】:

在 JAVA 中,假设我有一个使用 log4j 的多线程应用程序,并且有超过 1000 个线程 t1、t2、t3 等等,运行和调用相同的日志记录函数,传递一条消息以及线程 ID,例如 log .info("信息消息").

这是 Filelogger 类:

public class FileLogger
{
 private static ConcurrentHashMap<String, AnalyticsLogger> hmap = new ConcurrentHashMap<String, AnalyticsLogger>();
    private static final String DELIM = "|";

    public static class AnalyticsLogger
    {
        private Logger logger;
        private AnalyticsLogger(String name)
        {
            logger = Logger.getLogger(name);
            logger.setAdditivity(false);
        }

        public void stat(String tag, Object map)
        {
            logger.info(tag.toString() + DELIM + map.toString());
        }
    }

    public static AnalyticsLogger getFileLogger(String loggerName)
    {
        AnalyticsLogger aLogger = hmap.get(loggerName);
        if(aLogger == null) {
            hmap.putIfAbsent(loggerName, new AnalyticsLogger(loggerName));
            aLogger = hmap.get(loggerName);
        }
        return aLogger;
    }

}

实例创建:

//creating object
private static AnalyticsLogger analyticsLogger = FileLogger.getFileLogger("1");
//calling method
analyticsLogger.stat(tag, obj.toJSONString());

注意: 1. 我使用并发 hashmap 来确保特定记录器应该有一个且只有一个实例,以便整个日志消息到一个位置。 (虽然我认为 Logger.getLogger() 是线程安全的,但仍然使用 hashmap 来双重确保)

  1. 有趣的是,一些随机消息会在随机时间发生。 一些消息被记录了更多 100 次。

请帮帮我

【问题讨论】:

  • 如何确定多次记录是记录器的问题,而不是线程实际上多次调用记录方法?
  • 我很确定,因为完全相同的消息(带有时间戳)正在多次记录,并且我的流程还会将相同的数据发送给一次收到此消息的客户端。

标签: java multithreading log4j


【解决方案1】:

Log4J 必须同步,否则您会在文件中看到交错和乱码的日志消息。但至少在 Logback 中,只有 appenders 是同步的,而不是整个日志消息(因此计算有效日志级别、日志消息等是多线程的)。

您可能还对AsyncAppender 感兴趣,以便在一个不同的线程中对日志消息进行排队。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 2010-12-09
    • 1970-01-01
    • 2012-07-28
    • 2019-06-14
    • 2011-02-08
    相关资源
    最近更新 更多