ludic/examples/library/logging.ludic
Orkuncakilkaya 031b138f84
All checks were successful
docs / build-and-deploy (push) Successful in 2s
feat(stdlib): add Log.* — levelled, structured logging (#15)
A Log.* namespace: five levels (trace/debug/info/warn/error), a runtime
threshold, and structured key=value fields, so games get something better than
scattered print calls and release builds can go quiet without touching call
sites.

  - Log.trace/debug/info/warn/error(msg, [k, v]...)  -> stderr, "[LEVEL] msg k=v"
  - Log.set_level(n)   show only level >= n (0 = all default, 5 silences all)
  - Log.level()        read the current threshold

Fields accept strings, ints, and longs (numbers formatted automatically); the
level tag is chosen at compile time so a filtered-out level costs only a
comparison. Writes to stderr, never touching the simulation — no effect on
determinism/replays. v1 is the console sink; rotating-file and in-engine overlay
sinks are noted as follow-ups.

- examples/library/logging.ludic: asserts the set_level/level threshold
  round-trip and that every level (with mixed-type fields) runs without faulting;
  the stderr gating itself was verified by hand (warn/error emit, lower levels
  suppressed). Wired into `x test` (now 53 passed).
- docs: a new Log section + per-symbol pages; inventory and coverage pass.
- seed regenerated; `x bootstrap-cfree` fixpoint holds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 21:57:22 +03:00

28 lines
1.3 KiB
Text

# logging.ludic — Log.* levels, the threshold gate, and structured fields. Log
# lines go to stderr, which the test harness does not capture, so this program
# asserts the stdout-observable contract: the threshold round-trips through
# set_level/level, and every level method (with mixed string/number fields) runs
# without faulting. The run raises the level above `error` first so the suite's
# output stays clean; the actual stderr sink and its gating are demonstrated in
# the docs and verified by hand. Running it prints: 0 5 2 1
program Logging {
entry {
print(Log.level()) # 0 — everything shown by default
Log.set_level(5) # above error: silence the console for this run
print(Log.level()) # 5
# every level builds its line (including numeric fields, which are formatted
# for you) and is threshold-gated; none writes at level 5.
Log.trace("entering frame", "n", 10)
Log.debug("state", "hp", 100, "phase", "combat")
Log.info("level loaded", "name", "cavern", "entities", 42)
Log.warn("missing texture, using placeholder", "path", "rock.png")
Log.error("save failed", "code", 5)
Log.set_level(2) # info and above
print(Log.level()) # 2
print(1) # sentinel: reached the end without crashing
}
}