Skip to content
oshai edited this page Aug 23, 2018 · 43 revisions

Welcome to the kotlin-logging wiki!

kotlin-logging is a lightweight logging framework for Kotlin. A convenient and performant logging library wrapping slf4j with Kotlin extensions kotlin-logging provides both:

  • Idiomatic way to obtain a logger without the need to specify class name
  • Enhanced logging api that integrates fluently with Kotlin

Install

Important note: kotlin-logging depends on slf4j-api. At runtime, it is also required to depend on a logging implementation. More details here.

Maven

<dependency>
  <groupId>io.github.microutils</groupId>
  <artifactId>kotlin-logging</artifactId>
  <version>1.5.9</version>
</dependency>

See full example in kotlin-logging-example-maven.

Gradle

compile 'io.github.microutils:kotlin-logging:1.5.9'

Or alternatively, download jar from github or bintray or maven-central.

Usage

Obtaining a logger

The preferred way to obtain a logger is as follows:

// Place definition above class declaration, below imports, 
// to make field static and accessible only within the file

private val logger = KotlinLogging.logger {}

Another option (less recommended) is to is to have the Companion object extends KLogging():

companion object: KLogging()

In cases the Companion object already extending other class it is recommended to implement the KLoggable interface:

companion object: Any(), KLoggable {
  override val logger = logger()
  ...
}

Other (less recommended) alternatives are:

companion object: Any(), KLoggable by NamedKLogging("com.MyClass")

Or implementing it as a non static member:

class ClassHasLogging: KLoggable {
    override val logger = logger()
}

all examples also available in tests.

Usage of logger

The most simple use is the same as with java logger:

logger.info("hello message")

For sequences that are expected to be frequently used or costly prefer lazily evaluated messages:

logger.debug { "lazy evaluated $hello message" }

(Message is in lambda and gets evaluated only if debug log level is enabled at runtime)

When logging exceptions, it is also possible to use a lambda expression to calculate the attached message:

logger.error(exception) { "a $fancy message about the $exception" }

The complete list of methods can be found in KLogger source code.

Mapped Diagnostic Context (MDC) Support

MDC allows adding implicit context data such as user id to all log messages base on the caller thread. More details can be found on https://www.slf4j.org/manual.html#mdc.

In kotlin-logging it is possible to set MDC properties to be used later in a lambda that way:

import mu.withLoggingContext

...

withLoggingContext("userId" to userId) {
  doSomething()
}

Providing multiple values is also supported. See: KotlinLoggingMDC source code.

MDC and threads/coroutines

Under the hood, MDC uses ThreadLocal value to keep the content on the thread. When using thread pools or coroutines the data should be transported between the threads. Coroutines have support for it in the following way:

withLoggingContext("kotlin" to "the moon") {
  launch(MDCContext()) {
    logger.info { "..." }   // the MDC context will contain the mapping here
  }
}
  • In order to use it add the following additional dependency: compile "org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:<version>". More details in kotlinx-coroutines-slf4j.

Getting the actual Logger

In some cases, it is essential to get the actual Logger to use its specific features. In such cases use the underlyingLogger property like that:

logger.underlyingLogger

More details and examples here: https://github.com/MicroUtils/kotlin-logging/issues/20

FAQ

Q: Is method line reporting supported?

A: Yes. More details here: https://github.com/MicroUtils/kotlin-logging/issues/11

Q: Are colored logs supported?

A: As with other framework specific features it is supported and should be configured in the logging framework itself. More details here: https://github.com/MicroUtils/kotlin-logging/issues/24