ilusm.dev

obs

Observability - emit structured JSON log entries at info/warn/error levels, annotate the execution timeline with span notes, read back the full timeline as a list or JSON string, write it to stdout as NDJSON, peek the current span clock, reset the timeline, snapshot any value with type-aware truncation, and emit type-check trace events for debugging.

Load with: use obs

What this module does

obs is the central telemetry module. It wraps the obs_engine backend (which manages span tracking, sequence numbers, and the timeline buffer) and the host's __obs_spn / __obs_sum natives. All log entries are written to stdout as line-delimited JSON so they can be consumed by any log aggregator.

The trcx module is a thin re-export of the most common obs functions under shorter names. Use obs directly when you need the full surface.

Quick example

use obs

# Structured logs
obs.info("server started")
obs.warn("high latency detected")
obs.error("database unreachable")

# Custom log entry
obs.log({ev: "request", method: "GET", path: "/api/health", ms: 12})

# Annotate timeline
obs.note("auth", {user: "alice", ok: tru})

# Value snapshot (truncates large lists/objects)
obs.val("result", big_list, 5)  # logs first 5 elements

# Type-check trace
obs.typchk("user_id", x, "num")  # logs warning if x is not a number

# Export timeline
tl = obs.timeline()         # list of event objects
prn(obs.timeline_json())    # JSON string

obs.timeline_write()        # write full timeline JSON to stdout
obs.timeline_ndjson()       # write each event as a separate JSON line

# Reset
obs.reset()

Functions

Logging

obsle(data) / obs.log(data)

Writes a JSON log entry with {knd:"log", t, seq, span, d: data} to stdout.

obsin(msg) / obs.info(msg)

Logs {lvl:"inf", msg}.

obswr(msg) / obs.warn(msg)

Logs {lvl:"wrn", msg}.

obser(msg) / obs.error(msg)

Logs {lvl:"err", msg}.

Timeline

obstl() / obs.timeline()

Returns the full timeline as a list of event objects.

obstj() / obs.timeline_json()

Returns the timeline as a JSON-encoded string.

obstw() / obs.timeline_write()

Writes the timeline JSON to stdout followed by a newline.

obstn() / obs.timeline_ndjson()

Writes each timeline event as a separate JSON line to stdout.

obsno(span, data) / obs.note(span, data)

Appends a note event to the timeline for the given span name.

obsrs() / obs.reset()

Clears the timeline.

Span and telemetry

obssp0() / obs.span()

Starts a new span via __obs_spn.

obssu() / obs.summary()

Returns a summary from __obs_sum.

obspk() / obs.peek()

Returns the current span clock value.

obsrf() / obs.ref() / obs.stack()

Returns the current span reference/stack from the engine.

Value inspection

obssn(v, max) / obs.snap(v, max)

Returns a type-aware snapshot of v: for lists shows the first max elements and total length; for objects shows the first max keys. Useful for logging large values without flooding the log.

obsva(name, v, buf) / obs.val(name, v, buf)

Logs a value event with name, type, string representation, and snapshot.

obsva2(name, v, max) / obs.val2(name, v, max)

Like obs.val but omits the raw string value, only logging the snapshot.

obsty(name, v, want) / obs.typchk(name, v, want)

Checks that v has type want. Logs a warning event if not. Returns tru/fls.

Notes

  • Requires trl, jsn, and obs_engine.
  • Used by trcx, mw, and other modules that need structured logging.