Bootique Logback - v3.0


1. Bootique Integration with Logback

As mentioned in Bootique general documentation on logging, standard modules rely on SLF4J loggers that can be easily bridged to various advanced logging frameworks. Same maximally neutral logging approach is reasonable to apply in the user modules as well.

bootique-logback is a "drag-and-drop" module integrating Bootique logging with Logback logging framework. Just like any other module, bootique-logback can be enabled by simply adding it to the pom.xml dependencies, assuming autoLoadModules() is in effect:

Maven
<dependency>
    <groupId>io.bootique.logback</groupId>
    <artifactId>bootique-logback</artifactId>
</dependency>
Gradle
{
  implementation: 'io.bootique.logback:bootique-logback'
}

Without further configuration it would log everything to console using INFO level. Configuration can be provided via YAML, as shown in the Configuration Reference section. Configuration options include per class and package log levels configuration, a choice of appenders, etc.

2. Configuration Reference

2.1. log

log:
  level: warn
  appenderRefs:
    - test
  loggers:
    com.foo:
      level: debug
      appenderRefs:
        - test
    com.example:
      level: debug
  appenders:
    - type: file
      name: test
      file: target/logback/testRun_Debug.log
      filters:
        - type: threshold
          level: info
      layout:
        type: pattern
        logFormat: '%c{20}: %m%n'

"log" is a root element of the Logback configuration and is bound to a LogbackContextFactory object. It supports the following properties:

Table 1. "log" Element Property Reference
Property Default Description

appenders

console appender

A list of appenders to output logs to. See below.

appenderRefs

none

A list of references to appenders. If it’s added to child logger only, then the child logger will write logs with this named appender. If the appender added to the root logger, or to both root and child loggers, or none, the appender will be attached to root logger only.

level

info

A default logging level. Can be overridden per logger.

loggers

none

A map of logger factories by logger name. Logger name is a package name (applied recursively) or class name. See below.

useLogbackConfig

false

If true, all other logback settings are ignored and the user is expected to provide its own config file per Logback documentation. This is only needed for a few advanced options not directly available via Bootique config.

2.2. log.appenders

log:
  appenders:
    - type: file
      name: test
      file: /var/log/myapp.log
      layout:
        type: json
        timestampFormat: "yyyy-MM-dd HH:mm"
    - type: console
      layout:
        type: pattern
        logFormat: '%c{20}: %m%n'

Lists appenders to sends the logs to. If the list is empty, console appender is used with default settings. Currently available appenders are "console" and "file":

Table 2. "console" Appender Property Reference
Property Default Description

logFormat

%-5p [%d{ISO8601,UTC}] %thread %c{20}: %m%n%rEx

A format of the log lines. See Logback PatternLayout for details. This is a shortcut for a pattern layout with a given format.

target

stdout

Whether to log to standard output or standard error. Possible values are stdout and stderr

filters

none

A collection of filters to use with this appender

layout

pattern

Layout config for this appender. Possible values are pattern, html, xml and json. If not set pattern layout is used by default. Examples are given below

Table 3. "file" Appender Property Reference
Property Default Description

logFormat

%-5p [%d{ISO8601,UTC}] %thread %c{20}: %m%n%rEx

A format of the log lines. See Logback PatternLayout for details. This is a shortcut for a pattern layout with a given format.

name

none

The name of the appender. If it has a name it could be added to the loggers by that name. If it has no name it will be automatically added to the root logger.

file

none

A name of a file to send the log to.

append

true

If true, events are appended at the end of an existing file. Otherwise, if append is false, any existing file is truncated. The append option is set to true by default.

rollingPolicy

none

An object that defines a log rotation policy. Examples are given below.

filters

none

A collection of filters to use with this appender. See filters section.

layout

pattern

Layout config for this appender. Possible values are pattern,html, xml and json. Examples are given below

There are a few ways log file rotation can be configured for the "file" appender, as defined by the rollingPolicy. Out of the box the following Logback policies are supported: fixedWindow, time, sizeAndTime.

2.3. log.appenders.rollingPolicy

2.3.1. "fixedWindow" Rolling Policy

log:
  appenders:
    - type: file
      file: /var/log/myapp.log
      logFormat: '%c{20}: %m%n'
      rollingPolicy:
        type: fixedWindow
        fileNamePattern: '/var/log/myapp-%i.log'
        historySize: 5
        fileSize: 20
        checkIncrement: 50ms

"fixedWindow" policy rotates the main log file when it reaches a certain size, keeping one or more rotated files.

