В Log4j, в чем разница между NDC и MDC? Могу ли я иметь простой пример, где они используются?
В чем разница между возможностями Log4j NDC и MDC?
Ответ 1
Чтобы расширить ссылку которую Сикорски добавил в комментарии:
NDC
В NDC N обозначает вложенный, то есть вы контролируете одно значение с помощью Stack. Вы "нажимаете" строку, тогда вы можете "нажимать" другую, когда обрабатывается диктует; и когда обработка завершена, вы можете выскочить, чтобы увидеть прежнее значение. Такой тип контекстного ведения журналов был бы полезен в некоторой глубоко вложенной обработке.
Установка строки контекста
NDC.push("processingLevel2");
log.info("success");
Это будет выводиться в вашем журнале, где у вас есть шаблон %x
(нижний регистр):
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %C %x = %m%n
MDC
M означает отображение, и это дает вам другой тип контроля. Вместо использования одного стека для управления одной контекстной строкой вы используете пары имя/значение. Это полезно для отслеживания нескольких контекстуальных битов, таких как включение имени пользователя и IP в журнал.
Настройка отображаемых значений:
MDC.put("userIP", req.getRemoteAddr());
MDC.put("userName", foo.getName());
log.info("success");
Пример шаблона MD4 log4j
Верхний регистр X с примерами строк "userIP"
и "userName"
. Они должны совпадать в вашем коде и в конфигурации log4j:
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %X{userIP} %C %X{userName} = %m%n
Я бы объединил их в одну) строку контекста *.
Сходства и различия
В обоих случаях, когда вы делаете log.info("success");
, на выходе будет дополнительный контекст, который вы предоставили. Это намного чище, чем конкатенация строк, таких как log.info(req.getRemoteAddr()) + " success");
каждый раз, когда вы регистрируетесь.
Обратите внимание, что между ними существуют серьезные различия в отношении потоков и ресурсов. В частности, NDC будет держать ручки в ваших потоках, которые могут повлиять на освобождение ресурсов, если вы не проявляете усердие по поводу выскакивания и очистки стека NDC.
Из ссылки: использование NDC может привести к утечке памяти, если вы не периодически вызываете метод NDC.remove()
.
Ответ 2
MDC позволяет добавлять пользовательские теги для log4j. например:
%X{mytag} in log4j.xml
ссылается на
MDC.put("mytag","StackOverflow");
Детский поток MDC автоматически наследует копию сопоставленного диагностического контекста его родителя.
Операции NDC, такие как push
, pop
, clear
, getDepth
и setMaxDepth
влияют только на NDC текущего потока.