log4j2:工作线程加入主线程

时间:2016-08-05 19:45:30

标签: java multithreading log4j2

我正在使用log4j2将日志写入控制台和多个线程的文件。我希望保留工作线程的日志,而不是混合来自不同线程的行,并且只有当工作线程加入主线程时才刷新它们。我怎么能这样做?

例如,不要使用以下日志:

Thread 1 started.
Thread 2 started.
Thread 1 working...
Thread 2 working...
Thread 1 working...
Thread 2 working...
Thread 1 finished.
Thread 2 finished.

我想:

Thread 1 started.
Thread 1 working...
Thread 1 working...
Thread 1 finished.
Thread 2 started.
Thread 2 working...
Thread 2 working...
Thread 2 finished.

1 个答案:

答案 0 :(得分:0)

  1. 为每个线程定义一个Logger对象。
  2. 对于来自(1)的记录器,禁用向上传递日志(将additivity设置为false)
  3. 从(1)向记录器添加WriterAppender,传入ByteArrayOutputStream个实例。
  4. 加入主题后,获取(3)中定义的OutputStream并相应处理
  5. 例如:

    public static void main(String[] args) throws Exception{
        BasicConfigurator.configure();
        LoggerRunner[] runners = new LoggerRunner[]{new LoggerRunner("t1"), new LoggerRunner("t2")};
        Thread t1 = new Thread(runners[0]);
        Thread t2 = new Thread(runners[1]);
        t1.start();
        t2.start();
        t1.join();
        System.out.println("Joined 1");
        t2.join();
        System.out.println("Joined 2");
        System.out.print(new String(runners[0].getLog()));
        System.out.print(new String(runners[1].getLog()));
    }
    
    private static class LoggerRunner implements Runnable{
    
        private final Logger logger;
    
        private ByteArrayOutputStream logs = new ByteArrayOutputStream();
        private final String name;
        public LoggerRunner(String name){
            this.name = name;
            logger = Logger.getLogger(name);
            logger.setAdditivity(false);
            logger.addAppender(new WriterAppender(new PatternLayout("%-1r [%t] %-5p %c %x - %m%n"), logs));
        }
    
        public byte[] getLog(){
            return logs.toByteArray();
        }
    
        @Override
        public void run() {
            logger.info(name + " started");
            try{
                Thread.sleep(1000);
                logger.info(name + " working");
                Thread.sleep(1000);
            }catch(Exception e){}
            logger.info(name + " finished");
        }
    }