1# log - messages with a date on them.2#3# The functions of the module write to standard error, one line each, with the4# local date in front:5#6# log = import("log")7#8# log.Print("listening on {port}") # 2026/07/29 10:13:44 listening on 80809# log.Fatal("cannot open {path}") # the same, then exit(1)10#11# SetPrefix puts a word of your own in front of the date, SetOutput sends the12# lines somewhere else, and New builds a logger writing to a file:13#14# l = log.New(os.Create("run.log"), "worker ")15# l.Print("started")1617os = import("os")18time = import("time")1920# The layout of the date, in the verbs of time.Format. Local time, seconds21# only: a log line is read by a person, not parsed.22Layout = "%Y/%m/%d %H:%M:%S"2324# New returns a logger writing to w, which is anything with a Write, with25# prefix written before the date of every line.26New = fn(w, prefix) {27 l = new()28 l.Out = w29 l.Prefix = if prefix == null { "" } else { string(prefix) }3031 # Stamp is what goes in front of a message. Setting it to false turns the32 # date off, for a program whose output is timestamped by something else.33 l.Stamp = true3435 l.line = fn(msg) {36 out = l.Prefix37 if l.Stamp {38 out = out + time.Format(time.NowLocal(), Layout) + " "39 }40 return out + string(msg) + "\n"41 }4243 # Print writes one line. The message is a string, so build it with the44 # interpolation of the language: log.Print("got {n} of them").45 l.Print = fn(msg) { l.Out.Write(l.line(msg)) }4647 # Fatal writes one line and ends the program with status 1.48 l.Fatal = fn(msg) {49 l.Print(msg)50 exit(1)51 }5253 return l54}5556# The logger behind the functions of the module, on standard error so that the57# output of a program stays clean.58std = New(os.Stderr, "")5960# SetOutput sends the lines of the module somewhere else, any file or object61# with a Write.62SetOutput = fn(w) {63 std.Out = w64 return null65}6667# SetPrefix puts s in front of every line, before the date.68SetPrefix = fn(s) {69 std.Prefix = string(s)70 return null71}7273# SetStamp turns the date in front of every line on or off.74SetStamp = fn(on) {75 std.Stamp = on == true76 return null77}7879Print = fn(msg) { std.Print(msg) }80Fatal = fn(msg) { std.Fatal(msg) }