Skip to content

Latest commit

 

History

History
219 lines (155 loc) · 5.25 KB

README.md

File metadata and controls

219 lines (155 loc) · 5.25 KB

SLF4K

Build Status MIT license Maven Central Pure Kotlin Discord Server

Simple Logging Facade for Kotlin is a set of Kotlin extension for SLF4J.

Features

  • Use kotlin features to cleanly get the appropriate logger for your class
  • Clean up kotlin class names to make logging easy to understand
  • Typed logger delegates: a logger instantiated using a class reference is only valid in that class
  • Lazy logger instantiation & logger cache

Including

You can include SLF4K in your project by adding the following:

Maven

<dependency>
  <groupId>ca.solo-studios</groupId>
  <artifactId>slf4k</artifactId>
  <version>0.5.3</version>
</dependency>

Gradle Groovy DSL

implementation 'ca.solo-studios:slf4k:0.5.3'

Gradle Kotlin DSL

implementation("ca.solo-studios:slf4k:0.5.3")

SLF4J 2.0.0

The current version of SLF4K should be compatible with all versions that are greater than 2.0.0. However, it should still work with versions lower than 2.0.0, so long as you don't use the Fluent Logging extensions.

Examples

Getting a Logger

How to get a logger:

Top Level

import org.slf4j.kotlin.toplevel.getLogger


val logger by getLogger()

Class

import org.slf4j.kotlin.getLogger


class MyClass {
    private val logger by getLogger() // or getLogger(MyClass::class)
}

Named Logger

val logger by getLogger("name of logger here")

Logging

SLF4K uses lazy log message evaluation to avoid expensive logging messages when they're not needed.

When you write the following:

logger.info { "expensive message: $someVariable" }

this code gets transformed at compiled time and inlined into:

if (logger.info)
    logger.info("expensive message: $someVariable")

This way, the expensive message is only evaluated if the info log level is enabled.

Extensions have also been provided for every combination of level and argument. So, you can log errors as needed:

logger.warn(exception) { "message" }

Using markers

Markers can also be really easily instantiated, as follows:

val myMarker = getMarker("MY_MARKER")

after which, they can be used normally.

Fluent Logging

The fluent logging api introduced in version 2.0.0 is also supported by SLF4K, here are some examples of how it can be used:

logger.atInfo {
    message = "my message that uses string interpolation. Here is someArgument: $someArgument"
}
// equivalent to
logger.info { "my message that uses string interpolation. Here is someArgument: $someArgument" }

Arguments:

logger.atInfo {
    message = "my message here. someArgument: {} someOtherArgument: {}"
    arguments = listOf(someArgument, someOtherArgument)
}
// equivalent to
logger.info { "here is someArgument: $someArgument and here is someOtherArgument: $someOtherArgument" }

Key-values:

logger.atInfo {
    message = "my message here."
    keyValues = listOf("someArgument" to someArgument, "someOtherArgument" to someOtherArgument)
}
// equivalent to
logger.info { "someArgument=$someArgument someOtherArgument=$someOtherArgument my message here." }

Markers:

logger.atInfo {
    message = "my message here."
    // You can also provide several markers in the list
    markers = listOf(myMarker)
}
// equivalent to
logger.info(myMarker) { "my message here." }

Errors:

try {
    // do something that might thrown an exception
} catch (e: RuntimeException) {
    logger.atError {
        cause = e
        message = "my error message here"
    }
    // equivalent to
    logger.error(e) { "my error message here" }
}

MDC with Coroutines

To pass MDC context between kotlinx coroutines, use kotlinx-coroutines-slf4j:

Including

Maven

<dependency>
  <groupId>org.jetbrains.kotlinx</groupId>
  <artifactId>kotlinx-coroutines-slf4j</artifactId>
  <version>$kotlinxCoroutinesVersion</version>
</dependency>

Gradle Groovy DSL

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:$kotlinxCoroutinesVersion'

Gradle Kotlin DSL

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:$kotlinxCoroutinesVersion")

Usage

You can propagate the MDC context through coroutines as follows:

MDC.put("kotlin", "rocks") // put a value into the MDC context

launch(MDCContext()) {
   logger.info { "..." }   // the MDC context will contain the mapping here
}