-
-
Notifications
You must be signed in to change notification settings - Fork 116
Home
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
Important note: kotlin-logging depends on slf4j-api. At runtime, it is also required to depend on a logging implementation. More details here.
<dependency>
<groupId>io.github.microutils</groupId>
<artifactId>kotlin-logging</artifactId>
<version>1.5.9</version>
</dependency>
See full example in kotlin-logging-example-maven.
compile 'io.github.microutils:kotlin-logging:1.5.9'
Or alternatively, download jar from github or bintray or maven-central.
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.
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.
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.
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.
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
A: Yes. More details here: https://github.com/MicroUtils/kotlin-logging/issues/11
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
Q: What is the minimal Gradle dependency that I need in order for kotlin-logging to work and print my messages?
A: See below, versions might change:
implementation 'io.github.microutils:kotlin-logging:1.7.4'
implementation 'org.slf4j:slf4j-simple:1.7.26'
A: In most cases the below setting for the logger should work:
companion object {
private val logger = KotlinLogging.logger {}
}
See more details in #115.
A: By default it will log a message saying: Log message invocation failed: ...
In JVM, it is possible to change it to throw an exception by adding system property to jvm args -Dkotlin-logging.throwOnMessageError
More details on #160.
A: Setting log level globally is done (for jvm projects / android) in the underlying logging framework (log4j, logbck etc').
An example how to do that for logback:
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
var mu.KLogger.level
get() = (underlyingLogger as Logger).level
set(value) { (underlyingLogger as Logger).level = value }
logger.level = Level.DEBUG
logger.level //=> Level.DEBUG
Something similar can be done for log4j, see answers here.
For other platforms it can be set like that:
KotlinLoggingConfiguration.LOG_LEVEL = KotlinLoggingLevel.ERROR;
See dedicated wiki for that.