¿Cómo evitar que el inicio de sesión genere su propio estado al comienzo de cada registro?

145

Esto parece un error de descuido, pero parece que no puedo encontrar la causa. Registro con logback / slf4j (versión más reciente slf4j-api-1.6.1, logback core / classic 0.9.24). La configuración de registro más simple para la prueba es:

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

Cada configuración de registro comienza con las líneas de estado internas 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]

que es, de acuerdo con los documentos, el formato de inicio de sesión utiliza por defecto. Luego termina de leer la configuración (que está configurada para generar un formato diferente) y continúa con la salida con el formato correcto. Hay un parámetro de configuración <configuration debug="false">que no afecta esto.

¿Alguien sabe cómo apagar esto?

Steve B.
fuente
Las versiones recientes de logback son mucho más rápidas al calcular% L.
Thorbjørn Ravn Andersen
@ ThorbjørnRavnAndersen los documentos dicen "L / line: Generar la información del número de línea no es particularmente rápido. Por lo tanto, su uso debe evitarse a menos que la velocidad de ejecución no sea un problema". FWIW: logback.qos.ch/manual/layouts.html (por lo que tal vez sea más rápido pero aún no es súper rápido o algo así ...)
rogerdpack
@rogerdpack sí. Se encuentra analizando un seguimiento de pila de una excepción. Eso se ha vuelto más rápido.
Thorbjørn Ravn Andersen

Respuestas:

249

Si establece el debugatributo del configurationelemento en true, obtendrá toda la información de estado en la consola. Si este es su problema, simplemente configúrelo como falso o elimínelo.

Si tiene algún problema de configuración de nivel WARNo superior, también obtendrá toda la información de estado registrada en la consola (incluidos los mensajes de nivel INFO). La mejor solución a este problema es solucionar el problema (en su caso, reemplace el <layout>elemento con un <encoder>elemento).

Si por alguna razón no puede solucionar el problema, pero desea eliminar la información de estado de la consola, puede configurar una alternativa StatusListener. Use NopStatusListenerpara eliminar completamente la información de estado:

<configuration>
  <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
  <!-- etc -->
</configuration>
Rasmus Faber
fuente
9
Esta es la respuesta correcta, se debe votar más, gracias. (logback 1.0.11)
Jakub Kulhan
3
Esto funcionó. No estaba completamente claro que los INFOmensajes de registro también desaparecerían, pero de hecho lo hacen. Sé que la respuesta dice esto, pero por alguna razón no estaba claro para mí. Para ser tan claro: solucione el problema del codificador / diseño y no solo desaparecerán los mensajes de advertencia, sino que también desaparecerán los mensajes de información, aunque no estén relacionados con el problema.
Jason
3
No funcionó con el atributo de depuración, pero funcionó perfectamente con el escucha de estado.
Ameba Spugnosa
Gracias - necesitaba estado de escucha.
Ezequiel Víctor
2
Con cuidado al usar este enfoque, parece funcionar pero oculta el hecho de que tiene un error de configuración en su archivo. El verdadero problema son los registros de WARN, estos problemas deben corregirse en la configuración, luego todos los registros inc. INFORMACIÓN vete.
teknopaul
45

Como se describe en los documentos , si se producen advertencias o errores durante el análisis del archivo de configuración, el inicio de sesión imprimirá automáticamente los datos de estado en la consola.

Siga http://logback.qos.ch/codes.html#layoutInsteadOfEncoder, es decir, el enlace mencionado por logback en su mensaje de advertencia. Una vez que siga los pasos mencionados allí, es decir, si reemplaza el elemento <layout> con <encoder>, el inicio de sesión dejará de imprimir mensajes en la consola.

