The Apache Log4j support for web servlet containers
—
Core servlet lifecycle components that manage Log4j startup, shutdown, and per-request context binding. These components ensure proper Log4j integration with servlet containers across different environments and configuration patterns.
Context listener responsible for initializing and deinitializing Log4j in servlet environments, particularly for pre-Servlet 3.0 containers or when automatic initialization is disabled.
/**
* ServletContextListener for managing Log4j lifecycle in web applications.
* Handles startup initialization and shutdown cleanup of Log4j logging context.
*/
public class Log4jServletContextListener implements ServletContextListener {
/** ServletContext attribute for tracking start count */
static final String START_COUNT_ATTR =
"org.apache.logging.log4j.web.Log4jServletContextListener.START_COUNT";
/** Default shutdown timeout in seconds */
private static final int DEFAULT_STOP_TIMEOUT = 30;
/** Default timeout time unit */
private static final TimeUnit DEFAULT_STOP_TIMEOUT_TIMEUNIT = TimeUnit.SECONDS;
/** Context parameter key for shutdown timeout */
private static final String KEY_STOP_TIMEOUT = "log4j.stop.timeout";
/** Context parameter key for timeout time unit */
private static final String KEY_STOP_TIMEOUT_TIMEUNIT = "log4j.stop.timeout.timeunit";
/**
* Initializes Log4j when the servlet context starts.
* Sets up LoggerContext and prepares logging infrastructure.
* Implements reference counting to handle multiple registrations.
*
* @param event ServletContextEvent containing the ServletContext
* @throws IllegalStateException if auto-shutdown is disabled or initialization fails
*/
public void contextInitialized(ServletContextEvent event);
/**
* Shuts down Log4j when the servlet context is destroyed.
* Cleanly stops the LoggerContext with configurable timeout.
* Uses reference counting to ensure proper shutdown timing.
*
* @param event ServletContextEvent containing the ServletContext
* @throws IllegalStateException if shutdown fails
*/
public void contextDestroyed(ServletContextEvent event);
}Configuration in web.xml:
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>Usage Notes:
isLog4jAutoShutdownDisabled is falseLog4jShutdownOnContextDestroyedListener insteadlog4j.stop.timeout context parameterPer-request filter that manages LoggerContext binding for individual HTTP requests. Ensures proper logging context isolation and cleanup for concurrent request processing.
/**
* Filter that manages LoggerContext on a per-request basis.
* Sets context before request processing and clears after completion.
* Implements once-per-request filtering to handle multiple dispatch types.
*/
public class Log4jServletFilter implements Filter {
/**
* Initializes the filter with servlet context reference.
* Clears logger context to indicate application startup completion.
*
* @param filterConfig FilterConfig containing initialization parameters
* @throws ServletException if initialization fails
*/
public void init(FilterConfig filterConfig) throws ServletException;
/**
* Processes each request with proper LoggerContext binding.
* Sets context before chain execution, clears after completion.
* Uses request attribute to prevent duplicate processing.
*
* @param request ServletRequest being processed
* @param response ServletResponse for the request
* @param chain FilterChain for continuing request processing
* @throws IOException if I/O error occurs during filtering
* @throws ServletException if servlet processing error occurs
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
/**
* Cleans up filter resources and sets LoggerContext for shutdown.
* Called when filter is taken out of service.
*
* @throws IllegalStateException if filter destroyed before initialization
*/
public void destroy();
}Configuration in web.xml:
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>Filter Constants:
public class Log4jServletFilter implements Filter {
/** Request attribute name to prevent duplicate filtering */
static final String ALREADY_FILTERED_ATTRIBUTE =
Log4jServletFilter.class.getName() + ".FILTERED";
}Servlet 3.0+ container initializer that automatically configures Log4j without requiring manual web.xml configuration. Provides zero-configuration setup for modern servlet containers.
/**
* ServletContainerInitializer for automatic Log4j setup in Servlet 3.0+ environments.
* Automatically registers listeners and filters without web.xml configuration.
*/
public class Log4jServletContainerInitializer implements ServletContainerInitializer {
/**
* Automatically configures Log4j components during container startup.
* Registers Log4jServletFilter and optionally Log4jServletContextListener.
* Only activates in Servlet 3.0+ when auto-initialization is enabled.
*
* @param classes Set of classes found during annotation scanning (unused)
* @param servletContext ServletContext for registration and configuration
* @throws ServletException if automatic configuration fails
*/
public void onStartup(Set<Class<?>> classes, ServletContext servletContext)
throws ServletException;
}Automatic Registration Process:
Log4jServletFilter with async supportLog4jServletContextListener for shutdown handlingDisabling Auto-Configuration:
<context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>Specialized context listener for shutdown-only scenarios when automatic shutdown is disabled. Used when application manually manages Log4j initialization but needs automatic cleanup.
/**
* ServletContextListener for Log4j shutdown when auto-shutdown is disabled.
* Validates Log4j setup during initialization, performs cleanup during shutdown.
*/
public class Log4jShutdownOnContextDestroyedListener implements ServletContextListener {
/**
* Validates that Log4j WebLifeCycle is properly initialized.
* Does not perform initialization, only verification.
*
* @param event ServletContextEvent containing the ServletContext
* @throws IllegalStateException if Log4jWebLifeCycle is not found
*/
public void contextInitialized(ServletContextEvent event);
/**
* Performs Log4j shutdown with configurable timeout.
* Clears LoggerContext and stops logging infrastructure.
*
* @param event ServletContextEvent containing the ServletContext
*/
public void contextDestroyed(ServletContextEvent event);
}When to Use:
isLog4jAutoShutdownDisabled is set to "true"// No configuration needed - automatic registration via SPI
// Log4jServletContainerInitializer handles all setup<web-app>
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app><context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>// Custom initialization code
Log4jWebLifeCycle initializer = WebLoggerContextUtils.getWebLifeCycle(servletContext);
initializer.start();
// Auto-shutdown still occurs via Log4jServletContainerInitializer<context-param>
<param-name>isLog4jAutoShutdownDisabled</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jShutdownOnContextDestroyedListener</listener-class>
</listener>The Log4jServletContextListener implements reference counting to handle scenarios where it might be registered multiple times:
public class Log4jServletContextListener implements ServletContextListener {
/** ServletContext attribute for tracking start count */
static final String START_COUNT_ATTR =
"org.apache.logging.log4j.web.Log4jServletContextListener.START_COUNT";
}This ensures Log4j is initialized only once and shut down only after all registrations are complete.
Both Log4jServletContextListener and Log4jShutdownOnContextDestroyedListener support configurable shutdown timeouts:
public class Log4jServletContextListener implements ServletContextListener {
/** Default shutdown timeout in seconds */
private static final int DEFAULT_STOP_TIMEOUT = 30;
/** Default timeout time unit */
private static final TimeUnit DEFAULT_STOP_TIMEOUT_TIMEUNIT = TimeUnit.SECONDS;
/** Context parameter key for shutdown timeout */
private static final String KEY_STOP_TIMEOUT = "log4j.stop.timeout";
/** Context parameter key for timeout time unit */
private static final String KEY_STOP_TIMEOUT_TIMEUNIT = "log4j.stop.timeout.timeunit";
}Configuration in web.xml:
<context-param>
<param-name>log4j.stop.timeout</param-name>
<param-value>60</param-value>
</context-param>
<context-param>
<param-name>log4j.stop.timeout.timeunit</param-name>
<param-value>SECONDS</param-value>
</context-param>Install with Tessl CLI
npx tessl i tessl/maven-org-apache-logging-log4j--log4j-web