Skip to content

Repository files navigation

Scribe

A flavored Kotlin Multiplatform logging library

Scribe logo

Maven Central License Platform Targets

Scribe is a Kotlin Multiplatform logging library built around the ideas from loggingsucks.com, so structured logs can model both single events and longer contextual flows.

Documentation Page

Features:

  • Story-driven logging primitives instead of flat logger calls
  • Contextual logging with newScroll(...) and immediate-seal one-shot scrolls
  • Delivery hooks through Archivist instances receiving Entry snapshots
  • Scroll lifecycle enrichment through Margin
  • Independent Scribe objects for applications and imported libraries
  • A JVM SLF4J 2.x provider backed by the same structured logging pipeline

Setup

Add Scribe to your commonMain dependencies:

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("com.rafambn:scribe:0.6.0")
        }
    }
}

Usage

Create a Scribe object, start processing its private buffer, and emit a scroll:

object AppScribe : Scribe() {
    override val archivists: List<Archivist> = listOf(
        Archivist { entry ->
            println(entry)
        }
    )
}
AppScribe.hire()

val scroll = AppScribe.newScroll()
scroll["tag"] = JsonPrimitive("payments")
scroll["message"] = JsonPrimitive("starting checkout")
scroll["level"] = JsonPrimitive("INFO")
scroll.seal(AppScribe)

Use a scroll when you need shared context for a longer flow:

object BillingScribe : Scribe() {
    override val archivists: List<Archivist> = listOf(
        Archivist { entry -> println(entry) }
    )
    override val imprint = mapOf(
        "service" to JsonPrimitive("billing"),
        "environment" to JsonPrimitive("production"),
    )
}
BillingScribe.hire()

val scroll = BillingScribe.newScroll(id = "checkout-42")
scroll["gateway"] = JsonPrimitive("stripe")
scroll["attempt"] = JsonPrimitive(1)
scroll["retry"] = JsonPrimitive(false)
scroll.seal(BillingScribe)

Each Scribe object has independent configuration and delivery lifecycle. A Scroll is a mutable JSON-element map initialized by newScroll(...); pass the runtime that should enrich and deliver it to scroll.seal(scribe). Each seal(...) call emits a separate snapshot of the scroll data.

SLF4J

For JVM applications, add the SLF4J provider:

dependencies {
    implementation("com.rafambn:scribe-slf4j:0.6.0")
}

Select exactly one application-wide backend with @ScribeBackend:

@ScribeBackend
object AppScribe : Slf4jScribe() {
    override val bufferCapacity = 1_024
    override val bufferOverflow = BufferOverflow.DROP_OLDEST
    override val onArchiveFailure: ((Archivist, Entry, Throwable) -> Unit)? = null
    override val archivists = listOf(
        Archivist { entry -> println(entry) },
    )

    override fun isEnabled(
        loggerName: String,
        level: Level,
        marker: Marker?,
    ): Boolean = level.toInt() >= Level.INFO.toInt()
}

The provider discovers the annotated backend once on the first SLF4J access and registers a JVM shutdown hook. Intake starts open, so early calls accumulate in the private buffer; the application calls AppScribe.hire() when processing should begin. The shutdown hook retires the Scribe and drains accepted entries automatically. Initialization fails with a descriptive error when no backend is present, multiple backends are annotated, or the annotation is not placed on a Kotlin object extending Slf4jScribe.

scribe-slf4j is a standalone SLF4J provider. Do not include another provider such as logback-classic in the same runtime classpath.

See the full documentation for lifecycle controls, overflow behavior, margins, and SLF4J field mapping.

Performance

Scribe is designed for high-throughput and thread-safe concurrent logging.

The repository includes JVM throughput tests for concurrent in-memory ingestion and serialized file writing. Results depend on the machine, runtime, buffer configuration, and archivist implementation; run the tests in your target environment before using them for capacity planning.

About

Simple Logging Lib for KMP based on the concepts of loggingsucks.com

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages