OxL Reference

module std.obs

std.obs — observability (§15.5, II.1): structured logs (D-3110), spans and metrics (D-5240..D-5259; docs/observability.md).

log.info("order {id} paid {amount}") writes one line to stderr and keeps every interpolated value as a separate field named after its expression (id, amount). The message is only built when the level is enabled. secret<T> values show as *** everywhere. The level comes from --log-level l or OXL_LOG (trace debug info warn error, default info, III.6); the format is text (default) or JSON lines (--log-format json or OXL_LOG_FORMAT=json):

oxl
2026-11-03T15:04:05.250Z INFO  order 42 paid 10.5 id=42 amount=10.5
{"ts":"2026-11-03T15:04:05.250Z","level":"info","msg":"order 42 paid 10.5","fields":{"id":"42","amount":"10.5"}}

Intrinsics: compiler/src/codegen/CGLog.cpp over runtime/src/obs/log.cpp.

Example:

oxl✓ checked in CI
use std.obs { log, metric, span }

fn main() io {
  let served = metric.counter("requests_total", "requests served")
  span.with("handle") {
    let id = 7
    log.info("request {id} handled")
    served.inc()
  }
  print("{served.value()}")
}
Output
1.0

Types

data CounterA value that only grows (requests served, errors).
data GaugeA value that goes up and down (queue length, connections).
data HistogramA distribution (latencies, sizes) counted into buckets.
enum LevelSeverity of a log record, lowest first.
data logNamespace of the logging functions
data metricNamespace of the metric constructors.
data SpanAn open span of the calling task.
data spanNamespace of the span functions

See also