How to use multiple configurations with logback in a single project?

Viewed 33817

The configuration file for logback gets found on the classpath, and is therefore Eclipse-project-specific, which is not what I want. I'm using multiple Java utilities, all of them residing in a single project (this sharing the classpath), and I need to use a specific configuration for some of them.

I've tried variable substitution and Joram configurator, but nothing worked for me. This was most probably my fault, and I'm going to solve it one day, but for now I'd need a simple solution.

3 Answers

In a Spring Boot application, you can reference Spring Profiles inside logback configuration file.

See this article.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
 <springProfile name="dev">
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
      <encoder>
        <pattern>
          %d{HH:mm:ss.SSS} | %5p | %logger{25} | %m%n
        </pattern>
        <charset>utf8</charset>
      </encoder>
    </appender>
    <root level="DEBUG">
      <appender-ref ref="CONSOLE"/>
    </root>
  </springProfile>
  ...

I have used another option based on Leonidas blog. There are two files:

  • the optional property file (environment.properties) that contains the environment property
  • and custom configurations (e.g. logback-env-test.xml). All these files have to be on the classpath.

If the property file exists and defines logEnv property e.g.

logEnv = dev66

the logback tries to find and include the custom configuration from logback-env-dev66.xml

<included>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
    </root>
</included>

Overwise it will be falback to default (<else> section) configuration. Please, note the <included> tag are using instead of <configuration> in custom configuration files.

the logback.xml to manage all the above things:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="5 seconds" debug="true">
    <!-- To skip error if property file doesn't exist -->
    <define name="propExists" class="ch.qos.logback.core.property.ResourceExistsPropertyDefiner">
        <resource>environment.properties</resource>
    </define>
    <if condition='${propExists}'>
        <then>
            <property resource="environment.properties" />
        </then>
    </if>
    <!-- If specific configuration exists, load it otherwise fallback to default (<else> section)  -->
    <define name="confExists" class="ch.qos.logback.core.property.ResourceExistsPropertyDefiner">
        <resource>logback-env-${logEnv}.xml</resource>
    </define>
    <if condition='${confExists}'>
        <then>
            <include resource="logback-env-${logEnv}.xml"/>
        </then>
        <else>
            <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
                <encoder>
                    <pattern>%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
                </encoder>
            </appender>
            <root level="INFO">
                <appender-ref ref="STDOUT" />
            </root>
        </else>
    </if>
</configuration>

It will allow you to have separate configuration for all environments, define own custom configuration (e.g. local development) without influence on others.

Related