2016-08-05 3 views
0

Я использую 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. 

ответ

0
  1. Определить Logger объект для каждого потока.
  2. Для Logger из (1), отключить прохождение бревен вверх по иерархии (набор аддитивность к ложному)
  3. Добавить WriterAppender в Logger из (1), переходящих в ByteArrayOutputStream инстанции.
  4. После присоединения нити, получить OutputStream определено в (3) и борьбы с ним соответственно

Например:

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"); 
    } 
} 
+0

В этом случае я бы передать нить конкретным логгер где мне нужно написать журнал. Обеспечивает ли log4j2 способ справиться с этим внутренне? – Fan

+0

Не уверен, что вы имеете в виду. Вышеупомянутые данные передаются обратно в начальный вызывающий поток. Возможно, вам удастся избежать этого, распечатав журнал по завершении реализации 'run', чтобы избежать« столкновения »журнала нескольких потоков, которые вам могут понадобиться для синхронизации вызовов, возможно, заставляя их приобретать блокировку до фактического logging out – copeg

+0

Теперь я использую статический логгер. Но в вашем ответе мне нужно будет создать регистратор для каждого потока и передать их другим классам/методам. Просто интересно, есть ли другой способ. – Fan

Смежные вопросы