java - ejemplo - log4j2 web
¿Cómo iniciar sesión dentro de los ganchos de cierre con Log4j2? (2)
Log4j2 también usa los ganchos de cierre para finalizar sus servicios. Pero, por supuesto, quiero iniciar sesión durante todo el ciclo de vida de mi aplicación, incluido el apagado. Con Log4j esto no fue un problema. Ahora parece ser imposible. El registro se cierra, mientras mi aplicación todavía está trabajando en ello. ¿Alguien tiene alguna esperanza para mí?
Saludos cordiales Martin
Desde 2.0-beta9 esto ahora es configurable en xml
<configuration ... shutdownHook="disable">
Teniendo en cuenta que ahora está desactivado, creo que necesito cerrar manualmente el sistema de registro al final de mi cierre. Sin embargo, no pude encontrar un medio a través de la interfaz externa, solo en la API interna.
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.LoggerContext;
...
public static void main(String[] args) {
final AnnotationConfigApplicationContext springContext = new AnnotationConfigApplicationContext(AppConfig.class)
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
//shutdown application
LOG.info("Shutting down spring context");
springContext.close();
//shutdown log4j2
if( LogManager.getContext() instanceof LoggerContext ) {
logger.info("Shutting down log4j2");
Configurator.shutdown((LoggerContext)LogManager.getContext());
} else
logger.warn("Unable to shutdown log4j2");
}
});
//more application initialization
}
Básicamente, simplemente respondí la misma pregunta y difícil. Compartiré mi respuesta aquí. Te animo a que leas la respuesta completa disponible aquí . Intentaré proporcionar un resumen aquí y adaptaré mi respuesta al contexto actual.
En la primera versión, Log4j proporcionaba una API para llamar manualmente al procedimiento de apagado. Por razones que no conocemos, se eliminó de la segunda versión . Ahora, la forma correcta de hacerlo (de acuerdo con la documentación inexistente) es proporcionar su propia implementación de la interfaz ShutdownCallbackRegistry
, que es responsable del procedimiento de apagado.
Solución propuesta
Lo que hice para solucionar este problema es que implementé mi propia versión de la interfaz ShutdownCallbackRegistry
. Principalmente hace las mismas cosas que la implementación predeterminada, pero en lugar de registrarse como un gancho de apagado para la JVM, espera hasta que se invoque manualmente.
Puede encontrar la solución completa y las instrucciones en GitHub / DjDCH / Log4j-StaticShutdown y utilizarlo en sus propios proyectos. Básicamente, al final, solo tienes que hacer algo como esto en tu aplicación:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
try {
// Do your usual shutdown stuff here that need logging
} finally {
// Shutdown Log4j 2 manually
StaticShutdownCallbackRegistry.invoke();
}
}
}));
No puedo decir sin ninguna duda que esta es la solución perfecta y que mi implementación es perfecta, pero traté de hacerlo de la manera correcta. Estaré encantado de escuchar sus comentarios, ya sea que encuentre esta solución apropiada o no.