Skip to content

Instantly share code, notes, and snippets.

@OndraZizka
Last active December 1, 2025 03:29
Show Gist options
  • Select an option

  • Save OndraZizka/a7381b8cd86f734bc3b6bf9e528a01ad to your computer and use it in GitHub Desktop.

Select an option

Save OndraZizka/a7381b8cd86f734bc3b6bf9e528a01ad to your computer and use it in GitHub Desktop.
Kotlin SLF4J log message lazy evaluation based on log level
package org.jbake.util
/*
Lazy evaluation of the messages sent to Slf4j.
Usage:
log.trace { "State dump: " + expensiveLongSerialisation(state) }
See also https://jira.qos.ch/browse/SLF4J-371
*/
import org.slf4j.Logger
import org.slf4j.LoggerFactory
inline fun Logger.error(msg: () -> String) { if (this.isErrorEnabled) this.error(msg()) }
inline fun Logger.error(ex: Exception, msg: () -> String) { if (this.isErrorEnabled) this.error(msg(), ex) }
inline fun Logger.warn(msg: () -> String) { if (this.isWarnEnabled) this.warn(msg()) }
inline fun Logger.warn(ex: Exception, msg: () -> String) { if (this.isWarnEnabled) this.warn(msg(), ex) }
inline fun Logger.info(msg: () -> String) { if (this.isInfoEnabled) this.info(msg()) }
inline fun Logger.debug(msg: () -> String) { if (this.isDebugEnabled) this.debug(msg()) }
inline fun Logger.trace(msg: () -> String) { if (this.isTraceEnabled) this.trace(msg()) }
/**
* Top-level function to create a logger for a specific class.
* Use this for companion objects or top-level declarations.
*
* Usage in companion object:
* companion object {
* private val log: Logger by logger(MyClass::class)
* }
*
* Usage at top-level:
* private val log: Logger by logger(MyClass::class)
*/
inline fun <reified T : Any> logger(): Lazy<Logger> = lazy { LoggerFactory.getLogger(T::class.java) }
object Logging {
/**
* Extension function to create a logger using the receiver's class.
* Use this for instance properties within a class.
*
* Usage:
* private val log: Logger by logger()
*/
inline fun <reified R : Any> R.logger(): Lazy<Logger> = lazy { LoggerFactory.getLogger(unwrapCompanionClass(this.javaClass).name) }
}
/**
* Unwraps the companion class to enclosing class given a Java Class.
* In Kotlin, companion objects are compiled to nested classes with the name "Companion".
* This function detects if a class is a companion object and returns the enclosing class instead.
*/
fun <T : Any> unwrapCompanionClass(ofClass: Class<T>): Class<*> {
return if (ofClass.enclosingClass != null && ofClass.simpleName == "Companion") {
ofClass.enclosingClass
} else {
ofClass
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment