
Flexible logging library designed for creating structured log events, leveraging coroutines for asynchronous event dispatch, and supporting high-resolution timestamps. Includes adapters for SLF4J, Spring Boot, and Hexagon frameworks.
Klogging is a pure-Kotlin logging library that aims to be flexible and easy to use. It uses Kotlin idioms for creating loggers and sending log events. It takes advantage of Kotlin coroutines in environments that use them, for example the Ktor asynchronous service framework.
This repository also includes an SLF4J provider and a Spring Boot starter that use Klogging.
See https://klogging.io for more detailed documentation.
Klogging supports JVM versions 8 and above, and Kotlin versions 1.8 and above.
Include Klogging in your project with Gradle:
implementation("io.klogging:klogging:0.11.7")or Maven:
<dependency>
<groupId>io.klogging</groupId>
<artifactId>klogging-jvm</artifactId>
<version>0.11.7</version>
</dependency>Configure logging early in your program startup using the configuration DSL. For simple logging to the console at INFO or higher level (more severe):
fun main() = runBlocking {
loggingConfiguration { ANSI_CONSOLE() }
// ...
}Create a logger attribute for a class, for example by using the Klogging interface for
logging inside
coroutines:
class ImportantStuff : Klogging {
suspend fun cleverAction(runId: String, input: String) = coroutineScope {
launch(logContext("runId" to runId)) {
logger.info { "cleverAction using $input" }
}
}
}Or by using the NoCoLogging interface for logging outside coroutines:
class OtherStuff : NoCologging {
fun funkyAction(input: String) {
logger.info { "funkyAction using $input" }
}
}These examples both call the logger.info function with a lambda whose value is only evaluated
if logger is currently configured to log at INFO level or higher.
If you try out Klogging in a simple command-line program you might not see all the log messages you expect to see. This example will not show the log message on the console:
suspend fun main() = coroutineScope {
loggingConfiguration { ANSI_CONSOLE() }
val logger = logger("main")
logger.info("Hello, world!")
}Klogging works asynchronously and the program completes before log events can be sent. In this case you can add a coroutine delay or thread sleep before the program completes, for example:
suspend fun main() = coroutineScope {
loggingConfiguration { ANSI_CONSOLE() }
val logger = logger("main")
logger.info("Hello, world!")
delay(50)
}Or you can specify that log events with severity above a certain level are sent directly instead of via coroutine channels:
suspend fun main() = coroutineScope {
loggingConfiguration {
ANSI_CONSOLE()
minDirectLogLevel(Level.INFO)
}
val logger = logger("main")
logger.info("Hello, world!")
}See Direct logging for more information.
Klogging is designed primarily for long-running services and applications.
I don’t know a reliable way to trap application shutdown and ensure all logs are sent before shutdown proceeds. Let me know if you do.
If you want to use the latest snapshot builds, specify these in your build.gradle.kts:
repositories {
// ...
maven ("https://central.sonatype.com/repository/maven-snapshots/")
}
dependencies {
// ...
implementation("io.klogging:klogging-jvm:0.12.0-SNAPSHOT")
}NB: The repository for snapshots changed in May 2025, when Klogging started being published via Maven Central Publishing Portal.
Klogging supports Android so it requires Android SDK version 24 or above. Install the Android SDK and either:
ANDROID_HOME environment variable to point to the installation directory; orlocal.properties file in the root directory of the project with the following line:
sdk.dir=/path/to/android/sdk
NB:
local.propertiesis not committed to the repository and may also contain sensitive information.
Run ./gradlew clean build
Klogging is designed from the ground up to be standalone, pure Kotlin and to be used with coroutines.
I could not find a logging library for Kotlin that meets these requirements:
These solid, but venerable Java libraries have formed the backbone of Java logging for more than 10 years. The limitations I find are:
They are designed to log strings of text. When you want to search for or filter logs by values within those messages you need to search within, or parse the strings.
There are add-ons for including structured data in logs, for example Logstash Logback Encoder, but they feel clumsy to use.
MDC (SLF4J/Logback) and ThreadContext (Log4j2) provide storage for context information but scopes are independent of thread lifecycles and need to be managed separately.
Logback is hamstrung by having timestamp resolution limited to milliseconds. This limit is baked
in to the
core of the library:
that long value is milliseconds since the Unix Epoch.
Klogging is a pure-Kotlin logging library that aims to be flexible and easy to use. It uses Kotlin idioms for creating loggers and sending log events. It takes advantage of Kotlin coroutines in environments that use them, for example the Ktor asynchronous service framework.
This repository also includes an SLF4J provider and a Spring Boot starter that use Klogging.
See https://klogging.io for more detailed documentation.
Klogging supports JVM versions 8 and above, and Kotlin versions 1.8 and above.
Include Klogging in your project with Gradle:
implementation("io.klogging:klogging:0.11.7")or Maven:
<dependency>
<groupId>io.klogging</groupId>
<artifactId>klogging-jvm</artifactId>
<version>0.11.7</version>
</dependency>Configure logging early in your program startup using the configuration DSL. For simple logging to the console at INFO or higher level (more severe):
fun main() = runBlocking {
loggingConfiguration { ANSI_CONSOLE() }
// ...
}Create a logger attribute for a class, for example by using the Klogging interface for
logging inside
coroutines:
class ImportantStuff : Klogging {
suspend fun cleverAction(runId: String, input: String) = coroutineScope {
launch(logContext("runId" to runId)) {
logger.info { "cleverAction using $input" }
}
}
}Or by using the NoCoLogging interface for logging outside coroutines:
class OtherStuff : NoCologging {
fun funkyAction(input: String) {
logger.info { "funkyAction using $input" }
}
}These examples both call the logger.info function with a lambda whose value is only evaluated
if logger is currently configured to log at INFO level or higher.
If you try out Klogging in a simple command-line program you might not see all the log messages you expect to see. This example will not show the log message on the console:
suspend fun main() = coroutineScope {
loggingConfiguration { ANSI_CONSOLE() }
val logger = logger("main")
logger.info("Hello, world!")
}Klogging works asynchronously and the program completes before log events can be sent. In this case you can add a coroutine delay or thread sleep before the program completes, for example:
suspend fun main() = coroutineScope {
loggingConfiguration { ANSI_CONSOLE() }
val logger = logger("main")
logger.info("Hello, world!")
delay(50)
}Or you can specify that log events with severity above a certain level are sent directly instead of via coroutine channels:
suspend fun main() = coroutineScope {
loggingConfiguration {
ANSI_CONSOLE()
minDirectLogLevel(Level.INFO)
}
val logger = logger("main")
logger.info("Hello, world!")
}See Direct logging for more information.
Klogging is designed primarily for long-running services and applications.
I don’t know a reliable way to trap application shutdown and ensure all logs are sent before shutdown proceeds. Let me know if you do.
If you want to use the latest snapshot builds, specify these in your build.gradle.kts:
repositories {
// ...
maven ("https://central.sonatype.com/repository/maven-snapshots/")
}
dependencies {
// ...
implementation("io.klogging:klogging-jvm:0.12.0-SNAPSHOT")
}NB: The repository for snapshots changed in May 2025, when Klogging started being published via Maven Central Publishing Portal.
Klogging supports Android so it requires Android SDK version 24 or above. Install the Android SDK and either:
ANDROID_HOME environment variable to point to the installation directory; orlocal.properties file in the root directory of the project with the following line:
sdk.dir=/path/to/android/sdk
NB:
local.propertiesis not committed to the repository and may also contain sensitive information.
Run ./gradlew clean build
Klogging is designed from the ground up to be standalone, pure Kotlin and to be used with coroutines.
I could not find a logging library for Kotlin that meets these requirements:
These solid, but venerable Java libraries have formed the backbone of Java logging for more than 10 years. The limitations I find are:
They are designed to log strings of text. When you want to search for or filter logs by values within those messages you need to search within, or parse the strings.
There are add-ons for including structured data in logs, for example Logstash Logback Encoder, but they feel clumsy to use.
MDC (SLF4J/Logback) and ThreadContext (Log4j2) provide storage for context information but scopes are independent of thread lifecycles and need to be managed separately.
Logback is hamstrung by having timestamp resolution limited to milliseconds. This limit is baked
in to the
core of the library:
that long value is milliseconds since the Unix Epoch.