package main import ( "fmt" "log" ) type LevelEnum uint8 const ( None LevelEnum = iota Error Warn Info Debug ) type levelInfo struct { abbrev string color string } var ( levelInfos = map[LevelEnum]levelInfo{ Error: {"ERR", ansiRed}, Warn: {"WARN", ansiYellow}, Info: {"INFO", ansiCyan}, Debug: {"DEBUG", ansiGreen}, } ) func (s LevelEnum) Info() levelInfo { info, ok := levelInfos[s] if !ok { return levelInfo{"UNK", ansiWhite} } return info } func (s LevelEnum) Format() string { info := s.Info() return colorize("["+info.abbrev+"]", info.color) } type Logger struct { Level LevelEnum ns string } func NewLogger(level LevelEnum) *Logger { return &Logger{ Level: level, } } func (l *Logger) WithNS(ns string) *Logger { return &Logger{ Level: l.Level, ns: formatNS(ns), } } func (l *Logger) Logf(level LevelEnum, format string, args ...any) { if level > l.Level { return } log.Printf("%s%s %s", l.ns, level.Format(), fmt.Sprintf(format, args...)) } func (l *Logger) Errorf(format string, args ...any) { l.Logf(Error, format, args...) } func (l *Logger) Warnf(format string, args ...any) { l.Logf(Warn, format, args...) } func (l *Logger) Infof(format string, args ...any) { l.Logf(Info, format, args...) } func (l *Logger) Debugf(format string, args ...any) { l.Logf(Debug, format, args...) } func formatNS(ns string) string { return colorize("["+ns+"]", ansiPurple) } var ansiReset = "\033[0m" var ansiRed = "\033[31m" var ansiGreen = "\033[32m" var ansiYellow = "\033[33m" var ansiBlue = "\033[34m" var ansiPurple = "\033[35m" var ansiCyan = "\033[36m" var ansiGray = "\033[37m" var ansiWhite = "\033[97m" func colorize(s string, color string) string { return color + s + ansiReset }