Como impedir que o logback produza seu próprio status no início de cada log?

145

Parece um erro de descuido, mas não consigo encontrar a causa. Log com logback / slf4j (versão mais recente slf4j-api-1.6.1, logback core / classic 0.9.24). A configuração de log mais simples para teste é:

<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>

Toda configuração de log começa com as linhas de status internas do 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]

que é, de acordo com os documentos, o formato que o logback usa por padrão. Em seguida, termina a leitura da configuração (configurada para gerar um formato diferente) e continua com a saída formatada corretamente. Há um parâmetro de configuração <configuration debug="false">que não afeta isso.

Alguém sabe como desligar isso?

Steve B.
fonte
Versões recentes do logback são muito mais rápidas no cálculo de% L.
Thorbjørn Ravn Andersen
@ ThorbjørnRavnAndersen os documentos dizem "L / linha: a geração das informações do número da linha não é particularmente rápida. Portanto, seu uso deve ser evitado, a menos que a velocidade de execução não seja um problema". FWIW: logback.qos.ch/manual/layouts.html (talvez por isso é mais rápido, mas ainda não super rápido ou algo assim ...)
rogerdpack
@rogerdpack sim. É encontrado analisando um rastreamento de pilha de uma exceção. Isso se tornou mais rápido.
Thorbjørn Ravn Andersen

Respostas:

249

Se você definir o debugatributo do configurationelemento como true, receberá todas as informações de status no console. Se este for o seu problema, apenas defina-o como falso ou remova-o.

Se você tiver algum problema de configuração de nível WARNou superior, também receberá todas as informações de status registradas no console (incluindo mensagens de nível INFO). A melhor solução para esse problema é corrigi-lo (no seu caso, substitua o <layout>elemento por um<encoder> elemento).

Se, por algum motivo, você não conseguir resolver o problema, mas quiser remover as informações de status do console, poderá configurar uma alternativa StatusListener. Use NopStatusListenerpara remover completamente as informações de status:

<configuration>
  <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
  <!-- etc -->
</configuration>
Rasmus Faber
fonte
9
Esta é a resposta certa, deve ser votada mais, obrigado. (logback 1.0.11)
Jakub Kulhan
3
Isso funcionou. Eu não estava totalmente claro de que as INFOmensagens de log também desapareceriam, mas na verdade elas desaparecem. Eu sei que a resposta diz isso, mas por algum motivo não estava claro para mim. Para ser tão claro: corrija o problema do codificador / layout e as mensagens de aviso desaparecerão, mas as informações também desaparecerão, mesmo que não estejam relacionadas ao problema.
Jason
3
Não funcionou com o atributo debug, mas funcionou perfeitamente com o ouvinte de status.
Ameba Spugnosa
Obrigado - ouvinte de status necessário.
Ezequiel Victor
2
Cuidado ao usar essa abordagem, ela parece funcionar, mas oculta o fato de você ter um erro de configuração no seu arquivo. O problema real são os logs WARN, esses problemas devem ser corrigidos na configuração e, em seguida, todos os logs inc. INFORMAÇÕES vão embora.
teknopaul
45

Conforme descrito na documentação , se ocorrerem avisos ou erros durante a análise do arquivo de configuração, o logback imprimirá automaticamente os dados de status no console.

Siga http://logback.qos.ch/codes.html#layoutInsteadOfEncoder, ou seja, o link mencionado pelo logback em sua mensagem de aviso. Depois de seguir as etapas mencionadas, ou seja, se você substituir o elemento <layout> por <encoder>, o logback interromperá a impressão de mensagens no console.

Ceki
fonte
4
Mais ou menos certo, embora você me tenha apontado na direção certa. Eu mudei para essa sintaxe do codificador sem efeito, embora a remoção de outra linha no logback.xml que estava causando um aviso funcionasse. A coisa enganosa é que a saída parece estar gerando decisões tomadas antes de realmente analisar seu arquivo de logback, (1> NÃO foi possível encontrar o recurso [logback.groovy], 2> Recurso encontrado [logback-test.xml]). É bastante confuso para uma correção no teste de logback ocultar as mensagens de status para o que acontece antes de ser analisado. Mas obrigado pelo ponteiro.
Steve B.
5
Acho que o que Steve B. quis dizer é que é contra-intuitivo (ou pelo menos não convencional) que o Logback suprima todas as mensagens de status, incluindo (e particularmente) aquelas que precedem o carregamento do arquivo de configuração, a menos que encontre um erro mais tarde na configuração. Quando você não está familiarizado com esta regra e vê pela primeira vez essas mensagens de status (o que implica um aviso ou erro de configuração), a maioria dos usuários espera que, uma vez resolvido o erro, o Logback não imprima mais as mensagens de erro relacionadas, mas continue imprimindo a outra. mensagens de status.
Derek Mahar
6
FWIW, também acho esse comportamento bastante confuso. O envio de mensagens no nível INFO faz um bom trabalho de ocultar as mensagens de erro dizendo o que eu realmente preciso corrigir. A falta de um DTD, ou qualquer outra especificação da sintaxe do arquivo de configuração, fez com que fosse uma tentativa de depuração, mesmo depois que vi a mensagem.
Tom Anderson
4
@ Cecki: Eu finalmente descobri: A segunda maneira de acionar essas mensagens é ter o debug="true"atributo no configurationelemento logback.xml. Mencione isso para o benefício de outras pessoas que caem nesse buraco!
Carl Smotricz
6
Talvez antes da primeira instrução INFO deva haver um 'Aviso detectado, exibindo todas as informações de status anteriores. Para parar esta mensagem, corrigir seus avisos / erros
David Roussel
7

