Круговая зависимость при входе в систему в приложении log4j - PullRequest
3 голосов
/ 12 июня 2011

Я пишу приложение log4j, которое отправляет журналы на сервер через http.Я хотел использовать HttpClient из apache-commons, чтобы сделать мой код красивым и простым.

Проблема теперь в том, что HttpClient и Co. используют сам log4j.Обычно это хорошо, но при вызове их из реализации приложения log4j вводятся циклические ссылки или бесконечные циклы, что в конечном итоге приводит к исключению OutOfMemoryException.

Конечно, я могу написать то, что я хочу, без каких-либо сторонних библиотек, но мне просто интересно, есть ли известное решение для такого рода проблем?

Ответы [ 2 ]

4 голосов
/ 29 июля 2011

Это отличный вопрос! Жаль, что 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-библиотека регистрирует ошибку, а ваш аппендер все еще обнаруживает цикл! Это самое лучшее, что вы можете попросить.

0 голосов
/ 12 июня 2011

Почему регистратор из Apache HttpClient использует ваш Appender?Дайте ему другой Appender, Console или что-то еще.

...