Я согласен, что 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>
Я думаю, что RoutingAppender подходит там, где у нас есть некоторые регистраторы, ранее определенные и динамически, мы должны выбрать регистратор, на который мы хотим сбросить журналы. Но в моей ситуации я должен создать несколько журналов для каждого потока, и имя файла журнала будет основано на времени вызова потока, идентификатора процесса или имени нити и т. Д. Пожалуйста, помогите мне в этом. Если это можно сделать с помощью RoutingAppender, тогда дайте некоторые подсказки для продолжения этого. Thank you – user1890780
Чтобы быть честным, ваши требования звучат очень сложно. Нет ли более простого способа? Но, полагая, что вы не можете контролировать дизайн, я все еще думаю, что вы можете делать то, что вы описываете с помощью RoutingAppender. Еще раз посмотрите пример RoutingAppender в FAQ. Последний маршрут динамически создает файл журнала с именем, основанным на значении ThreadContext. Карта ThreadContext имеет локальные значения потока, поэтому каждый поток может поместить некоторое значение на основе упомянутых вами аспектов (время, pid, tid). Это значение становится частью имени файла, поэтому для этого вы получаете отдельный файл журнала. –