Skip to Content
i documentation
Standard library referenceModules

std/log

Structured entries and call-time sink services. See std-2.md §6/§7. Level(..), Entry(..) export constructors; Sink(E,N) hides its constructor. Level { Debug Info Warning Failure } Entry { Entry(level: Level, message: String, fields: List((String,String)), at: Option(time.Instant)) } Sink(E,N) { Sink((Level)->Bool, (Entry)->Nil ? E ! N, (N)->Nil) } Interface: make(E,N): (accept: (Level)->Bool, send: (Entry)->Nil ? E ! N)->Sink(E,N) silent(N): ()->Sink(Never,N) filter(E,N): (sink: Sink(E,N), accept: (Level)->Bool)->Sink(E,N) minimum(E,N): (sink: Sink(E,N), level: Level)->Sink(E,N) enabled(E,N): (level: Level)->Bool ! Sink(E,N) write(E,N): (entry: Entry)->Nil ? E ! N | Sink(E,N) lazy(E,F,N): (level: Level, message: ()->String ? F ! N)->Nil ? E | F ! N | Sink(E,N) format: (entry: Entry)->String stderr/stdout: () -> Sink for the corresponding stream file: (path: String) -> Sink appending formatted lines timestamped: (entry: Entry) -> Entry, reading the Unix clock

Level order is Debug < Info < Warning < Failure. Entry strings are arbitrary; fields preserve order and duplicate keys. Timestamps are explicit Unix instants and are never added or replaced by delivery. No clock is read.

make stores callbacks without calling them. enabled checks accept once. write checks the current sink once, then sends the original entry once only if accepted. False returns Nil. Delivery preserves the original error, with no retry, buffering, deduplication, task spawn, or failure suppression. lazy checks once, then calls message once and sends an entry with no fields or timestamp. Rejection calls neither callback; a message error skips send. Eager write arguments still evaluate before filtering.

filter checks the new predicate before the old predicate; send is unchanged. minimum accepts levels at or above its threshold. silent always rejects. These factories are pure. enabled followed by write performs two checks. Sink’s E is covariant and its stored N invariant. The unused (N)->Nil marker is never called. Replacements need equal service arguments; N cannot contain the same Sink(E,N) recursively. Capture a concrete downstream sink instead.

format returns lowercase level, space, quoted message, optional “ @” and signed decimal Unix nanoseconds, then ordered quoted key=value pairs. It adds no final LF. Quotes/backslashes and LF/CR/tab are escaped; other C0/C1 controls and U+2028/U+2029 use minimal lowercase \u{h}. Other scalars remain. Formatting is deterministic and linear in text length, plus integer printing.

Service laws compare delivery observations, not closure equality: accepted entries arrive in sequential call order; filter(s,always_true) preserves delivery; minimum(minimum(s,a),b) uses threshold max(a,b). No callback termination guarantee is added. Generic client use awaits the §7 compiler IO adapters are explicit and use the same sink service.

Level

Level = Debug | Info | Warning | Failure

Entry

Entry = (

Sink

Sink(E, N) = ((Level) -> Bool, (Entry) <- (Fail(E), ..N) -> Nil, (N) -> Nil)

make

make = <E, N>(

silent

silent = <N>() -> Sink(Never, N) {

filter

filter = <E, N>(sink : Sink(E, N), accept : (Level) -> Bool) -> Sink(E, N) {

minimum

minimum = <E, N>(sink : Sink(E, N), level : Level) -> Sink(E, N) {

enabled

enabled = <E, N>(level : Level) <- (sink : Sink(E, N)) -> Bool {

write

write = <E, N>(entry : Entry) <- (sink : Sink(E, N)) {

lazy

lazy = <E, N>(level : Level, message : () <- N -> String) <- (

format

format = (entry : Entry) -> String {

stderr

A sink that writes each formatted entry to standard error.

stderr = () {

stdout

A sink that writes each formatted entry to standard output.

stdout = () {

file

A sink that appends each formatted entry to a file.

file = (path : String) {

timestamped

Adds the current Unix time to an entry.

timestamped = (entry : Entry) { Entry(..entry, at = Some(time.now())) }