// Package lol (log of location) formats log entries with microsecond // timestamps and source locations. Entries are sent as []byte on a channel // to the logger domain — no direct I/O happens here. package lol import ( "fmt" "runtime" "time" ) const ( Off = iota Fatal Error Warn Info Debug Trace ) var LevelNames = [][]byte{ []byte("off"), []byte("fatal"), []byte("error"), []byte("warn"), []byte("info"), []byte("debug"), []byte("trace"), } var LevelTags = [][]byte{ []byte(" "), []byte("FTL"), []byte("ERR"), []byte("WRN"), []byte("INF"), []byte("DBG"), []byte("TRC"), } type ( // Ln prints items with spaces between them. Ln func(a ...any) // F prints formatted output. F func(format []byte, a ...any) // C accepts a closure to defer computation if level is suppressed. C func(closure func() []byte) // Chk logs an error if non-nil and returns whether it was non-nil. Chk func(e error) bool // Err formats and returns an error, also logging it. Err func(format []byte, a ...any) error // LevelPrinter is the full set of printers for one log level. LevelPrinter struct { Ln F C Chk Err } ) // Log holds printers for all levels. type Log struct { F, E, W, I, D, T LevelPrinter } // Check holds error checkers for all levels. type Check struct { F, E, W, I, D, T Chk } // Errorf holds error-returning loggers for all levels. type Errorf struct { F, E, W, I, D, T Err } // Logger bundles Log, Check, and Errorf. type Logger struct { *Log *Check *Errorf } // Main is the default logger. It writes to a discard channel until // Init is called with a real log channel. var Main = &Logger{} // level is the current log level for this domain. Plain int32 — // single cooperative thread, no atomic needed. var level int32 = Info func init() { Main.Log, Main.Check, Main.Errorf = newPrinters(nil, 2) } // Init wires the logger to a channel. Must be called once per domain // at startup before any logging. Passing nil gives a local stderr // fallback (useful for the main domain before logger domain is spawned). func Init(ch chan<- []byte) { Main.Log, Main.Check, Main.Errorf = newPrinters(ch, 2) } // SetLevel sets the log level for this domain. func SetLevel(l int32) { level = l } // GetLevel returns the current log level. func GetLevel() int32 { return level } // SetLevelByName sets the log level by name. func SetLevelByName(name []byte) { for i := range LevelNames { if bytesEqual(name, LevelNames[i]) { level = int32(i) return } } level = Info } // GetLevelByName returns the level number for a name. func GetLevelByName(name []byte) int32 { for i := range LevelNames { if bytesEqual(name, LevelNames[i]) { return int32(i) } } return Info } func bytesEqual(a, b []byte) bool { if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true } // emit sends a formatted log entry on the channel, or prints to stderr // if no channel is configured. func emit(ch chan<- []byte, entry []byte) { if ch != nil { ch <- entry return } // Fallback: direct print (before logger domain is up, or in tests) print(string(entry)) } // formatEntry builds a log line: "timestamp TAG message location\n" func formatEntry(l int32, msg []byte, skip int) []byte { ts := time.Now().UnixMicro() _, file, line, _ := runtime.Caller(skip) return append([]byte(nil), fmt.Sprintf("%d %s %s %s:%d\n", ts, LevelTags[l], msg, file, line)...) } // getPrinter returns a LevelPrinter for one level that sends on ch. func getPrinter(l int32, ch chan<- []byte, skip int) LevelPrinter { return LevelPrinter{ Ln: func(a ...any) { if level < l { return } msg := append([]byte(nil), fmt.Sprint(a...)...) emit(ch, formatEntry(l, msg, skip)) }, F: func(format []byte, a ...any) { if level < l { return } msg := append([]byte(nil), fmt.Sprintf(string(format), a...)...) emit(ch, formatEntry(l, msg, skip)) }, C: func(closure func() []byte) { if level < l { return } emit(ch, formatEntry(l, closure(), skip)) }, Chk: func(e error) bool { if e == nil { return false } if level >= l { msg := []byte(e.Error()) emit(ch, formatEntry(l, msg, skip)) } return true }, Err: func(format []byte, a ...any) error { err := fmt.Errorf(string(format), a...) if level >= l { msg := []byte(err.Error()) emit(ch, formatEntry(l, msg, skip)) } return err }, } } // getNullPrinter returns a no-op printer. func getNullPrinter() LevelPrinter { return LevelPrinter{ Ln: func(a ...any) {}, F: func(format []byte, a ...any) {}, C: func(closure func() []byte) {}, Chk: func(e error) bool { return e != nil }, Err: func(format []byte, a ...any) error { return fmt.Errorf(string(format), a...) }, } } // newPrinters creates a full set of Log, Check, Errorf for all levels. func newPrinters(ch chan<- []byte, skip int) (*Log, *Check, *Errorf) { l := &Log{ T: getPrinter(Trace, ch, skip), D: getPrinter(Debug, ch, skip), I: getPrinter(Info, ch, skip), W: getPrinter(Warn, ch, skip), E: getPrinter(Error, ch, skip), F: getPrinter(Fatal, ch, skip), } c := &Check{ F: l.F.Chk, E: l.E.Chk, W: l.W.Chk, I: l.I.Chk, D: l.D.Chk, T: l.T.Chk, } ef := &Errorf{ F: l.F.Err, E: l.E.Err, W: l.W.Err, I: l.I.Err, D: l.D.Err, T: l.T.Err, } return l, c, ef }