Ceki resposta está correta:

(...) se ocorrerem avisos ou erros durante a análise do arquivo de configuração, o logback imprimirá automaticamente os dados de status no console.

Depois de acertar, não haverá mais poluição nas primeiras linhas do seu registro.

Desde março de 2015, no Logback 1.1.2 , você precisa usar o <encoder>subcomponente - <layout>agora está obsoleto e, se usá-lo, aparecerão mensagens de erro. Você não pode controlar isso, é o comportamento padrão do Logback .

Algumas classes internas também foram renomeadas e até os exemplos em sua página de manual estão desatualizados!

Aqui está o trecho de código da página de Ajuda do Código de erros , que tem a maneira correta de configurar o criador de logs. Isso corrigiu o problema completamente no meu projeto. 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
fonte
4

Percebi que Steve encontrou a correção, mas ele não a mencionou no tópico. Caso outra pessoa acerte o mesmo problema, aqui está a correção.

Substitua os elementos "<layout>" por "<encoder> .. </encoder>"

O culpado é: <layout class = "ch.qos.logback.classic.PatternLayout">

Intesar Mohammed
fonte
1
Se você deseja remover completamente essas mensagens, use o NopStatusListener como Rasmus descrito. A abordagem codificador vs layout não suprime mensagens como 'logback.groovy não encontrado' por exemplo. Estou usando o logback-classic 1.1.3 (março de 2015)
Cristian Botiza
3

Lutei com o mesmo problema, ou seja, havia um monte de linhas registradas logo no início que não estavam relacionadas ao meu código. Aqui está como eu consertei.

<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" />

Isso está sendo executado com a seguinte entrada no pom.xml

        <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
Kaun Jovi
fonte
2

Isso parece ser corrigido em 0.9.29. Acabei de fazer vários testes. Não há mais informações do Joran. Eu acho que esse é o conserto de conserto.

Michael-O
fonte
2

Eu tive o mesmo problema eu adicionei esta linha

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

no logback e funcionou com sucesso

Zineb Hachmaoui
fonte
Isso funciona, no entanto, evita a saída de mensagens de erro também - nenhuma saída é produzida quando ocorre um problema grave na configuração de logback.
Honza 11/03
0

Eu tentei de tudo e nada funcionou para mim. Meu problema foi devido a vários arquivos logback.xml no meu caminho de classe. Este é o caso comum em projetos multi-modulares. Quando existe apenas um arquivo logback.xml no caminho de classe, não há ambiguidade e o problema é resolvido.

Filip
fonte
que saída isso lhe deu?
Rogerdpack
0

Usando o logback.groovy:statusListener(NopStatusListener) (no src/test/resources/logback.groovy) funciona.

(Um caso de uso válido é, por exemplo, se estiver trabalhando com ANT no Eclipse, usando log de logback, classes groovy e testes de unidade em que os testes de unidade fazem o teste src/test/resources/logback.groovy, mas também verá o src/main/resources/logback.groovy(ou similar) que você não pode excluir (se o caminho de classe do ANT usar o caminho de classe dos projetos).)

Andreas Dietrich
fonte
0

Prefiro usar o ouvinte de status para desativar os próprios logs de logback:

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

Mas, como foi mencionado, o NopStatusListener também impede a exibição de avisos e erros. Assim, você pode escrever seu ouvinte de status personalizado e alterar o nível do log manualmente:

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();
            }
        }
    }

}    

Em seguida, use-o no seu arquivo logback.xml:

<configuration>
  <statusListener class="com.your.package.PrintOnlyWarningLogbackStatusListener" />
  ...
</configuration>
Maksym Pecheniuk
fonte