-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add JVM/JS logging module * Dump API * Codecov fix and top level readme * Implement PR feedback: - Various style fixes - Make implicit tag generation pluggable for more efficient options - Allow explicit tag use * Fix lint failure * Implement more PR feedback * Lint fix
- Loading branch information
1 parent
8e77f2a
commit ae28ac2
Showing
24 changed files
with
1,000 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
![badge-js] | ||
![badge-jvm] | ||
|
||
# Logging | ||
|
||
Tool box for a simple multiplatform logging API. | ||
|
||
## Installation | ||
|
||
### Gradle | ||
|
||
Artifacts are hosted on GitHub packages, which can be configured as follows: | ||
|
||
```kotlin | ||
import java.net.URI | ||
|
||
repositories { | ||
maven { | ||
url = URI("https://maven.pkg.github.com/juullabs/android-github-packages") | ||
credentials { | ||
username = findProperty("github.packages.username") as String | ||
password = findProperty("github.packages.password") as String | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Then the needed artifact(s) can be defined as dependencies. | ||
|
||
**Multiplatform projects** | ||
|
||
```kotlin | ||
kotlin { | ||
sourceSets { | ||
val commonMain by getting { | ||
implementation("com.juul.tuulbox:logging:$version") | ||
} | ||
} | ||
} | ||
``` | ||
|
||
**Platform-specific projects** | ||
|
||
```kotlin | ||
dependencies { | ||
implementation("com.juul.tuulbox:logging-$platform:$version") | ||
} | ||
``` | ||
|
||
|
||
[badge-android]: http://img.shields.io/badge/platform-android-6EDB8D.svg?style=flat | ||
[badge-ios]: http://img.shields.io/badge/platform-ios-CDCDCD.svg?style=flat | ||
[badge-js]: http://img.shields.io/badge/platform-js-F8DB5D.svg?style=flat | ||
[badge-jvm]: http://img.shields.io/badge/platform-jvm-DB413D.svg?style=flat | ||
[badge-linux]: http://img.shields.io/badge/platform-linux-2D3F6C.svg?style=flat | ||
[badge-windows]: http://img.shields.io/badge/platform-windows-4D76CD.svg?style=flat | ||
[badge-mac]: http://img.shields.io/badge/platform-macos-111111.svg?style=flat | ||
[badge-watchos]: http://img.shields.io/badge/platform-watchos-C0C0C0.svg?style=flat | ||
[badge-tvos]: http://img.shields.io/badge/platform-tvos-808080.svg?style=flat | ||
[badge-wasm]: https://img.shields.io/badge/platform-wasm-624FE8.svg?style=flat |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
public final class com/juul/tuulbox/logging/ConsoleLogger : com/juul/tuulbox/logging/Logger { | ||
public static final field INSTANCE Lcom/juul/tuulbox/logging/ConsoleLogger; | ||
public fun assert (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public fun debug (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public fun error (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public fun info (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public fun verbose (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public fun warn (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
} | ||
|
||
public final class com/juul/tuulbox/logging/ConstantTagGenerator : com/juul/tuulbox/logging/TagGenerator { | ||
public fun <init> (Ljava/lang/String;)V | ||
public fun getTag ()Ljava/lang/String; | ||
} | ||
|
||
public final class com/juul/tuulbox/logging/DispatchLogger : com/juul/tuulbox/logging/Logger { | ||
public fun <init> ()V | ||
public fun assert (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public final fun clear ()V | ||
public fun debug (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public fun error (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public fun info (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public final fun install (Lcom/juul/tuulbox/logging/Logger;)V | ||
public fun verbose (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public fun warn (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
} | ||
|
||
public final class com/juul/tuulbox/logging/Log { | ||
public static final field INSTANCE Lcom/juul/tuulbox/logging/Log; | ||
public final fun assert (Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V | ||
public static synthetic fun assert$default (Lcom/juul/tuulbox/logging/Log;Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V | ||
public final fun debug (Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V | ||
public static synthetic fun debug$default (Lcom/juul/tuulbox/logging/Log;Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V | ||
public final fun error (Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V | ||
public static synthetic fun error$default (Lcom/juul/tuulbox/logging/Log;Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V | ||
public final fun getDispatcher ()Lcom/juul/tuulbox/logging/DispatchLogger; | ||
public final fun getTagGenerator ()Lcom/juul/tuulbox/logging/TagGenerator; | ||
public final fun info (Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V | ||
public static synthetic fun info$default (Lcom/juul/tuulbox/logging/Log;Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V | ||
public final fun setTagGenerator (Lcom/juul/tuulbox/logging/TagGenerator;)V | ||
public final fun verbose (Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V | ||
public static synthetic fun verbose$default (Lcom/juul/tuulbox/logging/Log;Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V | ||
public final fun warn (Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V | ||
public static synthetic fun warn$default (Lcom/juul/tuulbox/logging/Log;Ljava/lang/Throwable;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V | ||
} | ||
|
||
public abstract interface class com/juul/tuulbox/logging/Logger { | ||
public abstract fun assert (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public abstract fun debug (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public abstract fun error (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public abstract fun info (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public abstract fun verbose (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
public abstract fun warn (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V | ||
} | ||
|
||
public abstract interface class com/juul/tuulbox/logging/TagGenerator { | ||
public abstract fun getTag ()Ljava/lang/String; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
plugins { | ||
kotlin("multiplatform") | ||
id("org.jmailen.kotlinter") | ||
jacoco | ||
`maven-publish` | ||
} | ||
|
||
apply(from = rootProject.file("gradle/jacoco.gradle.kts")) | ||
apply(from = rootProject.file("gradle/publish.gradle.kts")) | ||
|
||
kotlin { | ||
explicitApi() | ||
|
||
jvm() | ||
js().browser() | ||
|
||
sourceSets { | ||
val commonTest by getting { | ||
dependencies { | ||
implementation(project(":test")) | ||
implementation(kotlin("test-common")) | ||
implementation(kotlin("test-annotations-common")) | ||
} | ||
} | ||
|
||
val jvmTest by getting { | ||
dependencies { | ||
implementation(kotlin("test-junit")) | ||
} | ||
} | ||
|
||
val jsTest by getting { | ||
dependencies { | ||
implementation(kotlin("test-js")) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package com.juul.tuulbox.logging | ||
|
||
/** Logger for the console. */ | ||
public expect object ConsoleLogger : Logger |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.juul.tuulbox.logging | ||
|
||
/** Constant tag generator, for when performance is more important than useful implicit tags. */ | ||
public class ConstantTagGenerator(private val tag: String) : TagGenerator { | ||
override fun getTag(): String = tag | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.juul.tuulbox.logging | ||
|
||
/** Implementation of [Logger] which dispatches calls to consumer [Logger]s. */ | ||
public class DispatchLogger : Logger { | ||
private val consumers = mutableSetOf<Logger>() | ||
|
||
/** `false` if no consumers have been installed, `true` if at least one consumer has been installed. */ | ||
internal val hasConsumers: Boolean | ||
get() = consumers.isNotEmpty() | ||
|
||
/** Add a consumer to receive future dispatch calls. */ | ||
public fun install(consumer: Logger) { | ||
consumers.add(consumer) | ||
} | ||
|
||
/** Uninstall all installed consumers. */ | ||
public fun clear() { | ||
consumers.clear() | ||
} | ||
|
||
override fun verbose(tag: String, message: String, throwable: Throwable?) { | ||
consumers.forEach { it.verbose(tag, message, throwable) } | ||
} | ||
|
||
override fun debug(tag: String, message: String, throwable: Throwable?) { | ||
consumers.forEach { it.debug(tag, message, throwable) } | ||
} | ||
|
||
override fun info(tag: String, message: String, throwable: Throwable?) { | ||
consumers.forEach { it.info(tag, message, throwable) } | ||
} | ||
|
||
override fun warn(tag: String, message: String, throwable: Throwable?) { | ||
consumers.forEach { it.warn(tag, message, throwable) } | ||
} | ||
|
||
override fun error(tag: String, message: String, throwable: Throwable?) { | ||
consumers.forEach { it.error(tag, message, throwable) } | ||
} | ||
|
||
override fun assert(tag: String, message: String, throwable: Throwable?) { | ||
consumers.forEach { it.assert(tag, message, throwable) } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package com.juul.tuulbox.logging | ||
|
||
import kotlin.jvm.Volatile | ||
|
||
/** Global logging object. To receive logs, call [dispatcher].[install][DispatchLogger.install]. */ | ||
public object Log { | ||
|
||
/** Global log dispatcher. */ | ||
public val dispatcher: DispatchLogger = DispatchLogger() | ||
|
||
/** Global tag generator for log calls without explicit tag. */ | ||
@Volatile | ||
public var tagGenerator: TagGenerator = defaultTagGenerator | ||
|
||
/** Send a verbose-level log message to the global dispatcher. */ | ||
public fun verbose(throwable: Throwable? = null, tag: String? = null, message: () -> String) { | ||
if (dispatcher.hasConsumers) { | ||
dispatcher.verbose(tag ?: tagGenerator.getTag(), message.invoke(), throwable) | ||
} | ||
} | ||
|
||
/** Send a debug-level log message to the global dispatcher. */ | ||
public fun debug(throwable: Throwable? = null, tag: String? = null, message: () -> String) { | ||
if (dispatcher.hasConsumers) { | ||
dispatcher.debug(tag ?: tagGenerator.getTag(), message.invoke(), throwable) | ||
} | ||
} | ||
|
||
/** Send an info-level log message to the global dispatcher. */ | ||
public fun info(throwable: Throwable? = null, tag: String? = null, message: () -> String) { | ||
if (dispatcher.hasConsumers) { | ||
dispatcher.info(tag ?: tagGenerator.getTag(), message.invoke(), throwable) | ||
} | ||
} | ||
|
||
/** Send an warn-level log message to the global dispatcher. */ | ||
public fun warn(throwable: Throwable? = null, tag: String? = null, message: () -> String) { | ||
if (dispatcher.hasConsumers) { | ||
dispatcher.warn(tag ?: tagGenerator.getTag(), message.invoke(), throwable) | ||
} | ||
} | ||
|
||
/** Send an error-level log message to the global dispatcher. */ | ||
public fun error(throwable: Throwable? = null, tag: String? = null, message: () -> String) { | ||
if (dispatcher.hasConsumers) { | ||
dispatcher.error(tag ?: tagGenerator.getTag(), message.invoke(), throwable) | ||
} | ||
} | ||
|
||
/** Send an assert-level log message to the global dispatcher. */ | ||
public fun assert(throwable: Throwable? = null, tag: String? = null, message: () -> String) { | ||
if (dispatcher.hasConsumers) { | ||
dispatcher.assert(tag ?: tagGenerator.getTag(), message.invoke(), throwable) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.juul.tuulbox.logging | ||
|
||
/** Classes which implement [Logger] can write logs. */ | ||
public interface Logger { | ||
|
||
/** Log at verbose-level. */ | ||
public fun verbose(tag: String, message: String, throwable: Throwable?) | ||
|
||
/** Log at debug-level. */ | ||
public fun debug(tag: String, message: String, throwable: Throwable?) | ||
|
||
/** Log at info-level. */ | ||
public fun info(tag: String, message: String, throwable: Throwable?) | ||
|
||
/** Log at warn-level. */ | ||
public fun warn(tag: String, message: String, throwable: Throwable?) | ||
|
||
/** Log at error-level. */ | ||
public fun error(tag: String, message: String, throwable: Throwable?) | ||
|
||
/** Log at assert-level. */ | ||
public fun assert(tag: String, message: String, throwable: Throwable?) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.juul.tuulbox.logging | ||
|
||
internal expect val defaultTagGenerator: TagGenerator | ||
|
||
/** Creates tag strings for implicitly-tagged [Log] calls. */ | ||
public interface TagGenerator { | ||
|
||
/** Return a tag to use when the [Log] call has no explicit tag. */ | ||
public fun getTag(): String | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.juul.tuulbox.logging | ||
|
||
data class Call( | ||
val tag: String, | ||
val message: String, | ||
val throwable: Throwable? | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.juul.tuulbox.logging | ||
|
||
class CallListLogger : Logger { | ||
|
||
private val mutableVerboseCalls = mutableListOf<Call>() | ||
val verboseCalls: List<Call> = mutableVerboseCalls | ||
|
||
private val mutableDebugCalls = mutableListOf<Call>() | ||
val debugCalls: List<Call> = mutableDebugCalls | ||
|
||
private val mutableInfoCalls = mutableListOf<Call>() | ||
val infoCalls: List<Call> = mutableInfoCalls | ||
|
||
private val mutableWarnCalls = mutableListOf<Call>() | ||
val warnCalls: List<Call> = mutableWarnCalls | ||
|
||
private val mutableErrorCalls = mutableListOf<Call>() | ||
val errorCalls: List<Call> = mutableErrorCalls | ||
|
||
private val mutableAssertCalls = mutableListOf<Call>() | ||
val assertCalls: List<Call> = mutableAssertCalls | ||
|
||
override fun verbose(tag: String, message: String, throwable: Throwable?) { | ||
mutableVerboseCalls += Call(tag = tag, message = message, throwable = throwable) | ||
} | ||
|
||
override fun debug(tag: String, message: String, throwable: Throwable?) { | ||
mutableDebugCalls += Call(tag = tag, message = message, throwable = throwable) | ||
} | ||
|
||
override fun info(tag: String, message: String, throwable: Throwable?) { | ||
mutableInfoCalls += Call(tag = tag, message = message, throwable = throwable) | ||
} | ||
|
||
override fun warn(tag: String, message: String, throwable: Throwable?) { | ||
mutableWarnCalls += Call(tag = tag, message = message, throwable = throwable) | ||
} | ||
|
||
override fun error(tag: String, message: String, throwable: Throwable?) { | ||
mutableErrorCalls += Call(tag = tag, message = message, throwable = throwable) | ||
} | ||
|
||
override fun assert(tag: String, message: String, throwable: Throwable?) { | ||
mutableAssertCalls += Call(tag = tag, message = message, throwable = throwable) | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
logging/src/commonTest/kotlin/ConstantTagGeneratorTests.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.juul.tuulbox.logging | ||
|
||
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
|
||
class ConstantTagGeneratorTests { | ||
|
||
@Test | ||
fun constantTagGeneratorWorks() { | ||
val expected = "Constant" | ||
val generator = ConstantTagGenerator(expected) | ||
assertEquals(expected, generator.getTag()) | ||
} | ||
} |
Oops, something went wrong.