Ceki
fuente
44
Más o menos bien, aunque me apuntaste en la dirección correcta. Había cambiado a esa sintaxis del codificador sin efecto, aunque resulta que eliminar otra línea en el logback.xml que estaba causando una advertencia fue el truco. Lo engañoso al respecto es que la salida parece estar emitiendo decisiones tomadas antes de que realmente analice su archivo logback, (1> NO se pudo encontrar el recurso [logback.groovy], 2> Recurso encontrado [logback-test.xml]). Es bastante confuso para una solución en la prueba de logback ocultar mensajes de estado de lo que sucede antes de que se analice. Pero gracias por el puntero.
Steve B.
55
Creo que lo que Steve B. quiso decir es que es contrario a la intuición (o al menos no convencional) que Logback debería suprimir todos los mensajes de estado, incluidos (y particularmente) aquellos que preceden a la carga del archivo de configuración, a menos que encuentre un error más adelante en la configuración. Cuando no esté familiarizado con esta regla y vea por primera vez estos mensajes de estado (que implican una advertencia o error de configuración), la mayoría de los usuarios esperarían que una vez que se resuelva el error, Logback ya no imprimirá los mensajes de error relacionados, pero continuará imprimiendo el otro mensajes de estado
Derek Mahar
66
FWIW, también encuentro este comportamiento bastante confuso. La cantidad de mensajes de nivel INFO hace un muy buen trabajo al ocultar los mensajes de ERROR diciéndome lo que realmente necesito corregir. La falta de un DTD, o cualquier otra especificación de la sintaxis del archivo de configuración, hizo que fuera una prueba de depuración incluso una vez que vi el mensaje.
Tom Anderson
44
@Ceki: Finalmente lo descubrí: la segunda forma de activar estos mensajes es tener el debug="true"atributo en el configurationelemento de logback.xml. ¡Mencione esto en beneficio de otras personas que caen en este agujero!
Carl Smotricz
66
Quizás antes de la primera instrucción INFO debería haber una 'Advertencia detectada, que muestre toda la información de estado pasada. Para detener este mensaje, corrija sus advertencias / errores '
David Roussel
7

La respuesta de Ceki es correcta:

(...) si se producen advertencias o errores durante el análisis del archivo de configuración, el inicio de sesión imprimirá automáticamente los datos de estado en la consola.

Una vez que lo haga bien, ya no habrá contaminación en las primeras líneas de su registro.

A partir de marzo de 2015, en Logback 1.1.2 , debe usar <encoder>un subcomponente: <layout>ahora está en desuso y, si lo usa, aparecerán mensajes de error. No puede controlar esto, es el comportamiento predeterminado de Logback .

Algunas clases internas también han sido renombradas, ¡e incluso los ejemplos en su página de manual están desactualizados!

Aquí está el fragmento de código de su página de Ayuda de Código de Errores , que tiene la forma correcta de configurar el registrador. Esto solucionó el problema por completo en mi proyecto. 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>
revs Cbaldan
fuente
4

Me di cuenta de que Steve encontró la solución, pero no la mencionó en el hilo. En caso de que otra persona tenga el mismo problema, aquí está la solución.

Reemplace los elementos "<layout>" con "<encoder> .. </encoder>"

El culpable es: <layout class = "ch.qos.logback.classic.PatternLayout">

Intesar Mohammed
fuente
1
Si desea eliminar por completo esos mensajes, use NopStatusListener como lo describe Rasmus. El enfoque de codificador vs diseño no suprime mensajes como 'logback.groovy not found' por ejemplo. Estoy usando logback-classic 1.1.3 (marzo de 2015)
Cristian Botiza
3

Luché con el mismo problema, es decir, había un montón de líneas registradas al principio que no estaban relacionadas con mi código. Así es como lo arreglé.

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

Esto se ejecuta con la siguiente entrada en pom.xml

        <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
kaun jovi
fuente
2

Esto parece estar solucionado en 0.9.29. Acabo de hacer varias pruebas. No Joran INFO más. Supongo que este es el commit de fijación.

Michael-O
fuente
2

Tuve el mismo problema agregué esta línea

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

en el inicio de sesión y funcionó con éxito

Zineb Hachmaoui
fuente
Esto funciona, sin embargo, también evita la salida de mensajes de ERROR: no se produce ninguna salida cuando se produce un problema grave de configuración de inicio de sesión.
Honza
0

He intentado todo y nada funcionó para mí. Mi problema se debió a múltiples archivos logback.xml en mi classpath. Este es el caso común en proyectos multi modulares. Cuando solo hay un archivo logback.xml en classpath, no hay ambigüedad y el problema está resuelto.

Filip
fuente
¿Qué salida te dio?
rogerdpack
0

Usando el logback.groovy:statusListener(NopStatusListener) (en el src/test/resources/logback.groovy) funciona.

(Un caso de uso válido es, por ejemplo, si se trabaja con ANT en Eclipse, utilizando el registro de inicio de sesión, clases maravillosas y pruebas unitarias donde las pruebas unitarias toman el src/test/resources/logback.groovy, pero también verá el src/main/resources/logback.groovy(o similar) que no puede excluir (si se dice que el classpath de ANT usa los proyectos classpath).)

Andreas Dietrich
fuente
0

Prefiero usar el detector de estado para desactivar los registros de inicio de sesión propios:

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

Pero como se mencionó, NopStatusListener también evita mostrar advertencias y errores. Para que pueda escribir su escucha de estado personalizado y cambiar el nivel de registro de forma manual:

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

}    

Luego utilícelo en su archivo logback.xml:

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