Это отличный вопрос! Жаль, что log4j не пытается вам здесь помочь. Но мы можем быть хитрыми и использовать log4j, чтобы исправить log4j! Важной концепцией является Диагностический контекст :
private static final String IN_APPEND_KEY = MyAppender.class.getName() + ".inAppend";
public void append(LoggingEvent e) {
if (e.getMDC(IN_APPEND_KEY) != null) return;
MDC.put(IN_APPEND_KEY, this);
try {
<your code here>
} finally {
MDC.remove(IN_APPEND_KEY);
}
}
Вы в основном хотите установить флаг, который будет "путешествовать" с потоком выполнения вашего аппендера. Это именно то, что делает диагностический контекст, по крайней мере, в теории. Он является локальным для потока и наследуется между потоками. Тщательно написанный код даже сохранит контекст через другие границы, такие как очередь сообщений. Как здорово, что это будет: ваш аппендер помещает сообщение журнала в очередь HTTP-запросов, очередь сохраняет диагностический контекст и восстанавливает его при запуске запроса, HTTP-библиотека регистрирует ошибку, а ваш аппендер все еще обнаруживает цикл! Это самое лучшее, что вы можете попросить.