Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controlling logback environment dependent properties in external application properties file

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.

like image 306
javafan Avatar asked Nov 16 '16 03:11

javafan


2 Answers

add system environment variable, so logback falls back to this location for configuration file

logback.configurationFile=path/to/config.xml
like image 112
kuhajeyan Avatar answered Oct 06 '22 00:10

kuhajeyan


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 the logback.xml, in the example "consoleAppender". Also don't forget to specify the initMethod and destroyMethod.

Hope this helps you to find the way not to hardcode the path.

like image 28
vl4d1m1r4 Avatar answered Oct 05 '22 23:10

vl4d1m1r4