Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to configure logback from two separate logback.xml files per log level?

Tags:

java

logback

I have a logback.xml outside my packaged .war that I have to use for INFO & ERROR logging configuration - and no changes can be made to it . [edited: might be possible to add a or something similarly minimal ]
The goal I would like to set up my debug logging in such a way that each module has its own .log file, etc - and I can't add this configuration to the existing logback.xml, as stated above. [edited in] Also, I need a way to enable debug for specific module only -preferably via "my" added logback.xml

How do I get logback to read just the debug configuration from a different .xml file ?

Edited to add sample files:

the main/aka unchangeable logback.xml

<?xml version="1.0" encoding="UTF-8"?>

<property scope="system" name="component-name" value="COMPONENT_A" />
<property file="$configuration.yaml" />
<property scope="context" name="enable-all-log" value="false" />

    <property name="default-log-pattern"
    value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{uuid}|%X{instanceID}|%thread||%X{userId}|%level />

<!-- All log -->
<if condition='property("enable-all-log").equalsIgnoreCase("true")'>
    <then>
        <appender name="ALL_ROLLING"
            class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${log.home}/${component-name}/${subcomponent-name}/all.log
            </file>

            <rollingPolicy
                class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
                <fileNamePattern>${log.home}/${component-name}/${subcomponent-name}/all.log.%i
                </fileNamePattern>
                <minIndex>1</minIndex>
                <maxIndex>10</maxIndex>
            </rollingPolicy>

            <triggeringPolicy
                class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                <maxFileSize>20MB</maxFileSize>
            </triggeringPolicy>
            <encoder>
                <pattern>${default-log-pattern}</pattern>
            </encoder>
        </appender>

        <appender name="ASYNC_ALL" class="ch.qos.logback.classic.AsyncAppender">
            <appender-ref ref="ALL_ROLLING" />
        </appender>
    </then>
</if>

<!-- Error log -->
<appender name="ERROR_ROLLING"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${log.home}/${component-name}/${subcomponent-name}/error.log
    </file>

    <!-- Audit messages filter - deny audit messages -->
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
            <marker>AUDIT_MARKER</marker>
        </evaluator>
        <onMismatch>NEUTRAL</onMismatch>
        <onMatch>DENY</onMatch>
    </filter>   
<!-- Debug log -->
<appender name="DEBUG_ROLLING"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${log.home}/${component-name}/${subcomponent-name}/debug.log
    </file>


    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
            <marker>TRANSACTION_MARKER</marker>
        </evaluator>
        <onMismatch>NEUTRAL</onMismatch>
        <onMatch>DENY</onMatch>
    </filter>

    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
            <expression>
                e.level.toInt() &lt;= DEBUG.toInt()
            </expression>
        </evaluator>
        <OnMismatch>DENY</OnMismatch>
        <OnMatch>NEUTRAL</OnMatch>
    </filter>

    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
        <fileNamePattern>${log.home}/${component-name}/${subcomponent-name}/debug.log.%i
        </fileNamePattern>
        <minIndex>1</minIndex>
        <maxIndex>10</maxIndex>
    </rollingPolicy>

    <triggeringPolicy
        class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <maxFileSize>20MB</maxFileSize>
    </triggeringPolicy>
    <encoder>
        <pattern>${default-log-pattern}</pattern>
    </encoder>
</appender>

<root level="INFO">
    <appender-ref ref="ASYNC_ERROR" />
    <appender-ref ref="ASYNC_DEBUG" />
    <if condition='property("enable-all-log").equalsIgnoreCase("true")'>
        <then>
            <appender-ref ref="ALL_ROLLING" />
        </then>
    </if>
</root>

<logger name="foo.bar" level="INFO" />

like image 514
akapulko2020 Avatar asked Jan 03 '17 11:01

akapulko2020


People also ask

How do I change the Logback configuration file?

Setting the location of the configuration file via a system property. You may specify the location of the default configuration file with a system property named "logback. configurationFile" . The value of this property can be a URL, a resource on the class path or a path to a file external to the application.

Which of the following file is used by Logback logging system?

Logback-classic natively implements the SLF4J API so that you can readily switch back and forth between logback and other logging systems such as log4j or java. util. logging (JUL) introduced in JDK 1.4. The third module called access integrates with Servlet containers to provide HTTP-access log functionality.

Where should Logback xml be stored?

In a Spring Boot application, you can put the Logback. xml file in the resources folder. If your Logback. xml file is outside the classpath, you need to point to its location using the Logback.


1 Answers

You can use the Logback fileInclusion mechanism.

From the documentation :

Joran supports including parts of a configuration file from another file. This is done by declaring a element.

If you don't know, Joran is a component on which Logback relies on. You have no additional library to add.
Here are the 3 ways of including a configuration file :

The contents to include can be referenced as a file, as a resource, or as a URL.

As a file: To include a file use the file attribute. You can use relative paths but note that the current directory is defined by the application and is not necessarily related to the path of the configuration file.

As a resource:

To include a resource, i.e a file found on the class path, use the resource attribute.

<include resource="includedConfig.xml"/>

As a URL:

To include the contents of a URL use the url attribute.


Here are some hints about how to implement it.

Beware of duplicated elements between configuration files

I would like to warn you about unique elements which should not be duplicated between the logback configuration files, as for example the root element.

Your actual configuration declares very probably the root element, so you should not specify it again in the new configuration file.
It is the same thing for the logger elements for a specific class or package : you should not declare them twice to avoid unexpected behavior at runtime.

Which configuration file(s) should include other(s)

If the actual configuration file contains general configuration and the the new configuration files contain specific configurations, it makes sense to make the actual configuration file which one that includes the others.

Split configuration files

If you think that having multiple configurations may help you to have a cleaner configuration, don't hesitate to split it in multiples files :

...   
<include resource="other-logback-debug_product_a.xml"/>
<include resource="other-logback-debug_product_b.xml"/>
...

Be aware of the additivity

In the included resources, you should probably specify the additivity to false (which is true by default) for all loggers in so far as I think you don't want that the debugging logs to be duplicated in the ancestor's appenders.

Example

The included file defines a RollingFileAppender named FILE_DEBUG_KIOSK_PRODUCT.
It also defines a logger for the com.product.kiosk.area package with the level of log to DEBUG and it attaches to it the appender.
I have cooked it by starting from one of appenders your posted (I removed not relevant parts).

The configuration file that includes :

<configuration>    
  <include file="includedConfFooLogback.xml"/>  
</configuration>

includedConfFooLogback.xml, the included configuration file :

<?xml version="1.0" encoding="UTF-8"?>

<included>

    <!-- Debug log -->
    <appender name="FILE_DEBUG_KIOSK_PRODUCT"
        class="ch.qos.logback.core.rolling.RollingFileAppender">

        <file>${debug.kiosk.product.dir}/debug.log</file>

        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${log.home}/${component-name}/${subcomponent-name}/debug.log.%i
            </fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>10</maxIndex>
        </rollingPolicy>

        <triggeringPolicy
            class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>20MB</maxFileSize>
        </triggeringPolicy>
        <encoder>
           <pattern>${default-log-pattern}</pattern>
        </encoder>
    </appender>

    <logger name="com.product.kiosk.area" level="DEBUG" additivity="false">
        <appender-ref ref="FILE_DEBUG_KIOSK_PRODUCT" />
    </logger>

</included>
like image 127
davidxxx Avatar answered Oct 19 '22 22:10

davidxxx