2013-11-14 3 views
1

Я запускаю приложение Java, в котором я вызываю несколько потоков, каждый из которых имеет несколько уникальных имен. Теперь я хочу создать несколько файлов журналов для каждого из них, а имя файлов журнала должно быть как имена потоков. Возможно ли это использование log4j2. Помогите мне написать файлы конфигурации log4j2.Различные файлы журналов для нескольких потоков с использованием log4j2

Заранее спасибо.

ответ

1

Это можно сделать с помощью RoutingAppender. На странице часто задаваемых вопросов есть хороший пример конфигурации.

+0

Я думаю, что RoutingAppender подходит там, где у нас есть некоторые регистраторы, ранее определенные и динамически, мы должны выбрать регистратор, на который мы хотим сбросить журналы. Но в моей ситуации я должен создать несколько журналов для каждого потока, и имя файла журнала будет основано на времени вызова потока, идентификатора процесса или имени нити и т. Д. Пожалуйста, помогите мне в этом. Если это можно сделать с помощью RoutingAppender, тогда дайте некоторые подсказки для продолжения этого. Thank you – user1890780

+0

Чтобы быть честным, ваши требования звучат очень сложно. Нет ли более простого способа? Но, полагая, что вы не можете контролировать дизайн, я все еще думаю, что вы можете делать то, что вы описываете с помощью RoutingAppender. Еще раз посмотрите пример RoutingAppender в FAQ. Последний маршрут динамически создает файл журнала с именем, основанным на значении ThreadContext. Карта ThreadContext имеет локальные значения потока, поэтому каждый поток может поместить некоторое значение на основе упомянутых вами аспектов (время, pid, tid). Это значение становится частью имени файла, поэтому для этого вы получаете отдельный файл журнала. –

3

Я согласен, что RoutingAppender - это путь. Первоначально я использовал приложение маршрутизации в сочетании с поиском $ {ctx: threadName}, где «ctx» использует ThreadContext. Я обнаружил, что я должен был бы посыпать в коде строку, как это:

ThreadContext.put("threadName", Thread.currentThread().getName()); 

Хотя этот код работает это не расширяемый в разработке кода. Если бы я должен был добавить новый код java.lang.Runnable в базу кода, я должен был бы также включить эту строку.

Скорее всего, решение, как представляется, для реализации 'org.apache.logging.log4j.core.lookup.StrLookup' и зарегистрировать @Plugin с PluginManager Как это:

Класс: ThreadLookup

package my.logging.package  
import org.apache.logging.log4j.core.LogEvent; 
import org.apache.logging.log4j.core.config.plugins.Plugin; 
import org.apache.logging.log4j.core.lookup.StrLookup; 

@Plugin(name = "thread", category = StrLookup.CATEGORY) 
public class ThreadLookup implements StrLookup { 

@Override 
public String lookup(String key) { 
    return Thread.currentThread().getName(); 
} 

@Override 
public String lookup(LogEvent event, String key) { 
    return event.getThreadName() == null ? Thread.currentThread().getName() 
      : event.getThreadName(); 
} 

}  

Конфигурация: log4j2.xml (packages атрибут Configuration регистрирует @Plugin с PluginManager)

<?xml version="1.0" encoding="UTF-8"?> 
<Configuration status="warn" packages="my.logging.package"> 
    <Appenders> 
     <Routing name="Routing"> 
      <Routes pattern="$${thread:threadName}"> 
       <Route> 
        <RollingFile name="logFile-${thread:threadName}" 
        fileName="logs/concurrent-${thread:threadName}.log" filePattern="logs/concurrent-${thread:threadName}-%d{MM-dd-yyyy}-%i.log"> 
        <PatternLayout pattern="%d %-5p [%t] %C{2} - %m%n" /> 
        <Policies> 
         <SizeBasedTriggeringPolicy size="50 MB" /> 
        </Policies> 
        <DefaultRolloverStrategy max="100" /> 
       </RollingFile> 
      </Route> 
     </Routes> 
    </Routing> 
    <Async name="async" bufferSize="1000" includeLocation="true"> 
     <AppenderRef ref="Routing" /> 
    </Async> 
</Appenders> 
<Loggers> 
    <Root level="info"> 
     <AppenderRef ref="async" /> 
    </Root> 
</Loggers>