Skip to content

Getting Started

Add Scribe to commonMain

Use the library from shared code in your Kotlin Multiplatform module:

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

Create a Minimal Scribe

Initialize once with one or more savers, then hire the runtime with a Channel<Entry>.

import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel

Scribe.inscribe {
    shelves = listOf(NoteSaver { note ->
        println("[${note.level}] ${note.tag}: ${note.message}")
    })
}

Scribe.hire(
    channel = Channel(
        capacity = 256,
        onBufferOverflow = BufferOverflow.DROP_OLDEST,
    ),
)

Emit a Single Event

Use note(...) for standalone events:

Scribe.note(
    tag = "payments",
    message = "starting checkout",
    level = Urgency.INFO,
)

With the saver above, the log output looks like this:

[INFO] payments: starting checkout

Track a Flow with Scroll

Scroll is a mutable map (MutableMap<String, JsonElement>) that you seal into one wide event.

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonPrimitive

val scroll = Scribe.newScroll(id = "checkout-42")
scroll["gateway"] = JsonPrimitive("stripe")
scroll["attempt"] = JsonPrimitive(1)
scroll["retry"] = JsonPrimitive(false)
scroll["cart"] = Json.encodeToJsonElement(
    CheckoutMeta.serializer(),
    CheckoutMeta(itemCount = 3, subtotalCents = 249_900, featureFlag = "wide-events"),
)
scroll.seal(success = true)

The emitted SealedScroll shape:

{
  "success": true,
  "data": {
    "scroll_id": "checkout-42",
    "gateway": "stripe",
    "attempt": 1,
    "retry": false,
    "cart": {
      "item_count": 3,
      "subtotal_cents": 249900,
      "feature_flag": "wide-events"
    }
  }
}

Choose the Right Saver

val noteSaver = NoteSaver { note -> println(note) }
val scrollSaver = ScrollSaver { scroll -> println(scroll) }
val entrySaver = EntrySaver { entry -> println(entry) }
  • NoteSaver handles only Note
  • ScrollSaver handles only SealedScroll
  • EntrySaver handles both