Technology moves fast! ⚡ Don't get left behind.🚶 Subscribe to our mailing list to keep up with latest and greatest in open source projects! 🏆


Subscribe to our mailing list

scala-logging

Convenient and performant logging library for Scala wrapping SLF4J.

Subscribe to updates I use scala-logging


Statistics on scala-logging

Number of watchers on Github 545
Number of open issues 16
Average time to close an issue 2 months
Main language Scala
Average time to merge a PR 6 days
Open pull requests 8+
Closed pull requests 3+
Last commit over 1 year ago
Repo Created about 6 years ago
Repo Last Updated over 1 year ago
Size 153 KB
Organization / Authorlightbend
Contributors4
Page Updated
Do you use scala-logging? Leave a review!
View open issues (16)
View scala-logging activity
View on github
Fresh, new opensource launches 🚀🚀🚀
Trendy new open source projects in your inbox! View examples

Subscribe to our mailing list

Evaluating scala-logging for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

scala-logging Build Status

Scala Logging is a convenient and performant logging library wrapping SLF4J.

It's convenient, because you can simply call log methods, without checking whether the respective log level is enabled:

logger.debug(s"Some $expensive message!")

It's performant, because thanks to Scala macros the check-enabled-idiom is applied and the following code is generated:

if (logger.isDebugEnabled) logger.debug(s"Some $expensive message!")

Prerequisites

  • Java 6 or higher
  • Scala 2.11 or 2.12
  • Logging backend compatible with SLF4J

A compatible logging backend is Logback, add it to your sbt build definition:

libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.2.3"

If you are looking for a version compatible with Scala 2.10, check out Scala Logging 2.x.

Getting Scala Logging

Scala Logging is published to Sonatype OSS and Maven Central:

  • Group id / organization: com.typesafe.scala-logging
  • Artifact id / name: scala-logging
  • Latest version is 3.8.0

Usage with SBT, adding a dependency to the latest version of Scala Logging to your sbt build definition file:

libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.8.0"

Using Scala Logging

The Logger class from the com.typesafe.scalalogging package wraps an underlying SLF4J logger. In order to create a Logger, you pass a name to the apply factory method defined in the Logger companion object:

val logger = Logger("name")

Or, you pass in a SLF4J logger instance:

val logger = Logger(LoggerFactory.getLogger("name"))

Or, you pass in a class:

val logger = Logger(classOf[MyClass])

Or, using the runtime class wrapped by the implicit class tag parameter:

val logger = Logger[MyClass]

The LazyLogging and StrictLogging traits from the com.typesafe.scalalogging package define the logger member as a lazy or strict value respectively. In both cases the underlying SLF4J logger is named according to the class into which these traits are mixed:

class MyClass extends LazyLogging {
  logger.debug("This is very convenient ;-)")
}

LoggerTakingImplicit provides the same methods as Logger class, but with additional implicit parameter A. During creation of the LoggerTakingImplicit evidence CanLog[A] is required. It may be useful when contextual parameter (e.g. Correlation ID) is being passed around and you would like to include it in the log messages:

case class CorrelationId(value: String)
implicit case object CanLogCorrelationId extends CanLog[CorrelationId] {
  override def logMessage(originalMsg: String, a: CorrelationId): String = s"${a.value} $originalMsg"
}

implicit val correlationId = CorrelationId("ID") 

val logger = Logger.takingImplicit[CorrelationId]("test")
logger.info("Test") // takes implicit correlationId and logs "ID Test"

It's possible to use MDC through CanLog without any troubles with execution context.

case class CorrelationId(value: String)
implicit case object CanLogCorrelationId extends CanLog[CorrelationId] {
  override def logMessage(originalMsg: String, a: CorrelationId): String = {
    MDC.put("correlationId", a.value)
    originalMsg
  }

  override def afterLog(a: A): Unit = {
    MDC.remove("correlationId")
  }
}

implicit val correlationId = CorrelationId("ID") 

val logger = Logger.takingImplicit[CorrelationId]("test")

def serviceMethod(implicit correlationId: CorrelationId): Future[Result] = {
  dbCall.map { value => 
    logger.trace(s"Received value $value from db") // takes implicit correlationId
    toResult(value)
  }
}

