I am trying to write a message to the logger that a (Vaadin) servlet has stopped, this using SLF4J and Log4j2.
For this I am using a ServletContextListener
which logs a message when the application has started. However I have been unable to get any output when logging inside the contextDestroyed
method... Here is my implementation:
@WebListener
public class VaadinLogger implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger(VaadinLogger.class);
@Override
public void contextInitialized(ServletContextEvent contextEvent) {
// Remove appenders from JUL loggers
SLF4JBridgeHandler.removeHandlersForRootLogger();
// Install bridge
SLF4JBridgeHandler.install();
// Get servlet context
ServletContext context = contextEvent.getServletContext();
// Retrieve name
String name = context.getServletContextName();
// Log servlet init information
logger.info("Start \"{}\"", name);
}
@Override
public void contextDestroyed(ServletContextEvent contextEvent) {
// Get servlet context
ServletContext context = contextEvent.getServletContext();
// Retrieve name
String name = context.getServletContextName();
// Log servlet destroy information
logger.info("End \"{}\"{}", name, System.lineSeparator()));
// Uninstall bridge
SLF4JBridgeHandler.uninstall();
}
}
At this point, I'm guessing this is probably because at the point contextDestroyed
is called, logging is no longer possible because they have already been destroyed by the garbage collector.
So now my question is, is it possible to either log that the servlet has stopped before the context is destroyed, or make the contextlistener execute before log4j2 loggers are destroyed?
Thanks in advance!
ServletContextEvent class provides alerts/notifications for changes to a web application's servlet context. ServletContextListener is a class that receives alerts/notifications about changes to the servlet context and acts on them.
HttpSessionListener is a simple implementation to log the event when the session is created or destroyed. ServletRequestListener is to log the servletRequest IP address when the request is initialized and destroyed.
Methods of ServletContextListener interfacepublic void contextInitialized(ServletContextEvent e): is invoked when application is deployed on the server. public void contextDestroyed(ServletContextEvent e): is invoked when application is undeployed from the server.
void contextInitialized(ServletContextEvent sce) Receives notification that the web application initialization process is starting. All ServletContextListeners are notified of context initialization before any filters or servlets in the web application are initialized.
Since log4j 2.14.1, you can disable the auto-shutdown and add a listener to stop the logger.
<context-param>
<!-- auto-shutdown stops log4j when the web fragment unloads, but that
is too early because it is before the listeners shut down. To
compensate, use a Log4jShutdownOnContextDestroyedListener and
register it before any other listeners which means it will shut
down *after* all other listeners. -->
<param-name>isLog4jAutoShutdownDisabled</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<!-- ensure logging stops after other listeners by registering
the shutdown listener first -->
<listener-class>
org.apache.logging.log4j.web.Log4jShutdownOnContextDestroyedListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With