Comprehensive SLF4J implementation providing enterprise-grade logging with flexible configuration, high performance, and extensive appender ecosystem for Java applications.
—
Web application integration components for servlet containers, providing lifecycle management, context initialization, and request-based logging enhancements for Java web applications.
Servlet container lifecycle integration for proper Logback initialization and cleanup.
/**
* Servlet context listener for Logback lifecycle management
*/
public class LogbackServletContextListener implements ServletContextListener {
/**
* Initialize Logback when servlet context starts
*/
@Override
public void contextInitialized(ServletContextEvent sce);
/**
* Cleanup Logback when servlet context stops
*/
@Override
public void contextDestroyed(ServletContextEvent sce);
}Usage Examples:
<!-- web.xml configuration -->
<web-app>
<listener>
<listener-class>ch.qos.logback.classic.servlet.LogbackServletContextListener</listener-class>
</listener>
</web-app>// Programmatic registration (Servlet 3.0+)
@WebListener
public class MyLogbackListener extends LogbackServletContextListener {
// Inherits all functionality
}Automatic servlet container initialization using the SPI mechanism.
/**
* Servlet container initializer for automatic Logback setup
*/
@HandlesTypes({})
public class LogbackServletContainerInitializer implements ServletContainerInitializer {
/**
* Automatically called by servlet container during startup
*/
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException;
}This initializer is automatically discovered and invoked by Servlet 3.0+ containers through the ServiceLoader mechanism, requiring no manual configuration.
Specialized context selectors for multi-webapp environments.
/**
* Context detaching servlet context listener for proper cleanup
*/
public class ContextDetachingSCL implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce);
@Override
public void contextDestroyed(ServletContextEvent sce);
}
/**
* Logger context filter for web applications
*/
public class LoggerContextFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
@Override
public void destroy();
}Web interface for viewing Logback status and configuration information.
/**
* Servlet for viewing Logback status messages via web interface
*/
public class ViewStatusMessagesServlet extends HttpServlet {
private static final long serialVersionUID = 443878494348593337L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
}Usage Examples:
<!-- web.xml servlet configuration -->
<servlet>
<servlet-name>ViewStatusMessages</servlet-name>
<servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ViewStatusMessages</servlet-name>
<url-pattern>/logback-status</url-pattern>
</servlet-mapping>Servlet filter for automatically populating MDC with request information.
/**
* Servlet filter that populates MDC with request information
*/
public class MDCInsertingServletFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
@Override
public void destroy();
}This filter automatically adds the following keys to the MDC:
req.remoteHost - Remote host addressreq.userAgent - User agent stringreq.requestURI - Request URIreq.queryString - Query stringreq.requestURL - Full request URLreq.method - HTTP methodreq.xForwardedFor - X-Forwarded-For headerUsage Examples:
<!-- web.xml filter configuration -->
<filter>
<filter-name>MDCInsertingFilter</filter-name>
<filter-class>ch.qos.logback.classic.helpers.MDCInsertingServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MDCInsertingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>// Programmatic registration (Servlet 3.0+)
@WebFilter("/*")
public class CustomMDCFilter extends MDCInsertingServletFilter {
// Can override methods to customize behavior
}Web application specific context configuration and initialization.
/**
* Utility methods for web application context configuration
*/
public class WebLoggerContextUtils {
/**
* Get the logger context for a web application
*/
public static LoggerContext getLoggerContext(ServletContext servletContext);
/**
* Initialize logger context for a web application
*/
public static void initializeLoggerContext(ServletContext servletContext);
/**
* Destroy logger context for a web application
*/
public static void destroyLoggerContext(ServletContext servletContext);
}<!-- web.xml - Complete Logback servlet integration -->
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0">
<!-- Context parameters for Logback configuration -->
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value>classpath:logback-web.xml</param-value>
</context-param>
<!-- Logback servlet context listener -->
<listener>
<listener-class>ch.qos.logback.classic.servlet.LogbackServletContextListener</listener-class>
</listener>
<!-- MDC inserting filter (must be first) -->
<filter>
<filter-name>MDCInsertingFilter</filter-name>
<filter-class>ch.qos.logback.classic.helpers.MDCInsertingServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MDCInsertingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Status viewing servlet -->
<servlet>
<servlet-name>ViewStatusMessages</servlet-name>
<servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ViewStatusMessages</servlet-name>
<url-pattern>/admin/logback</url-pattern>
</servlet-mapping>
</web-app>import ch.qos.logback.classic.servlet.LogbackServletContextListener;
import ch.qos.logback.classic.helpers.MDCInsertingServletFilter;
@WebListener
public class MyLogbackListener extends LogbackServletContextListener {
// Automatic registration and lifecycle management
}
@WebFilter(filterName = "mdcFilter", urlPatterns = {"/*"})
public class MyMDCFilter extends MDCInsertingServletFilter {
// Automatic MDC population for all requests
}
@WebServlet(name = "logbackStatus", urlPatterns = {"/admin/logback-status"})
public class MyStatusServlet extends ViewStatusMessagesServlet {
// Web interface for viewing Logback status
}import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LogbackWebConfig {
@Bean
public ServletListenerRegistrationBean<LogbackServletContextListener> logbackListener() {
ServletListenerRegistrationBean<LogbackServletContextListener> listener =
new ServletListenerRegistrationBean<>();
listener.setListener(new LogbackServletContextListener());
return listener;
}
@Bean
public FilterRegistrationBean<MDCInsertingServletFilter> mdcFilter() {
FilterRegistrationBean<MDCInsertingServletFilter> filter =
new FilterRegistrationBean<>();
filter.setFilter(new MDCInsertingServletFilter());
filter.addUrlPatterns("/*");
filter.setOrder(1); // Ensure it's first
return filter;
}
@Bean
public ServletRegistrationBean<ViewStatusMessagesServlet> statusServlet() {
ServletRegistrationBean<ViewStatusMessagesServlet> servlet =
new ServletRegistrationBean<>();
servlet.setServlet(new ViewStatusMessagesServlet());
servlet.addUrlMappings("/admin/logback-status");
return servlet;
}
}<!-- logback-web.xml - Web application specific configuration -->
<configuration>
<!-- Use servlet context name in logs -->
<contextName>${CONTEXT_NAME}</contextName>
<!-- Web-specific appender with request information -->
<appender name="WEB_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${catalina.base}/logs/webapp.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${catalina.base}/logs/webapp.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%X{req.requestURI}] [%X{req.remoteHost}] - %msg%n</pattern>
</encoder>
</appender>
<!-- Separate appender for access logs -->
<appender name="ACCESS_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${catalina.base}/logs/access.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${catalina.base}/logs/access.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %X{req.remoteHost} "%X{req.method} %X{req.requestURI} %X{req.queryString}" %X{req.userAgent}%n</pattern>
</encoder>
</appender>
<!-- Access logger -->
<logger name="access" level="INFO" additivity="false">
<appender-ref ref="ACCESS_LOG" />
</logger>
<!-- Root logger -->
<root level="INFO">
<appender-ref ref="WEB_FILE" />
</root>
</configuration>import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
@WebServlet("/user")
public class UserServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(UserServlet.class);
private static final Logger accessLogger = LoggerFactory.getLogger("access");
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// MDC is automatically populated by MDCInsertingServletFilter
// Additional custom MDC values can be added
String userId = req.getParameter("userId");
if (userId != null) {
MDC.put("userId", userId);
}
try {
logger.info("Processing user request");
// Business logic here
processUserRequest(req, resp);
// Access log entry
accessLogger.info("Request processed successfully");
} catch (Exception e) {
logger.error("Error processing user request", e);
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
// Clean up custom MDC values
MDC.remove("userId");
// Note: Request-related MDC values are automatically cleaned up
}
}
private void processUserRequest(HttpServletRequest req, HttpServletResponse resp) {
// Implementation
}
}// Custom context selector for webapp isolation
public class WebAppContextSelector extends ContextJNDISelector {
@Override
public LoggerContext getLoggerContext() {
// Return context specific to current web application
return getLoggerContext(getCurrentWebAppName());
}
private String getCurrentWebAppName() {
// Implementation to determine current webapp context
return Thread.currentThread().getContextClassLoader().toString();
}
}
// System property to enable custom selector
// -Dlogback.ContextSelector=com.example.WebAppContextSelectorThis servlet integration provides:
Install with Tessl CLI
npx tessl i tessl/maven-ch-qos-logback--logback-classic