Come impedire che il logback generi il proprio stato all'inizio di ogni log?


145

Sembra un errore di disattenzione, ma non riesco a trovare la causa. Registrazione con logback / slf4j (versione più recente slf4j-api-1.6.1, logback core / classic 0.9.24). La configurazione del registro più semplice per i test è:

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

Ogni impostazione del registro inizia con le righe di stato interne del registro:

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]

che è, secondo i documenti, il formato di logback utilizza per impostazione predefinita. Termina quindi la lettura della configurazione (impostata per l'output di un formato diverso) e continua con l'output formattato correttamente. C'è un parametro di configurazione <configuration debug="false">che non influenza questo.

Qualcuno sa come spegnerlo?


Le versioni recenti del logback sono molto più veloci nel calcolare% L.
Thorbjørn Ravn Andersen,

@ ThorbjørnRavnAndersen i documenti dicono "L / line: la generazione delle informazioni sul numero di riga non è particolarmente veloce. Pertanto, il suo uso dovrebbe essere evitato a meno che la velocità di esecuzione non sia un problema." FWIW: logback.qos.ch/manual/layouts.html (quindi forse è più veloce ma ancora non super veloce o qualcosa del genere ...)
rogerdpack

@rogerdpack sì. Si trova analizzando una traccia dello stack di un'eccezione. È diventato più veloce.
Thorbjørn Ravn Andersen,

Risposte:


249

Se si imposta l' debugattributo configurationdell'elemento su true, si otterranno tutte le informazioni sullo stato sulla console. Se questo è il tuo problema, basta impostarlo su false o rimuoverlo.

In caso di problemi di configurazione di livello WARNo superiore, tutte le informazioni sullo stato verranno registrate sulla console (inclusi i messaggi di livello INFO). La migliore soluzione a questo problema è quella di risolvere il problema (nel tuo caso sostituisci l' <layout>elemento con un <encoder>elemento).

Se per qualche motivo non è possibile risolvere il problema, ma si desidera rimuovere le informazioni sullo stato dalla console, è possibile invece configurare un'alternativa StatusListener. Utilizzare NopStatusListenerper rimuovere completamente le informazioni sullo stato:

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

9
Questa è la risposta giusta, dovrebbe essere votata di più, grazie. (logback 1.0.11)
Jakub Kulhan,

3
Questo ha funzionato. Non ero del tutto chiaro che anche i INFOmessaggi di registro sarebbero scomparsi, ma in realtà lo fanno. So che la risposta dice questo, ma per qualche ragione non mi è stato chiaro. Per essere così chiari: risolvi il problema dell'encoder / del layout e non solo i messaggi di avviso scompaiono, ma anche i messaggi informativi scompaiono, anche se non sono correlati al problema.
Jason,

3
Non ha funzionato con l'attributo debug, ma ha funzionato perfettamente con il listener di stato.
Ameba Spugnosa,

Grazie - ascoltatore di stato necessario.
Ezechiele Vittorio,

2
Attento usando questo approccio, sembra funzionare ma nasconde il fatto che hai un errore di configurazione nel tuo file. Il vero problema sono i log di WARN, questi problemi dovrebbero essere risolti in config, quindi tutti i log inc. INFO vai via.
Teknopaul,

45

Come descritto nei documenti , se si verificano avvisi o errori durante l'analisi del file di configurazione, il logback stamperà automaticamente i dati di stato sulla console.

Segui http://logback.qos.ch/codes.html#layoutInsteadOfEncoder, ovvero il link indicato dal logback nel suo messaggio di avviso. Una volta seguiti i passaggi qui menzionati, ovvero se si sostituisce l'elemento <layout> con <encoder>, il logback interromperà la stampa dei messaggi sulla console.


4
Un po 'giusto, anche se mi hai indicato nella giusta direzione. Avevo cambiato la sintassi di quel codificatore senza effetto, anche se si è scoperto che rimuovere un'altra riga nel logback.xml che stava causando un avviso ha fatto il trucco. La cosa ingannevole al riguardo è che l'output sembra emettere decisioni prese prima che analizzi effettivamente il file di logback, (1> NON è stato possibile trovare la risorsa [logback.groovy], 2> Found found [logback-test.xml]). È abbastanza confuso per una correzione nel test di logback nascondere i messaggi di stato per ciò che accade prima che venga analizzato. Ma grazie per il puntatore.
Steve B.

5
Penso che Steve B. intendesse dire che è controintuitivo (o almeno non convenzionale) che Logback debba sopprimere tutti i messaggi di stato, inclusi (e in particolare) quelli che precedono il caricamento del file di configurazione, a meno che non si verifichi un errore in seguito nella configurazione. Quando non si ha familiarità con questa regola e si vedono per la prima volta questi messaggi di stato (che implicano un avviso o un errore di configurazione), la maggior parte degli utenti si aspetterebbe che una volta risolto l'errore, Logback non stampasse più i relativi messaggi di errore, ma continuasse a stampare l'altro messaggi di stato.
Derek Mahar,

6
FWIW, trovo anche questo comportamento abbastanza confuso. La quantità di messaggi a livello di INFO fa un ottimo lavoro nel nascondere i messaggi di ERRORE che mi dicono cosa devo effettivamente riparare. La mancanza di un DTD, o qualsiasi altra specifica della sintassi del file di configurazione, ha reso piuttosto difficile il debug anche dopo aver individuato il messaggio.
Tom Anderson,

4
@Ceki: Alla fine l'ho capito: il secondo modo per attivare questi messaggi è avere l' debug="true"attributo configurationnell'elemento di logback.xml. Per favore, menzionalo a beneficio di altre persone che cadono in questo buco!
Carl Smotricz,

6
Forse prima della prima istruzione INFO dovrebbe esserci un 'Avviso rilevato, che fornisce tutte le informazioni sullo stato passato. Per interrompere questo messaggio, correggi i tuoi avvertimenti / errori "
David Roussel,

7

La risposta di Ceki è corretta:

(...) se si verificano avvisi o errori durante l'analisi del file di configurazione, il logback stamperà automaticamente i dati di stato sulla console.

Una volta che hai capito bene, non ci sarà più alcun inquinamento nelle prime righe del tuo registro.

A partire da marzo 2015, in Logback 1.1.2 , è necessario utilizzare il <encoder>sottocomponente: <layout>ora è obsoleto e, se utilizzato, verranno visualizzati messaggi di errore. Non puoi controllarlo, è il comportamento predefinito di Logback .

Anche alcune classi interne sono state rinominate e persino gli esempi nella loro pagina di manuale sono obsoleti!

Ecco lo snippet di codice dalla loro pagina di aiuto del codice errori , che ha il modo corretto di configurare il logger. Ciò ha risolto completamente il problema nel mio progetto. 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>

4

Mi sono reso conto che Steve ha trovato la soluzione ma non l'ha menzionata nel thread. Nel caso in cui un'altra persona abbia riscontrato lo stesso problema, ecco la soluzione.

Sostituisci gli elementi "<layout>" con "<encoder> .. </encoder>"

Il colpevole è: <layout class = "ch.qos.logback.classic.PatternLayout">


1
Se si desidera rimuovere completamente quei messaggi, utilizzare NopStatusListener come descritto da Rasmus. L'approccio encoder vs layout non sopprime ad esempio i messaggi come 'logback.groovy not found'. Sto usando logback-classic 1.1.3 (marzo 2015)
Cristian Botiza il

3

Ho lottato con lo stesso problema, cioè all'inizio c'erano un sacco di linee registrate che non erano correlate al mio codice. Ecco come l'ho risolto.

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

Questo è in esecuzione con la seguente voce in pom.xml

        <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>

2

Questo sembra essere stato risolto in 0.9.29. Ho appena fatto diversi test. Nessuna Joran INFO più. Immagino che questo sia il commit della correzione.


2

Ho avuto lo stesso problema, ho aggiunto questa riga

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

nel logback e ha funzionato con successo


Funziona, tuttavia impedisce anche l'output dei messaggi ERRORE - non viene prodotto alcun output quando si verifica un grave problema di configurazione del logback.
Honza,

0

Ho provato di tutto e niente ha funzionato per me. Il mio problema era dovuto a più file logback.xml nel mio percorso di classe. Questo è il caso comune nei progetti multi modulari. Quando esiste un solo file logback.xml nel percorso di classe, non vi è alcuna ambiguità e il problema è risolto.


quale uscita ti ha dato?
rogerdpack,

0

Utilizzando il logback.groovy:statusListener(NopStatusListener) (nel src/test/resources/logback.groovy) funziona.

(Un caso d'uso valido è ad esempio se si lavora con ANT in Eclipse, utilizzando la registrazione di logback, le classi groovy e i test unitari in cui i test unitari prendono il src/test/resources/logback.groovy, ma vedrà anche src/main/resources/logback.groovy(o simili) che non è possibile escludere (se si dice che il percorso di classe ANT il percorso di classe dei progetti).)


0

Preferisco usare il listener di stato per disattivare i log di logback:

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

Ma come è stato menzionato, NopStatusListener impedisce anche la visualizzazione di avvisi ed errori. Quindi puoi scrivere il tuo listener di stato personalizzato e modificare manualmente il livello di registro:

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

}    

Quindi utilizzalo nel tuo file logback.xml:

<configuration>
  <statusListener class="com.your.package.PrintOnlyWarningLogbackStatusListener" />
  ...
</configuration>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.