Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbull committed Jun 8, 2019
0 parents commit 1122901
Show file tree
Hide file tree
Showing 19 changed files with 1,074 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.{kt,kts,gradle}]
indent_style = space
indent_size = 4
continuation_indent_size = 4
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Hidden files
.*

# Temporary files
*~

# Git
!.git*

# EditorConfig
!.editorconfig

# IntelliJ Idea
out/
*.iml
*.ipr
*.iws

# Travis CI
!.travis.yml

# Gradle
build/

# JVM error logs
hs_err_pid*.log
replay_pid*.log
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
language: java
jdk:
- oraclejdk8

notifications:
email: false
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright (c) 2018 Michael Bull (https://www.michael-bull.com)

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
150 changes: 150 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# kotlin-inline-logger

[![Release](https://api.bintray.com/packages/michaelbull/maven/kotlin-inline-logger/images/download.svg)](https://bintray.com/michaelbull/maven/kotlin-inline-logger/_latestVersion) [![Build Status](https://travis-ci.org/michaelbull/kotlin-inline-logger.svg?branch=master)](https://travis-ci.org/michaelbull/kotlin-inline-logger) [![License](https://img.shields.io/github/license/michaelbull/kotlin-inline-logger.svg)](https://github.com/michaelbull/kotlin-inline-logger/blob/master/LICENSE)

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

## Installation

```groovy
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`][mpp].
Currently the only implementation supports the JVM, utilising [SLF4J][slf4j],
however in future other platforms can also be supported by implementing the
necessary platform-specific APIs found in [`src/commonMain`](src/commonMain).

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

### JVM

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

![ReplaceWith example](replacewith-example.gif)

#### 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][slf4j-idiom] that is resistant to
cut-and-pasting between classes.

Named loggers can be created by passing a name:

```kotlin
val transactionLogger = InlineLogger("DatabaseTransactions")
```

Class loggers can be created by passing the `::class` reference:

```kotlin
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][slf4j-formatter],
with the more idiomatic [string templates][string-templates] Kotlin provides.

##### Kotlin:

```kotlin
import com.github.michaelbull.logging.InlineLogger

val logger = InlineLogger()

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

fun main() {
logger.warn { "The result is: ${expensiveCalculation()}" }
}
```

##### Compiled Java:

```java
import com.github.michaelbull.logging.InlineLogger;
import java.lang.invoke.MethodHandles;
import kotlin.Metadata;
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 final Logger getLogger() {
return logger;
}

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

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

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

static {
boolean $i$f$InlineLogger = false;
Logger delegate$iv = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
logger = InlineLogger.constructor-impl((Logger)delegate$iv);
}
}
```

## Contributing

Bug reports and pull requests are welcome on [GitHub][github].

## License

This project is available under the terms of the ISC license. See the
[`LICENSE`](LICENSE) file for the copyright information and licensing terms.

[inline-classes]: https://kotlinlang.org/docs/reference/inline-classes.html
[inline-functions]: https://kotlinlang.org/docs/reference/inline-functions.html
[mpp]: https://kotlinlang.org/docs/reference/multiplatform.html
[string-templates]: https://kotlinlang.org/docs/reference/basic-types.html#string-templates
[github]: https://github.com/michaelbull/kotlin-inline-logger
[slf4j]: https://www.slf4j.org/
[slf4j-idiom]: https://www.slf4j.org/faq.html#declaration_pattern
[slf4j-formatter]: https://www.slf4j.org/api/org/slf4j/helpers/MessageFormatter.html
94 changes: 94 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import com.jfrog.bintray.gradle.BintrayExtension
import com.jfrog.bintray.gradle.tasks.BintrayUploadTask

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

plugins {
`maven-publish`
kotlin("multiplatform") version ("1.3.31")
id("com.github.ben-manes.versions") version ("0.21.0")
id("com.jfrog.bintray") version ("1.8.4")
id("net.researchgate.release") version ("2.8.0")
}

repositories {
mavenCentral()
jcenter()
}

kotlin {
sourceSets {
named("commonMain") {
dependencies {
implementation(kotlin("stdlib-common"))
}
}

named("commonTest") {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
}

jvm {
compilations.named("main") {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = listOf("-Xno-call-assertions", "-Xno-receiver-assertions", "-Xno-param-assertions")
}

dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation("org.slf4j:slf4j-api:1.7.26")
}
}

compilations.named("test") {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = listOf("-Xno-call-assertions", "-Xno-receiver-assertions", "-Xno-param-assertions")
}

dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
}
}
}
}

fun BintrayExtension.pkg(configure: BintrayExtension.PackageConfig.() -> Unit) {
pkg(delegateClosureOf(configure))
}

val bintrayUser: String? by project
val bintrayKey: String? by project

bintray {
user = bintrayUser
key = bintrayKey
setPublications("jvm", "metadata")

pkg {
repo = "maven"
name = project.name
desc = project.description
websiteUrl = "https://github.com/michaelbull/kotlin-inline-logger"
issueTrackerUrl = "https://github.com/michaelbull/kotlin-inline-logger/issues"
vcsUrl = "[email protected]:michaelbull/kotlin-inline-logger.git"
githubRepo = "michaelbull/kotlin-inline-logger"
setLicenses("ISC")
}
}

val bintrayUpload by tasks.existing(BintrayUploadTask::class) {
dependsOn("build")
dependsOn("generatePomFileForJvmPublication")
dependsOn("generatePomFileForMetadataPublication")
}

tasks.named("afterReleaseBuild") {
dependsOn(bintrayUpload)
}
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
group=com.michael-bull.kotlin-inline-logger
version=1.0.0
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 1122901

Please sign in to comment.