Builtin Library
README.md
logs Module
Public Luau surface over the __logs Internal FFI namespace —
read-only, filterable query API over the engine's in-memory log ring.
Purpose
Wrap the raw __logs.* FFI namespace in a typed Luau table that gets
auto-injected as _G.logs via the prelude. The store is the single
in-engine source of truth for everything the engine has logged
recently — Rust console_log!, bridged third-party log::* events
(wgpu validation, etc.), and Rust panics. The same store backs the
/engine/logs HTTP endpoint and /zero/runtime/logs/engine.
Usage
-- Did anything break?
for _, e in ipairs(logs.errors(10)) do print(e.timestamp, e.message) end
-- Filtered query
for _, e in ipairs(logs.query({ level = "warn", type = "RENDERER", limit = 50 })) do
print(e.message)
end
-- Case-insensitive grep
local hits = logs.find("MY_MARKER")
-- Aggregate counters (lifetime, survive ring eviction)
local c = logs.count()
print(c.errors, "errors,", c.warnings, "warnings,", c.dropped, "dropped")
Exports
logs.query(opts?) -> { LogEntry }logs.errors(limit?) -> { LogEntry }logs.warnings(limit?) -> { LogEntry }logs.find(text, limit?) -> { LogEntry }logs.tail(limit?) -> { LogEntry }logs.count(opts?) -> LogCountslogs.template(message) -> stringlogs.clear() -> boolean
Origin
A line a script logged carries script and entity fields, so
logs.query({ entity = "ent_9f3c" }) asks for one entity's output rather than
guessing at what its messages look like. Engine lines carry neither.
Context
logs.query({ level = "error", context = 3 }) also returns the three lines
either side of each match, marked context = true. What led up to a failure is
made of lines the filter rejected, so a filtered view cannot otherwise show it.
The other ways in
The logs toolbox reads the same ring through the tool surface — its search,
tail, errors, summary and clear tools — and adds grouping of repeated
messages. This module is the direct Luau path to that ring.
The ring is also mounted as plain files: /zero/runtime/logs/engine for every
level, /zero/runtime/logs/errors for the ERROR-and-above subset, and
/zero/runtime/logs/script for what scripts logged. Those render the most
recent 500 lines with tool-call records included, where a query here reaches
the whole ring and leaves them out unless asked for.
The ring starts empty at every boot. /zero/runtime/logs/previous holds the
previous session of the world the engine booted on: how it ended, then the last
lines it wrote.