ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Follow publication

Kotlin Tips and Tricks You May Not Know: #1 — Kotlin Logging

Elena van Engelen - Maslova
ProAndroidDev
Published in
6 min readSep 10, 2024

Introduction

What is Kotlin-Logging?

dependencies {
implementation("io.github.oshai:kotlin-logging-jvm:7.0.0")
implementation("org.slf4j:slf4j-api:2.0.16")
implementation("ch.qos.logback:logback-classic:1.5.11")
}

Idiomatic Logging in Kotlin

import io.github.oshai.kotlinlogging.KotlinLogging

private val logger = KotlinLogging.logger {}

fun main() {
val compliment = "Great job"
logger.debug { "Generating compliment: $compliment" } // Lazy evaluation, only executed if the log level is enabled
logger.info { "Compliment generated: $compliment" } // Lazy evaluation, only executed if the log level is enabled
}

Handling Exceptions in Kotlin-Logging

try {
// Some risky code
} catch (e: Exception) {
logger.error(e) { "An error occurred during execution" } // Logs both the exception and a message
}
logger.error("An error occurred during execution", e);

Adding Metadata

Structured Logging

import io.github.oshai.kotlinlogging.KotlinLogging

private val logger = KotlinLogging.logger {}

fun processOrder(order: Order) {
// process order
// something failed
logException(order, Exception("Order processing exception"))
}

fun logException(order: Order, t: Throwable) {
logger.atError {
message = "Order processing failed"
cause = t
payload = buildMap(capacity = 2) {
put("customerId", order.customerId)
put("orderId", order.orderId)
}
}
}

fun main() {
processOrder(Order("C123", "O98765"))
}

data class Order(val customerId: String, val orderId: String)
10:04:48.685 [main] ERROR LoggingExample -customerId="C123" orderId="O98765"- Order processing failed
java.lang.Exception
: Order processing exception
at LoggingExampleKt.processOrder(LoggingExample.kt:12)
at LoggingExampleKt.main(LoggingExample.kt:27)
at LoggingExampleKt.main(LoggingExample.kt)

Mapped Diagnostic Context (MDC)

import io.github.oshai.kotlinlogging.KotlinLogging
import io.github.oshai.kotlinlogging.withLoggingContext

private val logger = KotlinLogging.logger {}

fun processOrder(order: Order) =
withLoggingContext("customerId" to order.customerId, "orderId" to order.orderId) {
// process order
// something failed
logException(Exception("Order processing exception"))
}

// no need to repeat order details for every log line
fun logException(t: Throwable) {
logger.error (t) { "Order processing failed" }
}

fun main() {
processOrder(Order("C123", "O98765"))
}

data class Order(val customerId: String, val orderId: String)
<configuration>

<!-- Console appender for logging to the console -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- Use %X to include all MDC key-value pairs -->
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %X - %msg%n</pattern>
</encoder>
</appender>

<!-- Root logger configuration -->
<root level="info">
<appender-ref ref="STDOUT" />
</root>

</configuration>
10:08:37.070 [main] ERROR LoggingExampleMDC - customerId=C123, orderId=O98765 - Order processing failed
java.lang.Exception
: Order processing exception
at LoggingExampleMDCKt.processOrder(LoggingExampleMDC.kt:12)
at LoggingExampleMDCKt.main(LoggingExampleMDC.kt:21)
at LoggingExampleMDCKt.main(LoggingExampleMDC.kt)

MDC and Coroutines

import io.github.oshai.kotlinlogging.KotlinLogging
import io.github.oshai.kotlinlogging.withLoggingContext
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.launch
import kotlinx.coroutines.slf4j.MDCContext

private val logger = KotlinLogging.logger {}
fun main() = runBlocking {
withLoggingContext("customerId" to "C123", "orderId" to "O98765") {
launch(MDCContext()) {
logger.info { "Starting coroutine for order processing" }
// Simulate order processing
logger.info { "Order processed with status: Shipped" }
}
}
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:<version>")
}

Additional Information

Conclusion

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Responses (2)

Write a response