How to log output to a file in a Scala application with Grizzled-SLF4J

At the moment it’s not easy to find instructions on how to log output to a file using Grizzled-SLF4J in a Scala application, so I’m taking a few moments to show how this is done.

Grizzled-SLF4J dependencies

First, assuming that you’re using SBT, your build.sbt file should look like this:

name := "GrizzledSLF4JTests"

version := "1.0"

scalaVersion := "2.10.3"

libraryDependencies ++= Seq("org.slf4j" % "slf4j-api" % "1.7.5",
                            "org.slf4j" % "slf4j-simple" % "1.7.5",
                            "org.clapper" %% "grizzled-slf4j" % "1.0.2")

That takes care of your dependencies.

SLF4J properties file

Next, you need to put an SLF4J properties file somewhere on your classpath. When using SBT you can just put a file named simplelogger.properties in your src/main/resources folder. The file should have contents like this:

org.slf4j.simpleLogger.logFile         = /tmp/myapp.log
org.slf4j.simpleLogger.defaultLogLevel = info
org.slf4j.simpleLogger.showDateTime    = true
org.slf4j.simpleLogger.dateTimeFormat  = yyyy'/'MM'/'dd' 'HH':'mm':'ss'-'S
org.slf4j.simpleLogger.showThreadName  = true
org.slf4j.simpleLogger.showLogName     = true
org.slf4j.simpleLogger.showShortLogName= false
org.slf4j.simpleLogger.levelInBrackets = true

The first line shows that you want to log your output to a file named /tmp/myapp.log. All of the other lines are boilerplate SLF4J configuration lines. If you want to log output to your console, use System.err instead of the path to your file (or, as shown below, leave this field blank and it will default to System.err).

(Note: I copied this properties file from this link on Blue Collar Programming, and changed the first line.)

SLF4J logging configuration parameters

For more information on these logging configuration parameters, see the documentation for the SLF4J SimpleLogger class. For your convenience the logging properties are copied from that doc and shown here:

logFile          - The output target which can be the path to a file, or the special values "System.out" 
                   and "System.err". Default is "System.err".

defaultLogLevel  - Default log level for all instances of SimpleLogger. Must be one of ("trace", "debug", 
                   "info", "warn", or "error"). If not specified, defaults to "info".

log.a.b.c        - Logging detail level for a SimpleLogger instance named "a.b.c". Right-side value must 
                   be one of "trace", "debug", "info", "warn", or "error". When a SimpleLogger named 
                   "a.b.c" is initialized, its level is assigned from this property. If unspecified, the 
                   level of nearest parent logger will be used, and if none is set, then the value specified 
                   by org.slf4j.simpleLogger.defaultLogLevel will be used.

showDateTime     - Set to true if you want the current date and time to be included in output messages. 
                   Default is true

dateTimeFormat   - The date and time format to be used in the output messages. The pattern describing the 
                   date and time format is defined by SimpleDateFormat. If the format is not specified or 
                   is invalid, the number of milliseconds since start up will be output.

showThreadName   - Set to true if you want to output the current thread name. Defaults to true.

showLogName      - Set to true if you want the Logger instance name to be included in output messages. 
                   Defaults to true.

showShortLogName - Set to true if you want the last component of the name to be included in output messages.
                   Defaults to false.

levelInBrackets  - Should the level string be output in brackets? Defaults to false.

warnLevelString  - The string value output for the warn level. Defaults to WARN.

If you just needed to see how to configure Grizzled-SLF4J to log its output to a log file, that’s probably all you needed to see. If you want to see how to configure Grizzled-SLF4J in your Scala classes, read on.

Grizzled-SLF4J logging in Scala classes

There are several ways to configure a Grizzled-SLF4J logger in your Scala classes. First, you can give Grizzled the name of your Scala class, although frankly this is a manual and old-school approach:

// Foo1.scala

package com.alvinalexander.logging

import grizzled.slf4j.Logger

/**
 * Use the `Logger`, manually giving it a class name.
 */
object Foo1 extends App {
    val logger = Logger("com.alvinalexander.logging.Foo1")
    logger.info("Hello, world")
}

A better way to configure Grizzled-SLF4J in your Scala class is to give Grizzled your class:

// Foo2.scala

package com.alvinalexander.logging

import grizzled.slf4j.Logger

// need a class for the use below, so i'm using the "companion object" approach
class Foo2

/**
 * Use the `Logger`, giving it our class.
 */
object Foo2 extends App {
    val logger = Logger(classOf[Foo2])
    logger.info("Hello, world")
}

That’s certainly better than the first approach. I think the best approach is to extend the Grizzled Logging trait, like this:

// Foo3.scala
package com.alvinalexander.logging

import grizzled.slf4j.Logging

/**
 * Extend the `Logging` trait, then call methods like `info`
 * directly.
 */
object Foo3 extends App with Logging {
    info("Hello, world")
}

Note that when you do this you can just call methods like info directly, you don’t have to write log.info().

I keep showing the info method, but Grizzled-SLF4J has these logging methods:

debug
error
info
trace
warn

See the Grizzled-SLF4J documentation for more information on these methods.

Summary

If you needed to see an example of how to log output to a file using Grizzled-SLF4J, or perhaps with SLF4J alone, I hope this tutorial has been helpful. As shown, the key is knowing about the simplelogger.properties file and the parameters you can specify in that file.