fermentord/vendor/github.com/d2r2/go-logger/package.go
Søren Rasmussen 07a23c1845
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Upgrade to go 1.20 and add vendor catalog
2023-04-22 10:37:23 +02:00

260 lines
6 KiB
Go

package logger
import (
"fmt"
"log/syslog"
"os"
"sync"
"github.com/davecgh/go-spew/spew"
)
type PackageLog interface {
Printf(level LogLevel, format string, args ...interface{})
Print(level LogLevel, args ...interface{})
Debugf(format string, args ...interface{})
Debug(args ...interface{})
Infof(format string, args ...interface{})
Info(args ...interface{})
Notifyf(format string, args ...interface{})
Notify(args ...interface{})
Warningf(format string, args ...interface{})
Warnf(format string, args ...interface{})
Warning(args ...interface{})
Warn(args ...interface{})
Errorf(format string, args ...interface{})
Error(args ...interface{})
Panicf(format string, args ...interface{})
Panic(args ...interface{})
Fatalf(format string, args ...interface{})
Fatal(args ...interface{})
}
type Package struct {
sync.RWMutex
parent *Logger
packageName string
level LogLevel
syslog *syslog.Writer
}
// Static cast to verify that object implement interface.
var _ PackageLog = &Package{}
func (v *Package) Close() error {
v.Lock()
defer v.Unlock()
if v.syslog != nil {
err := v.syslog.Close()
v.syslog = nil
if err != nil {
return err
}
}
return nil
}
func (v *Package) SetLogLevel(level LogLevel) {
v.Lock()
defer v.Unlock()
v.level = level
}
func (v *Package) GetLogLevel() LogLevel {
v.RLock()
defer v.RUnlock()
return v.level
}
func (v *Package) getSyslog(level LogLevel, options FormatOptions,
appName string) (*syslog.Writer, error) {
v.Lock()
defer v.Unlock()
if v.syslog == nil {
tag := metaFmtStr(false, level, options, appName,
v.packageName, "", "%[2]s-%[3]s")
sl, err := syslog.New(syslog.LOG_DEBUG, tag)
if err != nil {
err = spew.Errorf("Failed to connect to syslog: %v\n", err)
return nil, err
}
v.syslog = sl
}
return v.syslog, nil
}
func (v *Package) writeToSyslog(options FormatOptions,
level LogLevel, appName string, msg string) error {
sl, err := v.getSyslog(level, options, appName)
if err != nil {
return err
}
switch level {
case DebugLevel:
return sl.Debug(msg)
case InfoLevel:
return sl.Info(msg)
case NotifyLevel:
return sl.Notice(msg)
case WarnLevel:
return sl.Warning(msg)
case ErrorLevel:
return sl.Err(msg)
case PanicLevel:
return sl.Crit(msg)
case FatalLevel:
return sl.Emerg(msg)
default:
return sl.Debug(msg)
}
}
type printLog func(log *Log, msg interface{})
type getMessage func(colored bool) interface{}
func printLogs(logs []*Log, level LogLevel, prnt printLog, getMsg getMessage) {
// Console and custom logs output
for _, log := range logs {
if log.level >= level {
prnt(log, getMsg(log.colored))
}
}
}
func (v *Package) print(level LogLevel, msg string) {
lvl := v.GetLogLevel()
if lvl >= level {
appName := getApplicationName()
logs := v.parent.getLogs()
options := v.parent.GetFormatOptions()
out1 := FormatMessage(options, level, v.packageName, msg, false)
// File output
if lf := v.parent.GetLogFileInfo(); lf != nil {
rotateMaxSize := v.parent.GetRotateMaxSize()
rotateMaxCount := v.parent.GetRotateMaxCount()
if err := lf.writeToFile(out1, rotateMaxSize, rotateMaxCount); err != nil {
err = spew.Errorf("Failed to report syslog message %q: %v\n", out1, err)
printLogs(logs, FatalLevel,
func(log *Log, msg interface{}) {
log.log.Fatal(msg)
},
func(colored bool) interface{} {
return err
})
}
}
// Syslog output
if v.parent.GetSyslogEnabled() {
if err := v.writeToSyslog(options, level, appName, msg); err != nil {
err = spew.Errorf("Failed to report syslog message %q: %v\n", msg, err)
printLogs(logs, FatalLevel,
func(log *Log, msg interface{}) {
log.log.Fatal(msg)
},
func(colored bool) interface{} {
return err
})
}
}
// Console and custom logs output
outColored1 := FormatMessage(options, level, v.packageName, msg, true)
printLogs(logs, level,
func(log *Log, msg interface{}) {
log.log.Print(msg)
},
func(colored bool) interface{} {
if colored {
return outColored1 + fmt.Sprintln()
} else {
return out1 + fmt.Sprintln()
}
})
// Check critical events
if level == PanicLevel {
panic(out1)
} else if level == FatalLevel {
os.Exit(1)
}
}
}
func (v *Package) Printf(level LogLevel, format string, args ...interface{}) {
lvl := v.GetLogLevel()
if lvl >= level {
msg := spew.Sprintf(format, args...)
v.print(level, msg)
}
}
func (v *Package) Print(level LogLevel, args ...interface{}) {
lvl := v.GetLogLevel()
if lvl >= level {
msg := fmt.Sprint(args...)
v.print(level, msg)
}
}
func (v *Package) Debugf(format string, args ...interface{}) {
v.Printf(DebugLevel, format, args...)
}
func (v *Package) Debug(args ...interface{}) {
v.Print(DebugLevel, args...)
}
func (v *Package) Infof(format string, args ...interface{}) {
v.Printf(InfoLevel, format, args...)
}
func (v *Package) Info(args ...interface{}) {
v.Print(InfoLevel, args...)
}
func (v *Package) Notifyf(format string, args ...interface{}) {
v.Printf(NotifyLevel, format, args...)
}
func (v *Package) Notify(args ...interface{}) {
v.Print(NotifyLevel, args...)
}
func (v *Package) Warningf(format string, args ...interface{}) {
v.Printf(WarnLevel, format, args...)
}
func (v *Package) Warnf(format string, args ...interface{}) {
v.Printf(WarnLevel, format, args...)
}
func (v *Package) Warning(args ...interface{}) {
v.Print(WarnLevel, args...)
}
func (v *Package) Warn(args ...interface{}) {
v.Print(WarnLevel, args...)
}
func (v *Package) Errorf(format string, args ...interface{}) {
v.Printf(ErrorLevel, format, args...)
}
func (v *Package) Error(args ...interface{}) {
v.Print(ErrorLevel, args...)
}
func (v *Package) Panicf(format string, args ...interface{}) {
v.Printf(PanicLevel, format, args...)
}
func (v *Package) Panic(args ...interface{}) {
v.Print(PanicLevel, args...)
}
func (v *Package) Fatalf(format string, args ...interface{}) {
v.Printf(FatalLevel, format, args...)
}
func (v *Package) Fatal(args ...interface{}) {
v.Print(FatalLevel, args...)
}