Я использую slf4j v2.0.9 и log4j v2.21.1.
Журнал MCD работает должным образом, но я дополнительно получаю следующее предупреждение.
WARN StatusConsoleListener Ключ MDC_KEY использовался как в строковом, так и в стековом MDC.
Помимо установки значения для регистрации, я также читаю значение MDC, чтобы получить значение и передать его следующему запросу REST. В файле log4j.xml я использую следующий шаблон для записи значения MDC --> %X{MDC_KEY}
В коде, который я использую
public static final String DEFAULT_MDC_KEY = "MDC_KEY";
@Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException
{
try
{
//...
MDC.pushByKey(DEFAULT_MDC_KEY, breadcrumbValue);
//...
}
catch(Exception ex)
{
//...
}
finally
{
MDC.clear();
}
}
В другом классе я получаю значение, если оно установлено.
MDC.get(DEFAULT_MDC_KEY)
Что могло стать причиной предупреждения? Есть ли способ подавить предупреждение?
Спасибо, МХ





TL;DR Вероятно, вы захотите использовать:
try (MDCCloseable unused = MDC.putCloseable(DEFAULT_MDC_KEY, breadcrumbValue)) {
try {
...
} catch (Exception e) {
...
}
}
Прежде всего спасибо за внимание к предупреждениям: по моему опыту, в наши дни это редкий навык.
SLF4J MDC предлагает два вида методов:
Map<String, Deque<String>>.MDC.get/put/putCloseable/getCopyOfContextMap из SLF4J 1.x обеспечивают доступ к каждому потоку Map<String, String>.
Хотя из Javadoc неясно, реализация этой карты по умолчанию отличается от карты контекстной очереди.Чтобы реализовать эти функции в мосте между API SLF4J и API Log4j (см. LOG4J2-3583 ) без расширения API Log4j, мы решили сопоставить как карту контекста, так и карту контекстного дека с единым Map<String, Object>, предлагаемым ️. 🔁 ThreadContext.
Вот почему обе карты доступны через конвертер шаблонов %X{...}.
Однако, чтобы пользователи не могли по ошибке перезаписать весь стек с помощью MDC.set, мы выдаем предупреждения, когда один и тот же ключ используется как в карте контекста, так и в карте контекстного дека.
Чтобы избавиться от предупреждений, не используйте один и тот же ключ для методов разных групп. Я бы порекомендовал использовать более поддерживаемые MDC.get/put/putCloseable методы.
Примечание: насколько я мог проверить, в Logback в настоящее время нет шаблона преобразования, который позволил бы пользователям отображать значения карты контекстного дека. Поэтому использование старых методов позволяет вам быть независимыми от реализации журналирования.
Самый простой способ — посмотреть исходный код. Почему вам нужно использовать pushByKey вместо put?
Большое спасибо Петр за быстрый ответ. Я не получаю предупреждение сейчас. Для чтения значения я использую MDC.get(DEFAULT_MDC_KEY) и думаю, что это то же самое, что и MDC.getCopyOfContextMap().get(DEFAULT_MDC_KEY). Я также попробовал MDC.getMDCAdapter().getCopyOfDequeByKey(DEFAULT_MDC_KEY), но он возвращает ноль. Чего не хватает при чтении значения?