Table 4. "fixedWindow" rolling policy Property Reference
Property Default Description

fileNamePattern

none

A pattern of rotated file name. Must contain %i somewhere in the pattern (replaced by a number during rotation).

historySize

none (unlimited)

A max number of rotated files to keep.

fileSize

none

Max file size that causes rotation. Expressed in bytes, kilobytes, megabytes or gigabytes by suffixing a numeric value with KB, MB and respectively GB. For example: 5000000, 5000KB, 5MB and 2GB.

checkIncrement

1s

Prevents very quick succession of rotations. Files will not be rotated regardless of their size if the previous rotation happened within the specified interval.

2.3.2. "time" Rolling Policy

log:
  appenders:
    - type: file
      file: /var/log/myapp.log
      logFormat: '%c{20}: %m%n'
      rollingPolicy:
        type: time
        fileNamePattern: '/var/log/myapp-%d{yyyyMMddHHmmss}.log'

"time" policy rotates the main log file at a fixed time interval determined by the file name pattern.

Table 5. "time" rolling policy Property Reference
Property Default Description

fileNamePattern

none

A pattern of rotated file name. Its value should consist of the name of the file, plus a suitably placed %d conversion specifier. The %d conversion specifier may contain a date-and-time pattern as specified by the java.text.SimpleDateFormat class. If the date-and-time pattern is omitted, then the default pattern yyyy-MM-dd is assumed. The rollover interval is inferred from the value of the pattern.

historySize

none (unlimited)

A max number of rotated files to keep.

totalSize

none

Max size of all log files combined. Expressed in bytes, kilobytes, megabytes or gigabytes by suffixing a numeric value with KB, MB and respectively GB. For example: 5000000, 5000KB, 5MB and 2GB.

2.3.3. "sizeAndTime" Rolling Policy

log:
  appenders:
    - type: file
      file: /var/log/myapp.log
      logFormat: '%c{20}: %m%n'
      rollingPolicy:
        type: sizeAndTime
        fileNamePattern: '/var/log/myapp-%d{yyyyMMddHHmmss}.%i.log'
        historySize: 5
        fileSize: 50
        totalSize: 150

"sizeAndTime" policy rotates the main log file either at a fixed time interval determined by the file name pattern or when the log file reaches a certain size.

Table 6. "sizeAndTime" rolling policy Property Reference
Property Default Description

fileNamePattern

none

A pattern of rotated file name. Its value should consist of the name of the file, plus a suitably placed %d conversion specifier. The %d conversion specifier may contain a date-and-time pattern as specified by the java.text.SimpleDateFormat class. If the date-and-time pattern is omitted, then the default pattern yyyy-MM-dd is assumed. The rollover interval is inferred from the value of the pattern.

historySize

none (unlimited)

A max number of rotated files to keep.

totalSize

none

Max size of all log files combined. Expressed in bytes, kilobytes, megabytes or gigabytes by suffixing a numeric value with KB, MB and respectively GB. For example: 5000000, 5000KB, 5MB and 2GB.

fileSize

none

Max file size that causes rotation. Expressed in bytes, kilobytes, megabytes or gigabytes by suffixing a numeric value with KB, MB and respectively GB. For example: 5000000, 5000KB, 5MB and 2GB.

2.4. log.appenders.filters

2.4.1. "level" Filter

log:
  level: debug
  appenders:
    - type: file
      file: target/logs/info-only.log
      logFormat: '%c{20}: %m%n'
      filters:
        - type: level
          level: info
          onMatch: accept
          onMismatch: deny

level filter filters events based on exact level matching.

Property Default Description

level

none

logging event level to filter

onMatch

neutral

action to take on event level match (accept, deny, neutral)

onMismatch

neutral

action to take on event level mismatch (accept, deny, neutral)

2.4.2. "threshold" Filter

log:
  level: debug
  appenders:
    - type: console
      filters:
        - type: threshold
          level: warn

threshold filter filters events below the specified level threshold. Events with a level below the threshold will be denied.

Property Default Description

level

none

logging event level to filter

2.5. log.appenders.layout

2.5.1. Layout "pattern"

log:
  level: debug
  appenders:
    - type: file
      file: target/logs/info-only.log
      layout:
        type: pattern
        logFormat: '%c{20}: %m%n'

pattern layout configure log massage as plain text.

Property Default Description

logFormat

%-5p [%d{ISO8601,UTC}] %thread %c{20}: %m%n%rEx

A format of the log lines. See Logback PatternLayout for details.

2.5.2. Layout "json"

json layout generates logs in JSON format. This layout requires additional dependency:

