Spring - qos-ch/logback-extensions GitHub Wiki
The Logback Spring extension easily enables Logback to be used with Spring applications. This extension effectively enables similar features as Spring's Log4J Support, but for Logback.
This extension allows you to:
- Configure Logback components (Appenders, Layouts, etc) within Spring configuration (e.g.
applicationContext.xml
and Spring Java config). - Begin receiving log messages before Spring and the servlet starts, and store them in memory until the Appenders are configured.
- Use SLF4J's java.util.logging bridge.
- Specify the
logback.xml
location using a Spring resource path and system property placeholders. - Use the pre-set system property
webapp.root
(path to unpacked WAR directory) inside thelogback.xml
for setting log file paths, etc.
The last two features can help avoid having to configure Logback components programmatically.
- Add the following .jars to your application's classpath (this assumes you already have your respective Spring .jars added):
Jar | Maven or Ant+Ivy | Notes |
---|---|---|
logback-ext-spring-version.jar |
<dependency> <groupId>org.logback-extensions</groupId> <artifactId>logback-ext-spring</artifactId> <version>version</version> </dependency> |
logback-ext-spring is compiled against Spring 3.1.1 or later. Current version: 0.1.4 |
For redirecting java.util.logging, you will need to add jul-to-slf4j
. For redirecting Commons Logging, add jcl-over-slf4j
.
If you are using Spring Java configuration, do not set <scope>runtime</scope>
in Maven for Logback dependencies.
If using Spring in a web application, add the following servlet context listener declaration to web.xml
:
<listener>
<listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
</listener>
This will start up the Logback environment and shut it down in sync with your web application's lifecycle. This listener should be registered before ContextLoaderListener in web.xml, when using custom Logback initialization. For Servlet 2.2 containers and Servlet 2.3 ones that do not initialize listeners before servlets, use LogbackConfigServlet. See the LogbackConfigListener and WebLogbackConfigurer javadoc for details.
If you want to specify the logback.xml
config file in a location other than the default (root of the classpath), you can specify its location using a Spring resource path with system property placeholders in a logbackConfigLocation
servlet context param in web.xml
:
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value>/WEB-INF/logback-${os.name}.xml</param-value>
</context-param>
NOTE: If we take the logback.xml from somewhere else in the system, use file:
prefix.
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value>file:/home/john/configs/logback-${os.name}.xml</param-value>
</context-param>
Ref: https://docs.spring.io/spring-framework/docs/3.1.x/spring-framework-reference/html/resources.html
If logback.xml
is in one of its standard locations, nothing needs to be done. To specify its location programmatically, call LogbackConfigurer.initLogging(String location)
before starting Spring. The parameter is a Spring resource path and can use system property placeholders.
To redirect java.util.logging to Logback (provided you have jul-to-slf4j
in the classpath), execute the following before creating the Spring context:
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
If you want to configure Logback components (Appenders, Layouts, etc) in applicationContext.xml
instead of logback.xml
to take advantage of the many Spring configuration features (PropertyPlaceholderConfigurer, Spring environment profiles, etc), you can follow the following steps.
Define a logback.xml
file defining one or more DelegatingLogbackAppender
elements. For example:
<configuration>
<appender name="consoleAppender" class="ch.qos.logback.ext.spring.DelegatingLogbackAppender"/>
<root level="INFO">
<appender-ref ref="consoleAppender"/>
</root>
</configuration>
The DelegatingLogbackAppender
stores log messages until the Spring context is created and the real appender is configured. The DelegatingLogbackAppender exposes a single property, cacheMode
, with three settings: on
, off
, soft
. The default is on
. Off
disables storing logs. Soft
uses SoftReferences to allow stored log messages to be garbage collected if memory pressure necessitates it.
Add the following bean to applicationContext.xml
:
<beans ...>
...
<bean class="ch.qos.logback.ext.spring.ApplicationContextHolder"/>
...
</beans>
For each <appender .../>
defined in logback.xml
, ensure you have an identically named Appender
bean defined in applicationContext.xml
. Continuing the example above:
<beans ...>
...
<bean id="consoleAppender" class="ch.qos.logback.core.ConsoleAppender" init-method="start" destroy-method="stop">
<property name="context" value="#{ T(org.slf4j.LoggerFactory).getILoggerFactory() }"/>
<property name="encoder">
<bean class="ch.qos.logback.classic.encoder.PatternLayoutEncoder" init-method="start" destroy-method="stop">
<property name="context" value="#{ T(org.slf4j.LoggerFactory).getILoggerFactory() }"/>
<property name="pattern" value="%date %-5level [%thread] %logger{36} %m%n"/>
</bean>
</property>
</bean>
...
</beans>
Notice that the bean id consoleAppender
is the same as the appender name in logback.xml
.
WARNING: Ensure that you set the init-method
and destroy-method
properties to start
and stop
respectively for relevant Logback components. Most Logback components will not function correctly unless they are started and stopped appropriately!
The above xml configuration is equivalent to the following configuration class:
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.ext.spring.ApplicationContextHolder;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LogbackConfig {
@Bean
public static ApplicationContextHolder applicationContextHolder() {
return new ApplicationContextHolder ();
}
@Bean
public static LoggerContext loggerContext() {
return (LoggerContext) LoggerFactory.getILoggerFactory();
}
@Bean (initMethod = "start", destroyMethod = "stop")
public static PatternLayoutEncoder encoder (LoggerContext ctx) {
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(ctx);
encoder.setPattern("%date %-5level [%thread] %logger{36} %m%n");
return encoder;
}
@Bean (initMethod = "start", destroyMethod = "stop")
public static ConsoleAppender consoleAppender (LoggerContext ctx, PatternLayoutEncoder encoder) {
ConsoleAppender appender = new ConsoleAppender();
appender.setContext(ctx);
appender.setEncoder(encoder);
return appender;
}
}
Note that the method consoleAppender
has the same name as the appender defined in logback.xml
.
If you have problems using a class which you've included in Maven, ensure that the dependency's scope is compile
(the default) rather than runtime
. Many examples in this wiki suggest using runtime
scope, which only works for xml configuration.
WARNING: Ensure that you set the context of each Logback component.
WARNING: Ensure that you set the initMethod
and destroyMethod
properties to start
and stop
respectively for relevant Logback components. Most Logback components will not function correctly unless they are started and stopped appropriately! This usually necessitates making each Logback component its own Spring component.