Configuring Logging

§Configuring Logging

Lagom uses SLF4J for logging, backed by Logback as its default logging engine. See the Logback documentation for details on configuration.

§Default configuration

If you don’t provide your own Logback configuration, Lagom uses the following default configuration in development:

<!--
  ~ Copyright (C) 2016 Lightbend Inc. <http://www.lightbend.com>
  -->
<!-- The default logback configuration that Lagom uses in dev mode if no other configuration is provided -->
<configuration>

  <conversionRule conversionWord="coloredLevel" converterClass="com.lightbend.lagom.internal.logback.ColoredLevel" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <file>${application.home:-.}/logs/application.log</file>
     <encoder>
       <pattern>%date [%level] from %logger in %thread - %message%n%xException</pattern>
     </encoder>
   </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
    </encoder>
  </appender>
  
  <!-- Set logging for all Play library classes to INFO -->
  <logger name="play" level="WARN" />
  <!-- Set logging for all Akka library classes to WARN -->
  <logger name="akka" level="WARN" />
  <!-- Set logging for all Lagom library classes to WARN -->
  <logger name="com.lightbend.lagom" level="WARN" />
  <!-- Cassandra and the datasta driver are used by the Lagom event sourcing modules -->
  <logger name="org.apache.cassandra" level="ERROR" />
  <logger name="com.datastax.driver" level="ERROR" />
  <!-- Turning off connection error logging to avoid noise when services are forcely stopped -->
  <logger name="com.datastax.driver.core.ControlConnection" level="OFF" />

  <root level="INFO">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="FILE" />
  </root>
  
</configuration>

While it uses the following one in production:

<!--
  ~ Copyright (C) 2016 Lightbend Inc. <http://www.lightbend.com>
  -->
<!-- The default logback configuration that Lagom uses if no other configuration is provided -->
<configuration>
    
  <conversionRule conversionWord="coloredLevel" converterClass="com.lightbend.lagom.internal.logback.ColoredLevel" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <file>${application.home:-.}/logs/application.log</file>
     <encoder>
       <pattern>%date [%level] from %logger in %thread - %message%n%xException</pattern>
     </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
    </encoder>
  </appender>

  <appender name="ASYNCFILE" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE" />
  </appender>

  <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="STDOUT" />
  </appender>

  <!-- Set logging for all Play library classes to INFO -->
  <logger name="play" level="WARN" />
  <!-- Set logging for all Akka library classes to WARN -->
  <logger name="akka" level="WARN" />
  <!-- Set logging for all Lagom library classes to WARN -->
  <logger name="com.lightbend.lagom" level="WARN" />
  <!-- Cassandra and the datasta driver are used by the Lagom event sourcing modules -->
  <logger name="org.apache.cassandra" level="ERROR" />
  <logger name="com.datastax.driver" level="ERROR" />

  <root level="WARN">
    <appender-ref ref="ASYNCFILE" />
    <appender-ref ref="ASYNCSTDOUT" />
  </root>
  
</configuration>

A few things to note:

  • A file appender that writes to logs/application.log is declared.
  • The file logger logs full exception stack traces, while the console logger only logs 10 lines of an exception stack trace.
  • Lagom uses ANSI color codes by default in level messages.
  • In production, Lagom puts both the console and the file logger behind the logback AsyncAppender. For details on the performance implications on this, see this blog post.

§Custom configuration

For any custom configuration, you need to provide your own Logback configuration file.

§Using a configuration file from project source

You can provide a default logging configuration by creating a logback.xml file in the project’s resource folder. Furthermore, for testing purposes, you can also create a logback-test.xml and place it in the src/test/resources directory of your project. When both logback.xml and logback-test.xml are in the classpath, the latter has higher precedence.

§Using an external configuration file

You can also specify a configuration file via a System property. This is particularly useful for production environments where the configuration file may be managed outside of your application source.

Note: The logging system gives top preference to configuration files specified by system properties, secondly to files in the resource directory, and lastly to the default. This allows you to customize your application’s logging configuration and still override it for specific environments or developer setups.

§Using -Dlogger.resource

To specify a configuration file to be loaded from the classpath use the system property -Dlogger.resource, e.g., -Dlogger.resource=prod-logger.xml.

§Using -Dlogger.file

To specify a configuration file to be loaded from the file system use the system property -Dlogger.file, e.g., -Dlogger.file=/opt/prod/logger.xml.

§Play Lagom applications

When integrating a Play application in Lagom via the LagomPlay sbt plugin, the default Play logging module is used. The main difference, with respect to the Lagom logging module, is that the Play logging module provides different default logback configurations. Read the Play framework Configuring Logging documentation for details.

§Internal framework logging

It can be useful at times to gain more visibility on what’s happening inside Lagom.

§Lagom logging configuration

Lagom system logging can be done by changing the com.lightbend.lagom logger to DEBUG.

<!-- Set logging for all Lagom library classes to DEBUG -->
<logger name="com.lightbend.lagom" level="DEBUG" />

§Akka logging configuration

Akka system logging can be done by changing the akka logger to DEBUG.

<!-- Set logging for all Akka library classes to DEBUG -->
<logger name="akka" level="DEBUG" />
<!-- Set a specific actor to DEBUG -->
<logger name="actors.MyActor" level="DEBUG" />

And, you will also need to add the following in your project’s application.conf:

akka.loglevel=DEBUG

Furthermore, you may also wish to configure an appender for the Akka loggers that includes useful properties such as thread and actor address. For more information about configuring Akka’s logging, including details on Logback and Slf4j integration, see the Akka documentation.

§Play logging configuration

Play system logging can be done by changing the play logger to DEBUG.

<!-- Set logging for all Play library classes to DEBUG -->
<logger name="play" level="DEBUG" />

§Using a Custom Logging Framework

Lagom uses Logback by default, but it is possible to configure Lagom to use another logging framework, as long as there is an SLF4J adapter for it. To do this, the LagomLogback sbt plugin must be disabled using disablePlugins:

lazy val portfolioImpl = (project in file("portfolioImpl"))
  .enablePlugins(LagomJava)
  .disablePlugins(LagomLogback) // this avoids that the Lagom logging module is addedd to the classpath

From there, a custom logging framework can be used. Here, Log4J 2 is used as an example.

lazy val portfolioImpl = (project in file("portfolioImpl"))
  .enablePlugins(LagomJava)
  .disablePlugins(LagomLogback) // this avoids that the Lagom logging module is addedd to the classpath
  .settings(
    libraryDependencies ++= Seq(
      "org.apache.logging.log4j" % "log4j-slf4j-impl" % "2.4.1",
      "org.apache.logging.log4j" % "log4j-api" % "2.4.1",
      "org.apache.logging.log4j" % "log4j-core" % "2.4.1"
    )
  )

Once the libraries and the SLF4J adapter are loaded, the log4j.configurationFile system property can be set on the command line as usual.

Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.