Maven
<dependency>
    <groupId>io.bootique.logback</groupId>
    <artifactId>bootique-logback-json</artifactId>
</dependency>
Gradle
dependencies {
    implementation "io.bootique.logback:bootique-logback-json"
}
log:
  level: debug
  appenders:
    - type: file
      file: target/logs/info-only.log
      layout:
        type: json
        timestampFormat: 'yyyy-MM-dd HH:mm:ss'
        prettyPrint: true
Property Default Description

timestampFormat

yyyy-MM-dd HH:mm:ss.SSS

A format of the timestamp value.

prettyPrint

false

Option for human-readable output.

2.5.3. Layout "html"

log:
  level: debug
  appenders:
    - type: file
      file: target/logs/info-only.html
      layout:
        type: html
        pattern: %date%thread%level%logger%mdc%msg

html layout generates logs in HTML format. See Logback documentation on HTMLLayout for details

Property Default Description

pattern

%date%thread%level%logger%mdc%msg

Each specifier found in the pattern will result in a separate column. Likewise a separate column will be generated for each block of literal text found in the pattern, potentially wasting valuable real-estate on your screen. See Logback PatternLayout

2.5.4. Layout "xml"

log:
  level: debug
  appenders:
    - type: file
      file: target/logs/info-only.xml
      layout:
        type: xml
        locationInfo: true
        properties: true

xml generates logs in Log4j XML format. See Logback XMLLayout

Property Default Description

locationInfo

false

Setting locationInfo to true enables the inclusion of location info (caller data) in the each event.

properties

false

Setting properties to true enables the inclusion of MDC information. Both options are set to false by default.

2.6. log.loggers

log:
  loggers:
    com.foo:
      level: debug
    com.example:
      level: debug

This is a map of logger factories by logger name. Logger name is either a package name (applied recursively to subpackages and their classes) or a class name. Each LoggerFactory has the following properties:

Table 7. Logger Property Reference
Property Default Description

level

info

Log level for a particular logger. Can be off, error, warn, info, debug, trace, all

3. Logback In Unit Tests

Configuring Logback via Bootique works well for applications, as configuration loading happens in the main method before any of the loggers are started. Unit tests is a different environment though. When testing you’d create, start and stop multiple BQRuntimes, each with its own Logback configuration. To provide consistent logging in this situation, it would be wise to disable per-app configuration all together. This can be done by setting useLogbackConfig property to true for each test BQRuntime (thus disabling Bootique configuration). E.g.:

@BQApp
static final BQRuntime app = Bootique.app()
        .autoLoadModules()
        .module(b -> BQCoreModule.extend(b)
                // "useLogbackConfig=true" turns off Bootique config
                .setProperty("bq.log.useLogbackConfig", "true"))
        .createRuntime();

If you need to tweak test logs further, you can use the standard Logback approach - create logback-test.xml file placing it on the test classpath (e.g. under src/test/resources). Here is an example logback-test.xml:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%d{"dd/MMM/yyyy:HH:mm:ss"}] %t %p %c{1}: %m%n%ex</pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
    <logger name="io.bootique.metrics.health.sink.Slf4JReportSink" level="warn"/>
</configuration>

4. Logback Sentry Module

Provides Sentry integration with Bootique-Logback.

4.1. Setup

Get DSN (Data Source Name) from sentry.io or from your own instance of Sentry.

4.2. Add bootique-logback-sentry to your build tool:

Maven
<dependency>
    <groupId>io.bootique.logback</groupId>
    <artifactId>bootique-logback-sentry</artifactId>
</dependency>
Gradle
dependencies {
    implementation "io.bootique.logback:bootique-logback-sentry"
}
bootique-logback-sentry is a part of bootique-bom, and version can be imported from there.

4.3. Write Configuration

config.yml:

log:
  level: warn
  appenders:
    - type: console
      logFormat: '[%d{dd/MMM/yyyy:HH:mm:ss}] %t %-5p %c{1}: %m%n'
    - type: sentry
      dsn: 'your_dsn_here'
      serverName: aurora
      environment: development
      release: 42.0
      extra:
        extra1: value1
        extra2: value2
        extra3: value3
      minLevel: error
      distribution: x86
      applicationPackages:
        - "io.bootique.logback"
        - "com.myapp.package"
      commonFramesEnabled: true
      tags:
        tag1: value1
        tag2: value2

SentryClientFactory can be provided by overriding SentryClientFactory bean from LogbackSentryModule.

Also DSN can be provided via environment variable SENTRY_DSN.