package log import ( "fmt" "strings" ) type level uint8 /* Emergency (emerg): indicates that the system is unusable and requires immediate attention. Alert (alert): indicates that immediate action is necessary to resolve a critical issue. Critical (crit): signifies critical conditions in the program that demand intervention to prevent system failure. Error (error): indicates error conditions that impair some operation but are less severe than critical situations. Warning (warn): signifies potential issues that may lead to errors or unexpected behavior in the future if not addressed. Notice (notice): applies to normal but significant conditions that may require monitoring. Informational (info): includes messages that provide a record of the normal operation of the system. Debug (debug): intended for logging detailed information about the system for debugging purposes. */ const ( // SILENT means no log at all. not even panics. We just don't care about the end of the world. SILENT level = iota // PANIC (also: Emergency) indicates events which cannot be handled gracefully. Program execution will terminate. PANIC // FATAL (also: Critical, Alert) indicates a situation which requires user interaction to resolve. FATAL // ERROR indicates error conditions which may result in malfunction. ERROR // WARN signifies potential issues that may lead to errors or unexpected behavior in the future if not addressed. WARN // NOTICE logs are normal but significant information. NOTICE // INFO indicates normal, informational messages. INFO // DEBUG is intended for logging detailed information for debugging purposes. DEBUG // TRACE is the most detailed level of log output. Might spam your logs. TRACE ) type levelData struct { Name string Short string Hook func(string) } var levelDatas = []levelData{ // No, it's not a map! Indexing into a slice is faster {Name: "SILENT", Short: "SLT", Hook: nil}, {Name: "PANIC", Short: "PNC", Hook: func(msg string) { panic(msg) }}, {Name: "FATAL", Short: "FTL", Hook: nil}, {Name: "ERROR", Short: "ERR", Hook: nil}, {Name: "WARN", Short: "WRN", Hook: nil}, {Name: "NOTICE", Short: "NOT", Hook: nil}, {Name: "INFO", Short: "INF", Hook: nil}, {Name: "DEBUG", Short: "DBG", Hook: nil}, {Name: "TRACE", Short: "TRC", Hook: nil}, } // To sends the resulting log message to a given logger func (l level) To(log logger) *envelope { return &envelope{ log: log, lvl: l, err: nil, } } // Msg emits the given message to the default logger. func (l level) Msg(format string, args ...any) { l.To(0).Msg(format, args...) } // WithStack dumps a stack trace after the log message func (l level) WithStack() *envelope { return l.To(0).WithStack() } // WithStackAs dumps a stack trace after the log message using the given log level func (l level) WithStackAs(lvl level) *envelope { return l.To(0).WithStackAs(lvl) } // Err attaches an error to the log message. func (l level) Err(err error) *envelope { return l.To(0).Err(err) } // Arg attaches a named argument to the log message. func (l level) Arg(name string, value any) *envelope { return l.To(0).Arg(name, value) } // If executes the given function only, if the logger is set to func (l level) If(msg func(Fn)) { l.To(0).If(msg) } // hook executes the associated hook, if any func (l level) hook(msg string) { if levelDatas[l].Hook != nil { levelDatas[l].Hook(msg) } } func (l level) String() string { return levelDatas[l].Name } // Explain dumps the current log configuration to the default logger using the given log level func (l level) Explain() { l.To(0).Explain() } func ParseLevel(levelstring string) (level, error) { switch strings.ToLower(levelstring) { case "silent", "off", "none": return SILENT, nil case "panic", "emergency", "emerg": return PANIC, nil case "fatal", "crit", "critical", "alert": return FATAL, nil case "error": return ERROR, nil case "warn", "warning": return WARN, nil case "notice": return NOTICE, nil case "info": return INFO, nil case "debug": return DEBUG, nil case "trace": return TRACE, nil } return 0, fmt.Errorf("invalid loglevel '%v'", levelstring) }