log4j, вложенные диагностические контексты

#java #log4j #ndc

#java #log4j #ndc

Вопрос:

У меня есть объект MySession (общий сеанс, а не веб), который выполняется в его потоке. Я хочу использовать класс NDC, чтобы включить некоторые данные, взятые из полей моей MySession: пользователь, который его создал, время запуска и т.д. и т.п. Я хотел бы «отобразить» поля в сообщении. Возможно ли это или поддерживается только для сообщений? Заранее спасибо

 public class MySession {
    String userName;
    Date startTime;

    public void doSomething() {
        NDC.push(this);                                    //cannot do something like this?
        NDC.push(this.userName 
                    " "   startTime.toString());          //or should I do this? 
    }

}
  

Ответ №1:

NDC просто добавляет «контекст» (строку произвольной формы) ко всем сообщениям журнала (которые могут выводиться, а могут и не выводиться в зависимости от формата ведения журнала). Вложенная часть означает, что NDC.pop() возвращается к предыдущему (на следующий уровень выше) контексту.

Тем не менее, в любой заданный момент контекст представляет собой единственную строку произвольной формы — так что вы правы, что вам нужно было бы ввести что-то вроде this.username '.' this.startTime.toString() , как в вашем втором примере. Вы можете видеть из API, который push принимает строковый аргумент; этот контекст используется только как часть сообщения журнала (неявно строка), поэтому не было бы никакой пользы в принятии произвольных объектов другого типа.

Ответ №2:

Вы можете поместить практически любой текст (или текстовое представление любого объекта), который вы хотите, в NDC. Визуализация объектов в NDC не поддерживается, хотя toString() этого (или, по крайней мере, должно быть) почти всегда достаточно. Слишком много и / или сложных элементов в NDC затруднили бы чтение журналов, поэтому рекомендуется ограничить содержимое NDC необходимым минимумом.

Например, в вашем случае указывать время начала сеанса в каждом сообщении журнала было бы излишним (и потенциально неоднозначным тоже). Было бы лучше вводить в NDC только какой-то уникальный идентификатор сеанса (если у вас есть такая возможность) и регистрировать любые другие сведения о сеансе, такие как имя пользователя, время запуска в выделенных сообщениях сразу после установки NDC. Это по-прежнему позволяет вам извлекать все необходимые данные сеанса из ваших журналов и идентифицировать соответствующий сеанс для любого конкретного сообщения журнала.

Комментарии:

1. хорошо, но если это так просто, не является ли это клоном, простым «красивым именем» для идентификатора потока, который уже предоставлен без NDC?

2. @AgostinoX, нет, он гораздо более универсален и может использоваться способами, недоступными идентификатору потока. Например, в веб-приложении он может содержать идентификатор сеанса, где сеанс часто охватывает несколько запросов (и, следовательно, обрабатывается несколькими различными потоками).