Skip to content
A logger facilitating lazily-evaluated log calls via Kotlin's inline classes & functions.
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
gradle/wrapper Initial commit Jun 8, 2019
src Add JVM tests Jun 8, 2019
.editorconfig
.gitignore Initial commit Jun 8, 2019
.travis.yml Initial commit Jun 8, 2019
LICENSE Correct year in copyright notice Jun 8, 2019
README.md Remove redundant imports in decompiled Java Jun 8, 2019
build.gradle.kts Ensure all jar artifacts are created before bintray upload Jun 9, 2019
gradle.properties Add kotlin.code.style to gradle.properties Jun 8, 2019
gradlew Initial commit Jun 8, 2019
gradlew.bat Initial commit Jun 8, 2019
replacewith-example.gif Initial commit Jun 8, 2019
settings.gradle.kts Initial commit Jun 8, 2019

README.md

kotlin-inline-logger

Release Build Status License

A logger facilitating lazily-evaluated log calls via Kotlin's inline classes & functions.

Installation

repositories {
    maven { url = 'https://dl.bintray.com/michaelbull/maven' }
}

dependencies {
    compile 'com.michael-bull.kotlin-inline-logger:kotlin-inline-logger-jvm:1.0.0'
}

Introduction

kotlin-inline-logger has been structured as a multiplatform project. Currently the only implementation supports the JVM, utilising SLF4J, however in future other platforms can also be supported by implementing the necessary platform-specific APIs found in src/commonMain.

If you would like to implement support for a platform, please don't hesitate to open a pull request on GitHub.

JVM

On the JVM, kotlin-inline-logger provides inline functions that delegate to SLF4J. Users migrating from an existing SLF4J solution will find existing calls to logging functions like logger.info("Example") now marked as @Deprecated, prompting them to replace their existing code with the lazily-evaluated alternatives.

ReplaceWith example

Creating loggers

By default, passing no argument when creating an InlineLogger() will utilise MethodHandles.lookup(), introduced in JDK7, to derive the name of the logger from the class that created it. This is described in SLF4J's documentation as an idiomatic method of declaring a logger that is resistant to cut-and-paste errors:

class TransactionExecutor {
    val transactionLogger = InlineLogger() // named com.package.TransactionExecutor
}

Named loggers can be created by passing a String:

val transactionLogger = InlineLogger("DatabaseTransactions")

Class loggers can be created by passing a ::class reference:

class TransactionExecutor

val transactionLogger = InlineLogger(TransactionExecutor::class)

Effectiveness

The code examples below illustrate how the Kotlin you write is compiled to interoperable Java, demonstrating how the expensiveCalculation() function is only invoked and interpolated with the log message if warn-level logging is enabled.

This allows you to replace usages of SLF4J's MessageFormatter, with the more idiomatic string templates Kotlin provides.

Kotlin:
import com.github.michaelbull.logging.InlineLogger

val logger = InlineLogger("CalculationLogger")

fun expensiveCalculation(): Int {
    return 1234 * 5678
}

fun main() {
    logger.warn { "The result is: ${expensiveCalculation()}" }
}
Decompiled Java:
import com.github.michaelbull.logging.InlineLogger;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class ExampleKt {
    @NotNull
    private static final Logger logger;

    @NotNull
    public static Logger getLogger() {
        return logger;
    }

    public static int expensiveCalculation() {
        return 1234 * 5678;
    }

    public static void main() {
        Logger $this$iv = logger;
        if (InlineLogger.isWarnEnabled-impl((Logger) $this$iv)) {
            String string = "The result is: " + ExampleKt.expensiveCalculation();
            $this$iv.warn(String.valueOf(string));
        }
    }

    public static /* synthetic */ void main(String[] arrstring) {
        ExampleKt.main();
    }

    static {
        Logger delegate$iv = LoggerFactory.getLogger("CalculationLogger");
        logger = InlineLogger.constructor-impl((Logger) delegate$iv);
    }
}

Contributing

Bug reports and pull requests are welcome on GitHub.

License

This project is available under the terms of the ISC license. See the LICENSE file for the copyright information and licensing terms.

You can’t perform that action at this time.