Как запретить logback выводить свой собственный статус в начале каждого журнала?

145

Это похоже на ошибку по неосторожности, но я не могу найти причину. Ведение журнала с помощью logback / slf4j (последняя версия slf4j-api-1.6.1, ядро ​​logback / classic 0.9.24). Простейшая конфигурация журнала для тестирования:

<configuration>
 <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
  <layout class="ch.qos.logback.classic.PatternLayout">
   <!-- DONT USE THIS FORMATTER FOR LIVE LOGGING THE %L LINE NUMBER OUTPUTTER IS SLOW -->
   <pattern>%le %-1r [%c{1}:%L] %m%n</pattern>
  </layout>
 </appender>
 <root level="DEBUG">
  <appender-ref ref="stdout" />
 </root>
</configuration>

Каждая настройка журнала начинается с внутренних строк статуса logback:

11:21:27,825 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
11:21:27,826 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [file:.../logback-test.xml]
11:21:28,116 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
11:21:28,124 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
11:21:28,129 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [stdout]
11:21:28,180 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Pushing component [layout] on top of the object stack.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - This appender no longer admits a layout as a sub-component, set an encoder instead.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
11:21:28,207 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
11:21:28,207 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [stdout] to Logger[ROOT]

согласно документам формат logback используется по умолчанию. Затем он завершает чтение конфигурации (которая настроена на вывод в другом формате) и продолжает вывод в правильно отформатированном виде. Там есть параметр конфигурации, <configuration debug="false">который не влияет на это.

Кто-нибудь знает, как это отключить?

Стив Б.
источник
Последние версии logback намного быстрее вычисляют% L.
Турбьерн Равн Андерсен
@ ThorbjørnRavnAndersen в документах говорится: «L / line: генерирование информации о номере строки происходит не особенно быстро. Поэтому его следует избегать, если только скорость выполнения не является проблемой». FWIW: logback.qos.ch/manual/layouts.html (так что, может быть, это быстрее, но все же не очень быстро или что-то в этом роде ...)
rogerdpack
@rogerdpack да. Он обнаруживается путем анализа трассировки стека исключения. Это стало быстрее.
Турбьёрн Равн Андерсен

Ответы:

249

Если вы установите debugатрибут configurationэлемента на true, вы получите всю информацию о состоянии на консоль. Если это ваша проблема, просто установите значение false или удалите его.

Если у вас есть какие-либо проблемы с настройкой уровня WARNили выше, вы также получите всю информацию о состоянии, занесенную в консоль (включая сообщения уровня INFO). Лучшее решение этой проблемы - исправить проблему (в вашем случае замените <layout>элемент на <encoder>элемент).

Если вы по какой-то причине не можете решить проблему, но хотите удалить информацию о состоянии из консоли, вы можете вместо этого настроить альтернативу StatusListener. Используйте NopStatusListenerдля полного удаления информации о статусе:

<configuration>
  <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
  <!-- etc -->
</configuration>
Расмус Фабер
источник
9
Это правильный ответ, за него нужно больше голосовать, спасибо. (logback 1.0.11)
Якуб Кулхан
3
Это сработало. Я не совсем ясно, что INFOсообщения журнала тоже исчезнут, но на самом деле они делают. Я знаю, что ответ говорит об этом, но по какой-то причине мне это было непонятно. Для ясности: исправьте проблему с кодировщиком / компоновкой, и не только исчезнут предупреждающие сообщения, но и исчезнут информационные сообщения, даже если они не связаны с проблемой.
Джейсон
3
Не работал с атрибутом debug, но работал безупречно с прослушивателем статуса.
Амеба Спугноза
Спасибо - нужен статус слушателя.
Иезекииль Виктор
2
Осторожно используя этот подход, он работает, но он скрывает тот факт, что в вашем файле есть ошибка конфигурации. Реальная проблема заключается в журналах WARN, эти проблемы должны быть исправлены в конфигурации, а затем все журналы вкл. ИНФОРМАЦИЯ уходи.
Текнопаул
45

Как описано в документации , если во время синтаксического анализа файла конфигурации возникают предупреждения или ошибки, logback автоматически распечатывает данные о состоянии на консоли.

Следуйте http://logback.qos.ch/codes.html#layoutInsteadOfEncoder т.е. ссылку упоминаемый Logback в предупреждающее сообщение. После того, как вы выполните указанные шаги, то есть, если вы замените элемент <layout> на <encoder>, logback остановит печать сообщений на консоли.

Ceki
источник
4
Вроде правильно, хотя вы указали мне правильное направление. Я изменил синтаксис этого кодера без эффекта, хотя оказалось, что удаление другой строки в logback.xml, которая вызвала предупреждение, помогло. Обманчивая вещь в этом заключается в том, что выходные данные, по-видимому, выводят решения, принятые до того, как он фактически проанализирует ваш файл обратного входа (1> Не удалось найти ресурс [logback.groovy], 2> Найденный ресурс [logback-test.xml]). Исправление в тесте logback может сбить с толку, чтобы скрыть сообщения о состоянии для того, что происходит до того, как оно будет проанализировано. Но спасибо за указатель.
Стив Б.
5
Я думаю, что Стив Б. имел в виду, что нелогично (или, по крайней мере, нетрадиционно), что Logback должен подавлять все сообщения о состоянии, включая (и особенно) те, которые предшествуют загрузке файла конфигурации, если только он не обнаружит ошибку позже в конфигурации. Когда вы не знакомы с этим правилом и впервые видите эти сообщения о состоянии (которые подразумевают предупреждение о конфигурации или ошибку), большинство пользователей ожидают, что после устранения ошибки Logback больше не будет печатать связанные сообщения об ошибках, а продолжит печатать другие сообщения о статусе.
Дерек Махар
6
FWIW, я также считаю это довольно запутанным поведением. Избыток сообщений уровня INFO довольно хорошо скрывает сообщения об ошибках, указывающие, что мне на самом деле нужно исправить. Отсутствие DTD или какой-либо другой спецификации синтаксиса файла конфигурации сделало пробную отладку даже после того, как я заметил сообщение.
Том Андерсон
4
@Ceki: Я наконец понял: 2-й способ вызвать эти сообщения - это иметь debug="true"атрибут в configurationэлементе logback.xml. Пожалуйста, укажите это на благо других людей, которые попадают в эту дыру!
Карл Смотриц
6
Возможно, перед первым оператором INFO должно быть обнаружено предупреждение, выводящее всю информацию о прошлом состоянии. Чтобы прекратить это сообщение, исправьте свои предупреждения / ошибки »
David Roussel
7