What's new?

3.8.0

  • Added LoggerTakingImplicit, bugfixes.

3.7.2

  • Make logger to consume args of type Any with slf4 interpolator.

3.7.1

  • Remove @volatile from lazy logger, failing with strict compiler settings
3.7.0
  • Deconstruct Scala's string interpolation into SLF4J string interpolation.
3.6.0 - flawed release
3.5.0
  • More Logger factory methods, bugfixes and upgrades, published for Scala 2.12.0-M5, 2.12.0-RC1, 2.12.0-RC2 and 2.12.0.
3.4.0
  • Fixes #38 - Logger.info() cannot be used with primitive types.
3.3.0
  • Fixes #42 - Request: Add Logger(class). README changes.
3.2.0
  • SLF4J loggers and our Logger now survive serialization. By survive serialization, we mean that the deserialized logger instances are fully functional.

String Interpolation

It is idiomatic to use Scala's string interpolation logger.error(s"log $value") instead of SLF4J string interpolation logger.error("log {}", value). However there are some tools (such as Sentry) that use the log message format as grouping key. Therefore they do not work well with Scala's string interpolation.

Scala Logging replaces simple string interpolations with their SLF4J counterparts like this:

logger.error(s"my log message: $arg1 $arg2 $arg3")
logger.error("my log message: {} {} {}", arg1, arg2, arg3)

This has no effect on behavior and performace should be comparable (depends on the underlying logging library).

Limitations

  • Works only when string interpolation is directly used inside the logging statement. That is when the log message is static (available at compile time).
  • Works only for the logger.<level>(message) and logger.<level>(marker, message) logging methods. It does not work if you want to log an exception and use string interpolation too (this is a limitation of the SLF4J API).

Line numbers in log message?

Using the sourcecode library, it's possible to add line number information (especially useful for debugging):

def foo(arg: String)(implicit line: sourcecode.Line, file: sourcecode.File) = {
  ... do something with arg ...
  ... do something with file.value ...
}

foo("hello") // the implicit sourcecode.File is filled in automatically

Debugging Scala in IntelliJ

Check out scala-trace-debug to make multithreaded bug tracing and prevention easier than ever. Provides user-friendly prints, traces, assertions, container printing, and source code printing.

Logstash

Check out logstash-logback-encoder if you're using Logstash. Provides logback encoders, layouts, and appenders to log in JSON format.

Other noteworthy tooling

  • https://github.com/godaddy/godaddy-logger

Maintainer

The original author Heiko Seeberger stepped down Q1 2015, starting a new adventure at codecentric. Future maintenance is taken over by Mathias Bogaert.

Contribution policy

Contributions via GitHub pull requests are gladly accepted from their original author. Before we can accept pull requests, you will need to agree to the Typesafe Contributor License Agreement online, using your GitHub account.

License

This code is open source software licensed under the Apache 2.0 License.

scala-logging open issues Ask a question     (View All Issues)
  • almost 3 years [3.5.0] java.lang.NoClassDefFoundError: com/typesafe/scalalogging/Logger
  • over 3 years Add pretty printing?
  • over 3 years Custom logger
  • almost 4 years Use scala-logging in a macro?
  • about 4 years Examples of unit testing components that use Strict/LazyLogging
  • over 4 years Ease parallel support of scala 2.10 and scala 2.11
scala-logging open pull requests (View All Pulls)
  • Add possibility to create custom loggers
  • LazyLogging and StrictLogging now have @transient logger
  • Add kestrel logging
  • added: support for scala 2.10
  • Implicit logging
  • Adding Compliant Logger
  • check scalariform in travis
  • Added Logger that takes an implicit parameter (e.g. CorrelationId)
scala-logging questions on Stackoverflow (View All Questions)
  • Play Scala Logging delayed log message with string interpolation
  • Complete "Scala Logging" Example
  • Setting up scala-logging in a sbt module application
  • How to implement scala logging for a scala project?
  • scala logging function name
  • Scala logging line numbers - slf4s/slf4j?
  • performance in scala logging libraries call-by-value vs call-by-name
scala-logging list of languages used
Other projects in Scala