In my spring-boot
application I use logback
for logging. The application uses external application.properties
file for setting environment specific application properties and starts with option: -spring.config.location=path/to/file
. I would like logback configuration to read properties from there as well so that all environment properties are managed in one place.
I tried the approach described here, but since the properties file is not on the classpath, I get the error:
java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.joran.action.PropertyAction - Could not find resource [application.properties]
Is there something I am missing?
UPDATE:
Adding this configuration works:
<property file="path/to/file" />
But I would like to avoid hardcoding the file path.
add system environment variable, so logback falls back to this location for configuration file
logback.configurationFile=path/to/config.xml
Since you are using Spring you can use Spring extensions for Logback: logback-ext-spring
What this library does is basically gives you possibility to delegate the actual logging to spring managed objects giving you access to the spring context. You can create and configure appenders within the Spring configuration where you will have access to the Environment
variables and therefore also to application.properties
.
You can find more info on the GitHub page but here is an example configuration, based on the example provided in the link, where the pattern for the console appender is retrieved from the environment property "consolePattern"
:
logback.xml:
<configuration>
<appender name="consoleAppender" class="ch.qos.logback.ext.spring.DelegatingLogbackAppender"/>
<root level="INFO">
<appender-ref ref="consoleAppender"/>
</root>
</configuration>
LogbackConfig.java:
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.core.env.Environment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LogbackConfig {
@Autowired
private Environment environment;
@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(environment.getProperty("consolePattern");
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;
}
}
Important
Please note that the spring bean name must match the name of the appender in thelogback.xml
, in the example"consoleAppender"
. Also don't forget to specify theinitMethod
anddestroyMethod
.
Hope this helps you to find the way not to hardcode the path.
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