The Apache Log4j support for web servlet containers
npx @tessl/cli install tessl/maven-org-apache-logging-log4j--log4j-web@2.25.0Log4j Web provides comprehensive support for integrating Apache Log4j 2 logging framework with Java EE web applications and servlet containers. It handles proper Log4j lifecycle management during web application startup and shutdown, provides web-specific logging utilities, and ensures thread-safe logging contexts in servlet environments.
pom.xml:<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.25.1</version>
</dependency>For Gradle:
implementation 'org.apache.logging.log4j:log4j-web:2.25.1'import org.apache.logging.log4j.web.Log4jWebSupport;
import org.apache.logging.log4j.web.WebLoggerContextUtils;
import org.apache.logging.log4j.web.Log4jServletContextListener;
import org.apache.logging.log4j.web.Log4jServletFilter;
import org.apache.logging.log4j.web.Log4jServletContainerInitializer;
import org.apache.logging.log4j.web.Log4jShutdownOnContextDestroyedListener;
import org.apache.logging.log4j.web.ServletRequestThreadContext;
import org.apache.logging.log4j.web.WebLookup;
import org.apache.logging.log4j.web.appender.ServletAppender;Log4j Web automatically configures itself in Servlet 3.0+ environments without any manual setup:
// No manual configuration needed - Log4jServletContainerInitializer
// automatically registers listeners and filtersAdd to web.xml:
<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>import org.apache.logging.log4j.web.WebLoggerContextUtils;
// In async servlets, wrap async tasks with proper logging context
ServletContext servletContext = request.getServletContext();
Runnable wrappedTask = WebLoggerContextUtils.wrapExecutionContext(
servletContext,
() -> {
// Your async task code here
Logger logger = LogManager.getLogger();
logger.info("Executing async task with proper logging context");
}
);Log4j Web is built around several key components that integrate seamlessly with servlet containers:
The design ensures that Log4j is properly initialized before any application code runs and cleanly shut down after the application stops, while providing thread-safe logging contexts for concurrent request processing.
Core servlet lifecycle components including context listeners, filters, and container initializers that manage Log4j startup, shutdown, and per-request context binding.
public class Log4jServletContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent event);
public void contextDestroyed(ServletContextEvent event);
}
public class Log4jServletFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
public void destroy();
}
public class Log4jServletContainerInitializer implements ServletContainerInitializer {
public void onStartup(Set<Class<?>> classes, ServletContext servletContext) throws ServletException;
}Utilities for managing LoggerContext instances in web applications, including context retrieval, lifecycle management, and execution wrapping for async operations.
public final class WebLoggerContextUtils {
public static LoggerContext getWebLoggerContext(ServletContext servletContext);
public static LoggerContext getRequiredWebLoggerContext(ServletContext servletContext);
public static Log4jWebLifeCycle getWebLifeCycle(ServletContext servletContext);
public static Runnable wrapExecutionContext(ServletContext servletContext, Runnable runnable);
public static ServletContext getServletContext();
}
public interface Log4jWebSupport {
void setLoggerContext();
void clearLoggerContext();
void wrapExecution(Runnable runnable);
}Web-aware logging components including servlet context lookups for configuration variables, servlet appenders for direct logging to container logs, and thread context utilities for capturing request information.
@Plugin(name = "web", category = "Lookup")
public class WebLookup extends AbstractLookup {
public String lookup(LogEvent event, String key);
}
@Plugin(name = "Servlet", category = "Core", elementType = "appender", printObject = true)
public final class ServletAppender extends AbstractAppender {
public void append(LogEvent event);
public static <B extends Builder<B>> B newBuilder();
}
public class ServletRequestThreadContext {
public static void put(String key, ServletRequest servletRequest);
public static void put(String key, HttpServletRequest servletRequest);
}These parameters can be set in web.xml or programmatically via ServletContext.setInitParameter():
log4jContextName: Name for the LoggerContext (required for JNDI configurations)log4jConfiguration: Location of Log4j configuration fileisLog4jContextSelectorNamed: Set to "true" to enable JNDI context selectorisLog4jAutoInitializationDisabled: Set to "true" to disable automatic initialization in Servlet 3.0+isLog4jAutoShutdownDisabled: Set to "true" to disable automatic shutdown in Servlet 3.0+log4j.stop.timeout: Shutdown timeout in seconds (default: 30)log4j.stop.timeout.timeunit: Timeout time unit (default: SECONDS)Log4j Web handles various error conditions gracefully:
IllegalStateException when required LoggerContext is missingCommon exceptions:
IllegalStateException: Thrown when Log4j Web components are in invalid statesServletException: Propagated from underlying servlet container issues