Search code examples
logback

How can I configure logback conditionally based on context name?


I have three separate projects, each with their own embedded logback.xml files. Each of these files includes a common logging config file in the user's home durectory:

<include file="${user_home}/loggingConfig.xml"/>

After the include, I have this specification:

<root level="error">
    <appender-ref ref="${appender:-console}" />
</root>

This allows the user to configure their log levels and appenders, and have them applied by the core logging config file.

For example, in ~/loggingConfig.xml I have this line:

<property name="appender" value="file" />

But co-workers who prefer console logging leave that line out.

The problem is I would like to use different appenders for each log file. In otherwords, I would like to conditionally set a different appender based on which project is reading the customized config file.

I realize I could configure each project to read differently named config files, but I would like to eliminate the clutter and allow for shared configuration as well.


Solution

  • The documentation is a bit spare for advanced configuration, but I found that you can use the logback context name as a variable with conditional logging. So for each project I define a custom context name in the projects logback.xml file:

    <contextName>project1</contextName>
    

    etc...

    Then in my ~/loggingConfig.xml file I can do this:

    <property name="appender" value="file" />
    
    <!--if condition='property("CONTEXT_NAME").equalsIgnoreCase("project1")'>
        <then>
            <property name="appender" value="file" />
        </then>
    </if-->
    <if condition='property("CONTEXT_NAME").equalsIgnoreCase("project2")'>
        <then>
            <property name="appender" value="console" />
        </then>
    </if>
    <if condition='property("CONTEXT_NAME").equalsIgnoreCase("project3")'>
        <then>
            <property name="appender" value="file" />
        </then>
    </if>
    

    This can get a bit clunky, but in reality I am using this solution to configure properties used by a single appender for different projects, while still having a graceful fallback to a default value for projects that don't have their own conditional block.