es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo forzar el uso de log4j pero no slf4j

En mis dependencias de proyecto, tengo tanto slf4j como log4j. Por alguna razón técnica, esto no se puede cambiar.

> gradlew dependencies
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
> Task :dependencies
.
.
|    |         |    +--- org.springframework.boot:spring-boot-starter-logging:2.5.7
|    |         |    |    +--- ch.qos.logback:logback-classic:1.2.7
|    |         |    |    |    +--- ch.qos.logback:logback-core:1.2.7
|    |         |    |    |    \--- org.slf4j:slf4j-api:1.7.32
|    |         |    |    +--- org.apache.logging.log4j:log4j-to-slf4j:2.14.1
|    |         |    |    |    +--- org.slf4j:slf4j-api:1.7.25 -> 1.7.32
|    |         |    |    |    \--- org.apache.logging.log4j:log4j-api:2.14.1 -> 2.17.0
|    |         |    |    \--- org.slf4j:jul-to-slf4j:1.7.32
|    |         |    |         \--- org.slf4j:slf4j-api:1.7.32
.
.
+--- org.apache.logging.log4j:log4j-core:2.17.0
|    \--- org.apache.logging.log4j:log4j-api:2.17.0
+--- org.apache.logging.log4j:log4j-api:2.17.0
BUILD SUCCESSFUL in 16s
1 actionable task: 1 executed

Quiero establecer el nivel de registro en el código, y según tengo entendido, esto solo se puede hacer con log4j. Por lo tanto, simplemente busco una forma de hacer que esta línea de código (donde LogManager es parte de log4j) devuelva la implementación de log4j y no la implementación de slf4j:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
.
.
private final Logger logger = LogManager.getLogger(getClass());

Lamentablemente, la clase del logger que devuelve es org.apache.logging.slf4j.SLF4JLogger:

System.out.println("logger class is: [" + logger.getClass() + "]");

salida:

logger class is: [class org.apache.logging.slf4j.SLF4JLogger]

Aunque parece fácil, no he logrado hacerlo ni encontrar un ejemplo en línea. ¿Qué se puede hacer?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Dado que tu proyecto depende tanto de slf4j como de log4j, esto significa que la API de slf4j ya está siendo utilizada por otras bibliotecas y no puedes reemplazarla con la API de log4j. Sin embargo, puedes configurar slf4j para que utilice log4j como su sistema de registro subyacente.

    Aquí están los pasos para configurar slf4j para que utilice log4j:

    1. Elimina cualquier dependencia directa de logback (u otro marco de registro) del archivo build.gradle o pom.xml de tu proyecto.
    2. Agrega una dependencia en log4j-slf4j-impl, que proporciona el enlace de log4j para slf4j. Esta dependencia puede coexistir con otros marcos de registro, como logback.
    3. Agrega un archivo de configuración log4j2.xml al classpath de tu proyecto.

    Aquí tienes un ejemplo de configuración log4j2.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <appenders>
        <console name="Console" target="SYSTEM_OUT">
          <patternlayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"></patternlayout>
        </console>
      </appenders>
      <loggers>
        <root level="debug">
          <appenderref ref="Console"></appenderref>
        </root>
      </loggers>
    </configuration>
    

    Esta configuración registra mensajes de nivel debug y superior en la consola, utilizando un patrón que incluye la hora, el nombre del hilo, el nivel de registro, el nombre del registrador y el mensaje.

    Una vez que hayas agregado la dependencia de log4j-slf4j-impl y el archivo de configuración log4j2.xml, puedes utilizar la API de slf4j como de costumbre. Las declaraciones de registro pasarán por slf4j, que las delegará a log4j a través del enlace.

    Ten en cuenta que si tienes declaraciones de registro existentes que usan slf4j, seguirán funcionando con esta configuración, pero estarán utilizando log4j internamente. No necesitas cambiar ninguna de tus declaraciones de registro, pero puedes utilizar características específicas de log4j, como establecer el nivel de registro, utilizando el objeto Logger devuelto por LogManager.getLogger().

Comments are closed.