cl-log-kit¶
cl-log-kit is an 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. It is built on the nerima-lisp toolkit family —
cl-date-kit, cl-concurrent-kit, and cl-host-kit — used directly, with
no adapter layer in between.
New to cl-log-kit?
Load it, build a logger, and emit your first structured log line:
Continue with Getting Started → 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.
Project checks¶
- Small runtime dependency set. The shipped
cl-log-kitsystem depends oncl-date-kit,cl-concurrent-kit, andcl-host-kit;cl-log-kit/testadditionally depends oncl-weaveandcl-json-kit. - Semantic Versioning. Behavior changes are recorded in the release notes 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.
- Automated checks.
nix flake checkruns the SBCL suite, formatting, and this site's--strictbuild. A separate coverage gate checks expression and branch coverage, currently 95.03% / 98.51%. See Development. - Concurrency. 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.
- Input limits. Field depth, node count, string length, and collection size are capped, with structured conditions for each limit. See Fields.
- MIT-licensed, with a public bug tracker and no undocumented private API — every exported symbol has a docstring.
Status¶
Version 2.2.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¶
- Getting Started — loading
cl-log-kitwith ASDF or Nix, then a first logger, a first log line, and 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 allocation bounds checked by the suite. - 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.