cl-log-kit¶
cl-log-kit is a dependency-free, SBCL-only structured logging toolkit for
Common Lisp, inspired by Go's log/slog. It separates immutable log records
from handlers that serialize them: every built-in handler emits a record
through exactly one handle-log-record method, so there is no way to end up
with duplicate output paths.
New to cl-log-kit?
Load it, build a logger, and emit your first structured log line in under a minute:
Continue with Installation → Quick Start → Levels and Fields.
Explore the docs¶
-
Getting Started
Load the system with ASDF or Nix, and build your first logger and log line.
-
Core Concepts
Severity levels, structured fields, and how loggers derive scoped children with
logger-with,derive-logger, andwith-log-context. -
Handlers
Text and JSON output, composition with
multi-handlerandfilter-handler, file rotation and trigger-based buffering, and the handler lifecycle protocol. -
Conditions and Spans
Turn Lisp conditions into structured fields, and time an operation with paired start/end log records.
Production readiness¶
"Production ready" is a checkable claim here, not a slogan:
- Zero runtime dependencies. The shipped
cl-log-kitsystem depends on nothing but ASDF 3.3.1 or newer and SBCL itself — nothing to audit, pin, or break in a consumer's own dependency graph.cl-log-kit/testdepends oncl-weaveandcl-json-kit, both test-only. - Semantic Versioning, enforced by changelog discipline. Every behavior change is recorded in the changelog under the version it shipped in, and anything that changes the shape or behavior of an exported symbol gets a major version and its own migration path. See Compatibility.
- A CI gate that runs the exact suite a contributor runs locally.
nix flake checkdrives the SBCL suite, the formatting gate, and this site's--strictbuild; a separate coverage gate fails the build on any expression or branch coverage regression, currently 93.95% / 98.77%. See Development. - Concurrency-safe by construction, not by convention. Every handler that owns a stream serializes writes and closes through a single reentrant lock, and every composite handler's lifecycle guarantees close-at-most-once under concurrent and recursive callers. These are exercised by dedicated multi-thread specs, not single-threaded examples. See Handlers.
- Bounded by construction against hostile or malformed input. Field depth, node count, string length, and collection size are all capped, with structured conditions on every limit, so a logging call can never be the vector for an unbounded-memory or infinite-loop bug even on attacker-influenced field values. See Fields.
- MIT-licensed, with a public bug tracker and no undocumented private API — every exported symbol has a docstring.
Status¶
Version 1.0.0. cl-log-kit is a small, stable surface — see the
API Reference for the full list of exported symbols. The
capability list below is the intended public surface, validated by the test
suite documented in Development:
make-logger/logger-with/derive-logger/logger-childfor building and deriving structured loggers- explicit-logger logging macros (
log-debug,log-info,log-warn,log-error,log-fatal), which always take the logger as their first argument, and theirlog-default-*counterparts against*default-logger* with-default-loggerfor a dynamically scoped default loggerwith-log-contextfor dynamically scoped fields shared across a call stack, pluscapture-log-context/with-captured-log-contextfor carrying that context into a new thread- five built-in severity levels (
DEBUG<INFO<WARN<ERROR<FATAL) plus arbitrary integer custom levels - level-gated macros that skip message/field evaluation, clock access, and handler work entirely when a call is filtered
- property-list fields with case-insensitive canonical keys and strict duplicate-key rejection
- recursive, cycle-safe snapshotting of strings, conses, arrays, hash tables, and explicit JSON containers, with fixed resource limits
text-handlerandjson-handlerbuilt-in output handlers, both injection-safe against control characters, DEL, and bidi/invisible spoofing controls- an explicit JSON value model (
json-object,json-array,+json-null+,+json-false+) so field encoding is never guessed from Lisp types multi-handler,filter-handler,function-handler, andnull-handlerfor composing and adapting handlersprocessor-handlerfor per-record enrichment,rotating-file-handlerfor clock-driven file rotation with retention pruning, andbuffered-handlerfor holding records back until a trigger-level record arrives- an extensible handler lifecycle protocol (
handler-open-p,flush-handler,close-handler,with-handler,flush-logger) with atomic handle/flush/close admission condition-fields/log-conditionfor turning Lisp conditions into structured:condition-type/:condition-message/:backtracefieldswith-log-spanfor paired:start/:endrecords with duration, outcome, and parent/child span correlation- a
handlerextension protocol for new destinations and encodings
Guide Map¶
- Installation — loading
cl-log-kitwith ASDF or Nix. - Quick Start — a first logger, a first log line, JSON output.
- Levels — the five built-in severities, custom levels, and level-gated evaluation.
- Fields — property-list fields, canonicalization, snapshotting, and resource limits.
- Logger Derivation and Context —
logger-with,derive-logger,logger-child, andwith-log-contextprecedence rules. - Handlers —
text-handler,json-handler, composition, and the lifecycle protocol. - Logging Conditions —
condition-fieldsandlog-condition. - Log Spans —
with-log-spantiming and correlation. - Records and Extension —
log-record, implementing new handlers, and injecting a deterministic clock. - API Reference — every exported symbol, grouped by area.
- Compatibility — supported platforms, the stability promise, and what counts as a security defect.
- Benchmarks —
handle-log-recordtimings and the zero-allocation guarantee the suite asserts. - Development — the dev shell, coverage floors, and the Nix-driven test workflow.
Nix Workflow¶
The flake.nix
at the repository root packages cl-log-kit as a Nix flake:
nix develop— a devShell with SBCL and the test-only dependencies (cl-weave,cl-json-kit) wired intoCL_SOURCE_REGISTRY.nix build— builds thecl-log-kitASDF system as a Nix package.nix run .#test— runs the test suite under a bounded timeout.nix flake check— the test suite, the formatting gate, and this site's--strictbuild, each as a reproducible derivation.nix build .#docs— builds this documentation site with MkDocs (Material) in--strictmode, so broken links fail the build.
Project¶
cl-log-kit is part of the nerima-lisp org
and follows its shared community health files:
Report reproducible defects, documentation gaps, and concrete feature requests through GitHub Issues. Include the smallest form that reproduces the problem and your SBCL version; for anything involving concurrency, ordering, or a hang, say how many threads were involved and whether it reproduces every run — that distinction usually determines where to look first.
License¶
MIT. See LICENSE.