2023-08-04 23:35:49 +00:00
|
|
|
// Package zwrap provides a wrapper for zerolog.Logger that implements the standard library's log.Logger methods,
|
|
|
|
// as well as other common logging methods as an attempt to provide compatibility with other logging libraries.
|
2023-08-04 22:58:35 +00:00
|
|
|
package zwrap
|
|
|
|
|
|
|
|
import (
|
2023-08-27 21:05:59 +00:00
|
|
|
"bytes"
|
2023-08-04 22:58:35 +00:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/rs/zerolog"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Logger struct {
|
|
|
|
*zerolog.Logger
|
2024-05-20 10:27:50 +00:00
|
|
|
mu *sync.RWMutex
|
2023-08-05 06:23:47 +00:00
|
|
|
|
|
|
|
prefix string
|
|
|
|
printLevel zerolog.Level
|
2024-05-20 10:27:50 +00:00
|
|
|
forceLevel *zerolog.Level
|
|
|
|
noPanic bool
|
|
|
|
noFatal bool
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
2024-05-20 03:26:32 +00:00
|
|
|
func (l *Logger) Warning(args ...any) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.printLn(l.Logger.Warn(), false, args...)
|
2024-05-20 03:26:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Warningln(args ...any) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.printLn(l.Logger.Warn(), false, args...)
|
2024-05-20 03:26:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) V(level int) bool {
|
|
|
|
if level > 127 || level < 0 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if l.Logger.GetLevel() > zerolog.Level(int8(level)) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2023-08-04 22:58:35 +00:00
|
|
|
func (l *Logger) SetPrefix(prefix string) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.Lock()
|
2023-08-04 22:58:35 +00:00
|
|
|
l.prefix = prefix
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.Unlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
2023-08-05 06:23:47 +00:00
|
|
|
func (l *Logger) SetPrintLevel(level zerolog.Level) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.Lock()
|
2023-08-05 06:23:47 +00:00
|
|
|
l.printLevel = level
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.Unlock()
|
2023-08-05 06:23:47 +00:00
|
|
|
}
|
|
|
|
|
2023-08-04 22:58:35 +00:00
|
|
|
func (l *Logger) Prefix() string {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
p := l.myPrefix()
|
|
|
|
l.mu.RUnlock()
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) myPrefix() string {
|
2023-08-04 22:58:35 +00:00
|
|
|
return l.prefix
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Println(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.WithLevel(l.printLevel), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-05 06:23:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Printf(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
var str string
|
|
|
|
switch {
|
|
|
|
case len(v) == 0:
|
|
|
|
str = format
|
|
|
|
case len(v) == 1:
|
|
|
|
str = fmt.Sprintf(format, v[0])
|
|
|
|
default:
|
|
|
|
str = fmt.Sprintf(format, v...)
|
|
|
|
}
|
|
|
|
l.printLn(l.Logger.WithLevel(l.printLevel), false, str)
|
|
|
|
l.mu.RUnlock()
|
2023-08-05 06:23:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Print(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.WithLevel(l.printLevel), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Fatal(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
var ok bool
|
|
|
|
if _, v, ok = l.checkFatalBypass("", v...); ok {
|
|
|
|
l.printLn(l.Logger.Fatal(), true, v...)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Error(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Fatalf(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
var ok bool
|
|
|
|
if format, v, ok = l.checkFatalBypass(format, v...); ok {
|
|
|
|
l.printLn(l.Logger.Fatal(), true, fmt.Sprintf(format, v...))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Error(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Fatalln(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
var ok bool
|
|
|
|
if _, v, ok = l.checkFatalBypass("", v...); ok {
|
|
|
|
l.printLn(l.Logger.Fatal(), true, v...)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Error(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Panic(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
var ok bool
|
|
|
|
if _, v, ok = l.checkPanicBypass("", v...); ok {
|
|
|
|
l.printLn(l.Logger.Panic(), true, v...)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Error(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Panicf(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
var ok bool
|
|
|
|
if format, v, ok = l.checkPanicBypass(format, v...); ok {
|
|
|
|
l.printLn(l.Logger.Panic(), true, fmt.Sprintf(format, v...))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Error(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Panicln(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
var ok bool
|
|
|
|
if _, v, ok = l.checkPanicBypass("", v...); ok {
|
|
|
|
l.printLn(l.Logger.Panic(), true, v...)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Error(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Errorf(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Error(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Warnf(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Warn(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Infof(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Info(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Debugf(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Debug(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Tracef(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Trace(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Error(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Error(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Warn(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Warn(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Info(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Info(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Debug(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Debug(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Trace(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Trace(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Errorln(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Error(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Warnln(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Warn(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Infoln(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Info(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Debugln(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Debug(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Traceln(v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Trace(), false, v...)
|
|
|
|
l.mu.RUnlock()
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
|
2023-08-27 19:21:52 +00:00
|
|
|
func (l *Logger) Verbosef(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Trace(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-27 19:21:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Noticef(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Info(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-27 19:21:52 +00:00
|
|
|
}
|
|
|
|
func (l *Logger) Warningf(format string, v ...interface{}) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
|
|
|
l.printLn(l.Logger.Warn(), false, fmt.Sprintf(format, v...))
|
|
|
|
l.mu.RUnlock()
|
2023-08-27 19:21:52 +00:00
|
|
|
}
|
|
|
|
|
2023-09-13 07:56:09 +00:00
|
|
|
func (l *Logger) WithPrefix(prefix string) *Logger {
|
|
|
|
l.SetPrefix(prefix)
|
|
|
|
return l
|
|
|
|
}
|
|
|
|
|
2024-02-14 01:32:39 +00:00
|
|
|
func (l *Logger) Logf(format string, v ...interface{}) {
|
|
|
|
l.Printf(format, v...)
|
|
|
|
}
|
|
|
|
|
2023-09-13 07:56:09 +00:00
|
|
|
func (l *Logger) WithFields(fields map[string]interface{}) *Logger {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
2023-09-13 07:56:09 +00:00
|
|
|
nl := l.Logger.With().Fields(fields).Logger()
|
|
|
|
l.Logger = &nl
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RUnlock()
|
2023-09-13 07:56:09 +00:00
|
|
|
return l
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetLevel is compatibility for ghettovoice/gosip/log.Logger
|
2024-05-20 10:27:50 +00:00
|
|
|
func (l *Logger) SetLevel(level any) {
|
|
|
|
l.mu.Lock()
|
|
|
|
nl := l.Logger.Level(castToZlogLevel(level))
|
2023-09-13 07:56:09 +00:00
|
|
|
l.Logger = &nl
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.Unlock()
|
2023-09-13 07:56:09 +00:00
|
|
|
}
|
|
|
|
|
2023-08-27 20:50:30 +00:00
|
|
|
func (l *Logger) Write(p []byte) (n int, err error) {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
2023-08-27 21:05:59 +00:00
|
|
|
l.Logger.WithLevel(l.printLevel).Msg(string(bytes.TrimSuffix(p, []byte("\n"))))
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RUnlock()
|
2023-08-27 20:50:30 +00:00
|
|
|
return len(p), nil
|
|
|
|
}
|
|
|
|
|
2023-08-05 06:23:37 +00:00
|
|
|
func (l *Logger) Output(calldepth int, s string) error {
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RLock()
|
2023-08-05 06:23:37 +00:00
|
|
|
event := l.Logger.Info()
|
|
|
|
if calldepth != 2 {
|
|
|
|
if l.prefix != "" {
|
|
|
|
zerolog.CallerFieldName = "caller_file"
|
|
|
|
}
|
|
|
|
event.CallerSkipFrame(calldepth)
|
|
|
|
event = event.Caller()
|
|
|
|
}
|
|
|
|
event.Msg(s)
|
|
|
|
zerolog.CallerFieldName = "caller"
|
2024-05-20 10:27:50 +00:00
|
|
|
l.mu.RUnlock()
|
2023-08-05 06:23:37 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-05-20 10:27:50 +00:00
|
|
|
func (l *Logger) transformZEvent(e *zerolog.Event) *zerolog.Event {
|
|
|
|
switch *l.forceLevel {
|
|
|
|
case zerolog.PanicLevel:
|
|
|
|
if !l.noPanic {
|
|
|
|
e = l.Logger.Panic()
|
|
|
|
}
|
|
|
|
case zerolog.FatalLevel:
|
|
|
|
if !l.noFatal {
|
|
|
|
e = l.Logger.Fatal()
|
|
|
|
}
|
|
|
|
case zerolog.ErrorLevel:
|
|
|
|
e = l.Logger.Error()
|
|
|
|
case zerolog.WarnLevel:
|
|
|
|
e = l.Logger.Warn()
|
|
|
|
case zerolog.InfoLevel:
|
|
|
|
e = l.Logger.Info()
|
|
|
|
case zerolog.DebugLevel:
|
|
|
|
e = l.Logger.Debug()
|
|
|
|
case zerolog.TraceLevel:
|
|
|
|
e = l.Logger.Trace()
|
|
|
|
default:
|
|
|
|
panic(fmt.Sprintf("invalid logger config, bad force level %v", l.forceLevel))
|
|
|
|
}
|
|
|
|
return e
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) printLn(e *zerolog.Event, preserve bool, v ...interface{}) {
|
|
|
|
if l.forceLevel != nil && !preserve {
|
|
|
|
e = l.transformZEvent(e)
|
|
|
|
}
|
|
|
|
if len(v) == 0 {
|
|
|
|
e.Msg("")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if len(v) == 1 {
|
|
|
|
e.Msg(fmt.Sprint(v[0]))
|
|
|
|
return
|
|
|
|
}
|
2023-08-04 22:58:35 +00:00
|
|
|
strBuf := strBufs.Get().(*strings.Builder)
|
2023-08-27 20:50:30 +00:00
|
|
|
for i, val := range v {
|
2023-08-04 22:58:35 +00:00
|
|
|
if i > 0 {
|
|
|
|
strBuf.WriteString(" ")
|
|
|
|
}
|
2023-08-27 20:50:30 +00:00
|
|
|
strBuf.WriteString(fmt.Sprint(val))
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
|
|
|
e.Msg(strBuf.String())
|
|
|
|
strBuf.Reset()
|
|
|
|
strBufs.Put(strBuf)
|
|
|
|
}
|
|
|
|
|
2023-08-04 23:28:12 +00:00
|
|
|
type prefixHook struct {
|
2024-05-20 10:27:50 +00:00
|
|
|
parent *Logger
|
2023-08-04 23:28:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (h prefixHook) Run(e *zerolog.Event, _ zerolog.Level, _ string) {
|
|
|
|
if h.parent.Prefix() != "" {
|
2024-05-20 10:27:50 +00:00
|
|
|
e.Str("caller", h.parent.myPrefix())
|
2023-08-04 23:28:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Wrap(l zerolog.Logger) *Logger {
|
|
|
|
wrapped := &Logger{
|
2024-05-20 10:27:50 +00:00
|
|
|
mu: &sync.RWMutex{},
|
2023-08-05 06:23:47 +00:00
|
|
|
printLevel: zerolog.InfoLevel,
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|
2023-08-04 23:28:12 +00:00
|
|
|
p := prefixHook{wrapped}
|
|
|
|
l = l.Hook(p)
|
|
|
|
wrapped.Logger = &l
|
|
|
|
return wrapped
|
2023-08-04 22:58:35 +00:00
|
|
|
}
|