Documentation

You are viewing the documentation for the 2.3.x release series. The latest stable release series is 3.0.x.

§Configuring logging

Play uses Logback as its logging engine, see the Logback documentation for details on configuration.

§Default configuration

Play uses the following default configuration:

<configuration>
    
  <conversionRule conversionWord="coloredLevel" converterClass="play.api.Logger$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 %n%message%n%xException%n</pattern>
     </encoder>
   </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%coloredLevel %logger{15} - %message%n%xException{5}</pattern>
    </encoder>
  </appender>
  
  <logger name="play" level="INFO" />
  <logger name="application" level="DEBUG" />
  
  <!-- Off these ones as they are annoying, and anyway we manage configuration ourself -->
  <logger name="com.avaje.ebean.config.PropertyMapLoader" level="OFF" />
  <logger name="com.avaje.ebeaninternal.server.core.XmlConfigLoader" level="OFF" />
  <logger name="com.avaje.ebeaninternal.server.lib.BackgroundThread" level="OFF" />
  <logger name="com.gargoylesoftware.htmlunit.javascript" level="OFF" />

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

This specifies a file appender writing to logs/application.log, a console appender, and log levels for the root/play/application loggers.

§Configuring log levels in application.conf

You can override log levels in application.conf as follows:

# Root logger:
logger.root=ERROR

# Logger used by the framework:
logger.play=INFO

# Logger provided to your application:
logger.application=DEBUG

# Logger for a third party library
logger.org.springframework=INFO

§Custom configuration

For any custom configuration beyond log levels, you will need to specify your own Logback configuration file.

Note: Log level configuration in application.conf will also override custom configuration. It is best to remove these properties when using a Logback configuration file to avoid confusion.

§Using a configuration file from project source

If you create a configuration file at either conf/application-logger.xml or conf/logger.xml, Play will use this instead of the default configuration.

§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 conf 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

Specify a configuration file to be loaded from the classpath:

$ start -Dlogger.resource=prod-logger.xml

§Using -Dlogger.file

Specify a configuration file to be loaded from the file system:

$ start -Dlogger.file=/opt/prod/logger.xml

§Using -Dlogger.url

Specify a configuration file to be loaded from an URL:

$ start -Dlogger.url=http://conf.mycompany.com/logger.xml

§Examples

Here’s an example of configuration that would work well in a production environment:

<configuration>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${user.dir}/web/logs/application.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- Daily rollover with compression -->
            <fileNamePattern>application-log-%d{yyyy-MM-dd}.gz</fileNamePattern>
            <!-- keep 30 days worth of history -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss ZZZZ} - [%level] - from %logger in %thread %n%message%n%xException%n</pattern>
        </encoder>
    </appender>
    
    <appender name="ACCESS_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${user.dir}/web/logs/access.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover with compression -->
            <fileNamePattern>access-log-%d{yyyy-MM-dd}.gz</fileNamePattern>
            <!-- keep 1 week worth of history -->
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss ZZZZ} %message%n</pattern>
            <!-- this quadruples logging throughput -->
            <immediateFlush>false</immediateFlush>
        </encoder>
    </appender>

    <!-- additivity=false ensures access log data only goes to the access log -->
    <logger name="access" level="INFO" additivity="false">
        <appender-ref ref="ACCESS_FILE" />
    </logger>
    
    <root level="INFO">
        <appender-ref ref="FILE"/>
    </root>

</configuration>

This demonstrates a few useful features:
- It uses RollingFileAppender which can help manage growing log files.
- It writes log files to a directory external to the application so they aren’t affected by upgrades, etc.
- The FILE appender uses an expanded message format that can be parsed by third party log analytics providers such as Sumo Logic.
- The access logger is routed to a separate log file using the ACCESS_FILE_APPENDER.
- All loggers are set to a threshold of INFO which is a common choice for production logging.

NOTE: Logback uses blocking appenders by default. If you wish to use a non-blocking appender, then AsyncAppender is a good choice, but it is configured to “lose” debug messages when the queue is full, for a performance increase.

§Akka logging configuration

Akka has its own logging system which may or may not use Play’s underlying logging engine depending on how it is configured.

By default, Akka will ignore Play’s logging configuration and print log messages to STDOUT using its own format. You can configure the log level in application.conf:

akka {
  loglevel="INFO"
}

To direct Akka to use Play’s logging engine, you’ll need to do some careful configuration. First add the following config in application.conf:

akka {
  loggers = ["akka.event.slf4j.Slf4jLogger"]
  loglevel="DEBUG"
}

A couple things to note:

Next, refine your Akka logging settings in your Logback configuration:

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

You may also wish to configure an appender for the Akka loggers that includes useful properties such as thread and actor address. See the logging page in the Akka documentation for details on Logback configuration and other useful information.

Next: Configuring gzip encoding


Found an error in this documentation? The source code for this page can be found here. After reading the documentation guidelines, please feel free to contribute a pull request. Have questions or advice to share? Go to our community forums to start a conversation with the community.