Ceki ответ правильный:

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

Как только вы все сделаете правильно, в первых строках вашего журнала больше не будет загрязнения.

По состоянию на март 2015 года в Logback 1.1.2 вам необходимо использовать <encoder>подкомпонент - <layout>теперь он устарел и, если его использовать, будут появляться сообщения об ошибках. Вы не можете контролировать это, это поведение Logback по умолчанию.

Некоторые внутренние классы тоже были переименованы, и даже примеры на их странице руководства устарели!

Вот фрагмент кода на странице справки по коду ошибок , в котором указан правильный способ настройки регистратора. Это решило проблему полностью в моем проекте. http://logback.qos.ch/codes.html#layoutInsteadOfEncoder

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
  <file>testFile.log</file>
  ...
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>%msg%n</pattern>
  </encoder>
</appender>
оборота Cbaldan
источник
4

Я понял, что Стив нашел исправление, но он не упомянул об этом в теме. В случае, если любой другой человек столкнулся с той же проблемой, здесь есть решение.

Замените элементы "<layout>" на "<encoder> .. </ encoder>"

Преступник: <layout class = "ch.qos.logback.classic.PatternLayout">

Интесар Мухаммед
источник
1
Если вы хотите полностью удалить эти сообщения, используйте NopStatusListener, как описано в Rasmus. Подход «кодировщик и макет» не подавляет сообщения, например «logback.groovy not found». Я использую logback-classic 1.1.3 (март 2015 г.)
Кристиан Ботиза
3

Сам боролся с той же проблемой, то есть в самом начале было несколько строк, которые не были связаны с моим кодом. Вот как я это исправил.

<configuration debug="false">

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level 
        %logger{36} - %msg%n</pattern> </encoder> -->
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} %-5level %logger{10} - %msg%n</pattern>
    </encoder>
</appender>

<root level="error">
    <appender-ref ref="STDOUT" />
</root>

<logger name="fun.n.games" level="DEBUG" />

Это выполняется со следующей записью в файле pom.xml.

        <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
Каун Джови
источник
2

Кажется, это исправлено в 0.9.29. Просто сделал несколько тестов. Нет больше информации о Джоране. Я предполагаю, что это фиксационный коммит.

Michael-O
источник
2

У меня была такая же проблема, я добавил эту строку

        <!-- Stop output INFO at start -->
        <statusListener class="ch.qos.logback.core.status.NopStatusListener" />

в logback, и это успешно работает

Зинеб Хачмауи
источник
Это работает, однако также предотвращает вывод сообщений об ОШИБКАХ - никаких выходных данных не возникает, когда возникает серьезная проблема конфигурации обратного входа.
Гонза
0

Я перепробовал все, и у меня ничего не получалось. Моя проблема была из-за нескольких файлов logback.xml в моем classpath. Это распространенный случай в мультимодульных проектах. Когда в classpath есть только один файл logback.xml, двусмысленность отсутствует, и проблема решена.

Filip
источник
какой вывод это вам дало?
rogerdpack
0

Используя logback.groovy:statusListener(NopStatusListener)src/test/resources/logback.groovy ) работает.

(Допустимый вариант использования, например, если вы работаете с ANT в Eclipse, используете ведение журнала обратной связи, классы groovy и модульные тесты, где берутся модульные тесты src/test/resources/logback.groovy, но также увидят src/main/resources/logback.groovy(или подобное), которое вы не можете исключить (если говорят , что путь к классу ANT используется проекты classpath).)

Андреас Дитрих
источник
0

Я предпочитаю использовать прослушиватель статуса для отключения собственных журналов регистрации:

<configuration>
  <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
  ...
</configuration>

Но, как уже упоминалось, NopStatusListener также предотвращает отображение предупреждений и ошибок. Таким образом, вы можете написать свой пользовательский слушатель статуса и вручную изменить уровень журнала:

package com.your.package;

import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.Status;

import java.util.List;

public class PrintOnlyWarningLogbackStatusListener extends OnConsoleStatusListener {

    private static final int LOG_LEVEL = Status.WARN;

    @Override
    public void addStatusEvent(Status status) {
        if (status.getLevel() == LOG_LEVEL) {
            super.addStatusEvent(status);
        }
    }

    @Override
    public void start() {
        final List<Status> statuses = context.getStatusManager().getCopyOfStatusList();
        for (Status status : statuses) {
            if (status.getLevel() == LOG_LEVEL) {
                super.start();
            }
        }
    }

}    

Затем используйте его в файле logback.xml:

<configuration>
  <statusListener class="com.your.package.PrintOnlyWarningLogbackStatusListener" />
  ...
</configuration>
Максим Печенюк
источник