Configuring Logback

Configuring Logback

This page is dedicated to pax-logging-logback backend which provides support for Logback library.

Logback provides only XML-based configuration which doesn’t match well with properties-based approach taken by Configuration Admin. Thus all org.ops4j.pax.logging configurations for pax-logging-logback bundle look very simple:

org.ops4j.pax.logging.logback.config.file = /path/to/logback.xml

While the actual /path/to/logback.xml is normal Logback XML configuration file. For example:

<configuration> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="ch.qos.logback.classic.layout.TTLLLayout" /> </encoder> </appender> <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>logs/service.log</file> <append>true</append> <encoder> <pattern>%logger/%class [%level] %mdc %message%n</pattern> </encoder> <!-- A RollingPolicy is responsible for performing the rolling over of the active log file. The RollingPolicy is also responsible for providing the active log file, that is the live file where logging output will be directed. "what" - ch.qos.logback.core.rolling.FixedWindowRollingPolicy - ch.qos.logback.core.rolling.TimeBasedRollingPolicy - ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy A TriggeringPolicy controls the conditions under which roll-over occurs. Such conditions include time of day, file size, an external event, the log request or a combination thereof. "when" - ch.qos.logback.core.rolling.TimeBasedRollingPolicy - ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy - ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy - ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP - ch.qos.logback.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy Both the above policies are required. But if RollingPolicy is both ch.qos.logback.core.rolling.RollingPolicy and ch.qos.logback.core.rolling.TriggeringPolicy, only one is sufficient. These are: - ch.qos.logback.core.rolling.TimeBasedRollingPolicy - ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy --> <rollingPolicy class="org.ops4j.pax.logging.logback.extra.AlwaysTriggerPolicy"> <fileNamePattern>logs/service.log.%d{yyyy-MM}</fileNamePattern> <maxHistory>5</maxHistory> <totalSizeCap>100KB</totalSizeCap> </rollingPolicy> </appender> <logger name="my.logger" level="info" additivity="false"> <appender-ref ref="file" /> </logger> <root level="debug"> <appender-ref ref="console" /> </root> </configuration>

SIFT logging

Sifting (segregating) logger can split incoming logging events and pass them to different or parameterized appenders. Segregation is done using configured key. This key is then looked up in MDC which always contains the following entries (provided by Pax Logging itself):

Other libraries may use/add other keys. Apache camel adds these, when Camel context is MDC-aware:

  • camel.exchangeId

  • camel.messageId

  • camel.contextId

  • camel.correlationId

  • camel.breadcrumbId

Here’s sample configuration using ch.qos.logback.classic.sift.SiftingAppender:

<configuration> <appender name="sift" class="ch.qos.logback.classic.sift.SiftingAppender"> <discriminator> <key>bundle.name</key> <defaultValue>no-such-bundle</defaultValue> </discriminator> <sift> <appender name="file-${bundle.name}" class="ch.qos.logback.core.FileAppender"> <file>target/logs-logback/${bundle.name}-file-appender.log</file> <append>false</append> <encoder> <pattern>%c/%C [%p] {%X} %m%n</pattern> </encoder> </appender> </sift> </appender> <root level="info"> <appender-ref ref="sift" /> </root> </configuration>

Customizing Logback

Users are allowed to extend the functionality of Logback through mechanisms provided by Pax Logging.

Using whiteboard pattern, users may register services implementing interfaces from org.ops4j.pax.logging.spi package. These services may then be referenced in configuration like this:

<configuration> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="ch.qos.logback.classic.layout.TTLLLayout" /> </encoder> </appender> <appender name="any-name" class="org.ops4j.pax.logging.logback.internal.bridges.PaxAppenderDelegate"> <!-- Will translate to "(&(objectClass=org.ops4j.pax.logging.spi.PaxAppender)(org.ops4j.pax.logging.appender.name=custom))" --> <paxname>custom</paxname> </appender> <logger name="my.logger" level="info" additivity="false"> <!-- In Log4J1 we had "osgi:custom" refrences. Here we have to be more explicit with the above <appender /> --> <!--appender-ref ref="osgi:custom" /--> <appender-ref ref="any-name" /> </logger> <root level="info"> <appender-ref ref="console" /> </root> </configuration>

Another way is to provide fragment bundles for pax-logging-logback bundle with special implementations of e.g., appenders. This will be described in more details for pax-logging-log4j2 backend.