Feat (breaking changes?): panic/fatal bypasses, force level, add unit tests
This commit is contained in:
parent
dd9ca58d52
commit
e99bc8f197
72
bypass.go
Normal file
72
bypass.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package zwrap
|
||||||
|
|
||||||
|
func (l *Logger) checkPanicBypass(fmt string, v ...interface{}) (string, []interface{}, bool) {
|
||||||
|
if !l.noPanic {
|
||||||
|
return fmt, v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
if fmt != "" {
|
||||||
|
fmt = "[PANIC BYPASSED] " + fmt
|
||||||
|
return fmt, v, false
|
||||||
|
}
|
||||||
|
|
||||||
|
nv := make([]interface{}, len(v)+1)
|
||||||
|
nv[0] = "[PANIC BYPASSED]"
|
||||||
|
copy(nv[1:], v)
|
||||||
|
v = nil
|
||||||
|
return fmt, nv, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) checkFatalBypass(fmt string, v ...interface{}) (string, []interface{}, bool) {
|
||||||
|
if !l.noFatal {
|
||||||
|
return fmt, v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
if fmt != "" {
|
||||||
|
fmt = "[FATAL BYPASSED] " + fmt
|
||||||
|
return fmt, v, false
|
||||||
|
}
|
||||||
|
|
||||||
|
nv := make([]interface{}, len(v)+1)
|
||||||
|
nv[0] = "[FATAL BYPASSED]"
|
||||||
|
copy(nv[1:], v)
|
||||||
|
v = nil
|
||||||
|
return fmt, nv, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) NoPanics(b bool) {
|
||||||
|
l.mu.Lock()
|
||||||
|
l.noPanic = b
|
||||||
|
l.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) NoFatals(b bool) {
|
||||||
|
l.mu.Lock()
|
||||||
|
l.noFatal = b
|
||||||
|
l.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) WithNoPanics() *Logger {
|
||||||
|
l.NoPanics(true)
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) WithNoFatals() *Logger {
|
||||||
|
l.NoFatals(true)
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) ForceLevel(level any) {
|
||||||
|
l.mu.Lock()
|
||||||
|
nl := castToZlogLevel(level)
|
||||||
|
l.forceLevel = &nl
|
||||||
|
l.printLevel = nl
|
||||||
|
nll := l.Logger.Level(nl)
|
||||||
|
l.Logger = &nll
|
||||||
|
l.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) WithForceLevel(level uint32) *Logger {
|
||||||
|
l.ForceLevel(level)
|
||||||
|
return l
|
||||||
|
}
|
10
go.mod
10
go.mod
@ -1,11 +1,11 @@
|
|||||||
module git.tcp.direct/kayos/zwrap
|
module git.tcp.direct/kayos/zwrap
|
||||||
|
|
||||||
go 1.18
|
go 1.20
|
||||||
|
|
||||||
require github.com/rs/zerolog v1.30.0
|
require github.com/rs/zerolog v1.32.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
golang.org/x/sys v0.18.0 // indirect
|
golang.org/x/sys v0.20.0 // indirect
|
||||||
)
|
)
|
||||||
|
22
go.sum
22
go.sum
@ -1,14 +1,16 @@
|
|||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c=
|
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
|
||||||
github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w=
|
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||||
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
84
level.go
Normal file
84
level.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package zwrap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Level interface {
|
||||||
|
int | uint | int8 | uint8 | int16 | uint16 | int32 | uint32 | int64 | uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func castToZlogLevel(level any) zerolog.Level {
|
||||||
|
switch casted := level.(type) {
|
||||||
|
case int:
|
||||||
|
return toZlogLevel[int](casted)
|
||||||
|
case int8:
|
||||||
|
return toZlogLevel[int8](casted)
|
||||||
|
case int16:
|
||||||
|
return toZlogLevel[int16](casted)
|
||||||
|
case int32:
|
||||||
|
return toZlogLevel[int32](casted)
|
||||||
|
case int64:
|
||||||
|
return toZlogLevel[int64](casted)
|
||||||
|
case uint:
|
||||||
|
return toZlogLevel[uint](casted)
|
||||||
|
case uint8:
|
||||||
|
return toZlogLevel[uint8](casted)
|
||||||
|
case uint16:
|
||||||
|
return toZlogLevel[uint16](casted)
|
||||||
|
case uint32:
|
||||||
|
return toZlogLevel[uint32](casted)
|
||||||
|
case uint64:
|
||||||
|
return toZlogLevel[uint64](casted)
|
||||||
|
case string:
|
||||||
|
if parsed, err := zerolog.ParseLevel(casted); err == nil {
|
||||||
|
return parsed
|
||||||
|
} else {
|
||||||
|
panic(fmt.Sprintf("invalid log level string %v: %v", level, err))
|
||||||
|
}
|
||||||
|
case zerolog.Level:
|
||||||
|
return casted
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("invalid log level type (%T): %v", level, level))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toZlogLevel[T Level](level T) zerolog.Level {
|
||||||
|
switch casted := any(level).(type) {
|
||||||
|
case uint32: // compat
|
||||||
|
switch {
|
||||||
|
case casted == 0:
|
||||||
|
return zerolog.PanicLevel
|
||||||
|
case casted == 1:
|
||||||
|
return zerolog.FatalLevel
|
||||||
|
case casted == 2:
|
||||||
|
return zerolog.ErrorLevel
|
||||||
|
case casted == 3:
|
||||||
|
return zerolog.WarnLevel
|
||||||
|
case casted == 4:
|
||||||
|
return zerolog.InfoLevel
|
||||||
|
case casted == 5:
|
||||||
|
return zerolog.DebugLevel
|
||||||
|
case casted == 6:
|
||||||
|
return zerolog.TraceLevel
|
||||||
|
default:
|
||||||
|
if casted < 0 {
|
||||||
|
return zerolog.TraceLevel
|
||||||
|
}
|
||||||
|
if casted > 5 {
|
||||||
|
return zerolog.PanicLevel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case int16, int32, int64, int, uint, uint8, uint16, uint64, int8:
|
||||||
|
if level < 0 {
|
||||||
|
return zerolog.TraceLevel
|
||||||
|
}
|
||||||
|
if level > 5 {
|
||||||
|
return zerolog.PanicLevel
|
||||||
|
}
|
||||||
|
return zerolog.Level(int8(level))
|
||||||
|
}
|
||||||
|
return zerolog.TraceLevel
|
||||||
|
}
|
108
level_test.go
Normal file
108
level_test.go
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package zwrap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCastToZlogLevel(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
level any
|
||||||
|
want zerolog.Level
|
||||||
|
}{
|
||||||
|
{"int", 3, zerolog.ErrorLevel},
|
||||||
|
{"int8", int8(4), zerolog.FatalLevel},
|
||||||
|
{"int16", int16(2), zerolog.WarnLevel},
|
||||||
|
{"int32", int32(1), zerolog.InfoLevel},
|
||||||
|
{"int64", int64(5), zerolog.PanicLevel},
|
||||||
|
{"uint", uint(6), zerolog.PanicLevel},
|
||||||
|
{"uint8", uint8(0), zerolog.DebugLevel},
|
||||||
|
{"uint16", uint16(4), zerolog.FatalLevel},
|
||||||
|
{"uint32", uint32(3), zerolog.WarnLevel},
|
||||||
|
{"uint64", uint64(2), zerolog.WarnLevel},
|
||||||
|
{"string", "info", zerolog.InfoLevel},
|
||||||
|
{"zerolog.Level", zerolog.DebugLevel, zerolog.DebugLevel},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := castToZlogLevel(tt.level); got != tt.want {
|
||||||
|
t.Errorf("castToZlogLevel() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCastToZlogLevel_Panic(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
level any
|
||||||
|
}{
|
||||||
|
{"invalid type", 3.14},
|
||||||
|
{"invalid string", "invalid"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r == nil {
|
||||||
|
t.Errorf("castToZlogLevel() did not panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
castToZlogLevel(tt.level)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestToZlogLevel(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
level any
|
||||||
|
want zerolog.Level
|
||||||
|
}{
|
||||||
|
{"int8", int8(3), zerolog.ErrorLevel},
|
||||||
|
{"int16", int16(2), zerolog.WarnLevel},
|
||||||
|
{"int32", int32(1), zerolog.InfoLevel},
|
||||||
|
{"int64", int64(5), zerolog.PanicLevel},
|
||||||
|
{"uint", uint(0), zerolog.DebugLevel},
|
||||||
|
{"uint8", uint8(6), zerolog.PanicLevel},
|
||||||
|
{"uint16", uint16(4), zerolog.FatalLevel},
|
||||||
|
{"uint32", uint32(3), zerolog.WarnLevel},
|
||||||
|
{"uint64", uint64(2), zerolog.WarnLevel},
|
||||||
|
{"-1 trace level", -1, zerolog.TraceLevel},
|
||||||
|
{"> limit level", uint(7), zerolog.PanicLevel},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
switch casted := tt.level.(type) {
|
||||||
|
case int8:
|
||||||
|
if got := toZlogLevel[int8](casted); got != tt.want {
|
||||||
|
t.Errorf("toZlogLevel(%v) = %v, want %v", tt.level, got, tt.want)
|
||||||
|
}
|
||||||
|
case int16:
|
||||||
|
if got := toZlogLevel[int16](casted); got != tt.want {
|
||||||
|
t.Errorf("toZlogLevel(%v) = %v, want %v", tt.level, got, tt.want)
|
||||||
|
}
|
||||||
|
case int32:
|
||||||
|
if got := toZlogLevel[int32](casted); got != tt.want {
|
||||||
|
t.Errorf("toZlogLevel(%v) = %v, want %v", tt.level, got, tt.want)
|
||||||
|
}
|
||||||
|
case int64:
|
||||||
|
if got := toZlogLevel[int64](casted); got != tt.want {
|
||||||
|
t.Errorf("toZlogLevel(%v) = %v, want %v", tt.level, got, tt.want)
|
||||||
|
}
|
||||||
|
case uint:
|
||||||
|
if got := toZlogLevel[uint](casted); got != tt.want {
|
||||||
|
t.Errorf("toZlogLevel(%v) = %v, want %v", tt.level, got, tt.want)
|
||||||
|
}
|
||||||
|
case uint8:
|
||||||
|
if got := toZlogLevel[uint8](casted); got != tt.want {
|
||||||
|
t.Errorf("toZlogLevel(%v) = %v, want %v", tt.level, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
43
restore_colors_test.go
Normal file
43
restore_colors_test.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package zwrap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type colorTester struct {
|
||||||
|
t *testing.T
|
||||||
|
last []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *colorTester) Write(p []byte) (n int, err error) {
|
||||||
|
if len(c.last) == 0 {
|
||||||
|
c.last = make([]byte, len(p))
|
||||||
|
copy(c.last, p)
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
if bytes.Equal(c.last, p) {
|
||||||
|
c.t.Errorf("\ncaught second output: %s\nwhich is the same as the first: %s", string(p), string(c.last))
|
||||||
|
}
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLegacyColorizer(t *testing.T) {
|
||||||
|
tw := &colorTester{t: t}
|
||||||
|
zlc := zerolog.NewConsoleWriter()
|
||||||
|
zlc.Out = tw
|
||||||
|
zlc.NoColor = false
|
||||||
|
zl := Wrap(zerolog.New(zlc))
|
||||||
|
zl.Trace("yeet")
|
||||||
|
if len(tw.last) == 0 {
|
||||||
|
t.Fatalf("test writer busted")
|
||||||
|
}
|
||||||
|
zlc = zerolog.NewConsoleWriter()
|
||||||
|
zlc.FormatLevel = LogLevelFmt(false)
|
||||||
|
zlc.NoColor = false
|
||||||
|
zlc.Out = tw
|
||||||
|
zl = Wrap(zerolog.New(zlc))
|
||||||
|
zl.Trace("yeet")
|
||||||
|
}
|
306
wrap.go
306
wrap.go
@ -13,18 +13,21 @@ import (
|
|||||||
|
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
*zerolog.Logger
|
*zerolog.Logger
|
||||||
*sync.RWMutex
|
mu *sync.RWMutex
|
||||||
|
|
||||||
prefix string
|
prefix string
|
||||||
printLevel zerolog.Level
|
printLevel zerolog.Level
|
||||||
|
forceLevel *zerolog.Level
|
||||||
|
noPanic bool
|
||||||
|
noFatal bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Warning(args ...any) {
|
func (l *Logger) Warning(args ...any) {
|
||||||
l.Logger.Warn().Msg(fmt.Sprint(args...))
|
l.printLn(l.Logger.Warn(), false, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Warningln(args ...any) {
|
func (l *Logger) Warningln(args ...any) {
|
||||||
l.Logger.Warn().Msg(fmt.Sprintln(args...))
|
l.printLn(l.Logger.Warn(), false, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) V(level int) bool {
|
func (l *Logger) V(level int) bool {
|
||||||
@ -38,176 +41,226 @@ func (l *Logger) V(level int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) SetPrefix(prefix string) {
|
func (l *Logger) SetPrefix(prefix string) {
|
||||||
l.Lock()
|
l.mu.Lock()
|
||||||
l.prefix = prefix
|
l.prefix = prefix
|
||||||
l.Unlock()
|
l.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) SetPrintLevel(level zerolog.Level) {
|
func (l *Logger) SetPrintLevel(level zerolog.Level) {
|
||||||
l.Lock()
|
l.mu.Lock()
|
||||||
l.printLevel = level
|
l.printLevel = level
|
||||||
l.Unlock()
|
l.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Prefix() string {
|
func (l *Logger) Prefix() string {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
defer l.RUnlock()
|
p := l.myPrefix()
|
||||||
|
l.mu.RUnlock()
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) myPrefix() string {
|
||||||
return l.prefix
|
return l.prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Println(v ...interface{}) {
|
func (l *Logger) Println(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.WithLevel(l.printLevel).Msg(fmt.Sprint(v...))
|
l.printLn(l.Logger.WithLevel(l.printLevel), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Printf(format string, v ...interface{}) {
|
func (l *Logger) Printf(format string, v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.WithLevel(l.printLevel).Msgf(format, v...)
|
var str string
|
||||||
l.RUnlock()
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Print(v ...interface{}) {
|
func (l *Logger) Print(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.WithLevel(l.printLevel).Msg(fmt.Sprint(v...))
|
l.printLn(l.Logger.WithLevel(l.printLevel), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Fatal(v ...interface{}) {
|
func (l *Logger) Fatal(v ...interface{}) {
|
||||||
// Don't check mutex here because we're exiting anyway.
|
var ok bool
|
||||||
printLn(l.Logger.Fatal(), v...)
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Fatalf(format string, v ...interface{}) {
|
func (l *Logger) Fatalf(format string, v ...interface{}) {
|
||||||
// Don't check mutex here because we're exiting anyway.
|
var ok bool
|
||||||
l.Logger.Fatal().Msgf(format, v...)
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Fatalln(v ...interface{}) {
|
func (l *Logger) Fatalln(v ...interface{}) {
|
||||||
// Don't check mutex here because we're exiting anyway.
|
var ok bool
|
||||||
printLn(l.Logger.Fatal(), v...)
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Panic(v ...interface{}) {
|
func (l *Logger) Panic(v ...interface{}) {
|
||||||
// Don't check mutex here because we're panicking anyway.
|
var ok bool
|
||||||
printLn(l.Logger.Panic(), v...)
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Panicf(format string, v ...interface{}) {
|
func (l *Logger) Panicf(format string, v ...interface{}) {
|
||||||
// Don't check mutex here because we're panicking anyway.
|
var ok bool
|
||||||
l.Logger.Panic().Msgf(format, v...)
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Panicln(v ...interface{}) {
|
func (l *Logger) Panicln(v ...interface{}) {
|
||||||
// Don't check mutex here because we're panicking anyway.
|
var ok bool
|
||||||
printLn(l.Logger.Panic(), v...)
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Errorf(format string, v ...interface{}) {
|
func (l *Logger) Errorf(format string, v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.Error().Msgf(format, v...)
|
l.printLn(l.Logger.Error(), false, fmt.Sprintf(format, v...))
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Warnf(format string, v ...interface{}) {
|
func (l *Logger) Warnf(format string, v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.Warn().Msgf(format, v...)
|
l.printLn(l.Logger.Warn(), false, fmt.Sprintf(format, v...))
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Infof(format string, v ...interface{}) {
|
func (l *Logger) Infof(format string, v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.Info().Msgf(format, v...)
|
l.printLn(l.Logger.Info(), false, fmt.Sprintf(format, v...))
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Debugf(format string, v ...interface{}) {
|
func (l *Logger) Debugf(format string, v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.Debug().Msgf(format, v...)
|
l.printLn(l.Logger.Debug(), false, fmt.Sprintf(format, v...))
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Tracef(format string, v ...interface{}) {
|
func (l *Logger) Tracef(format string, v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.Trace().Msgf(format, v...)
|
l.printLn(l.Logger.Trace(), false, fmt.Sprintf(format, v...))
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Error(v ...interface{}) {
|
func (l *Logger) Error(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Error(), v...)
|
l.printLn(l.Logger.Error(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Warn(v ...interface{}) {
|
func (l *Logger) Warn(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Warn(), v...)
|
l.printLn(l.Logger.Warn(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Info(v ...interface{}) {
|
func (l *Logger) Info(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Info(), v...)
|
l.printLn(l.Logger.Info(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Debug(v ...interface{}) {
|
func (l *Logger) Debug(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Debug(), v...)
|
l.printLn(l.Logger.Debug(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Trace(v ...interface{}) {
|
func (l *Logger) Trace(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Trace(), v...)
|
l.printLn(l.Logger.Trace(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Errorln(v ...interface{}) {
|
func (l *Logger) Errorln(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Error(), v...)
|
l.printLn(l.Logger.Error(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Warnln(v ...interface{}) {
|
func (l *Logger) Warnln(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Warn(), v...)
|
l.printLn(l.Logger.Warn(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Infoln(v ...interface{}) {
|
func (l *Logger) Infoln(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Info(), v...)
|
l.printLn(l.Logger.Info(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Debugln(v ...interface{}) {
|
func (l *Logger) Debugln(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Debug(), v...)
|
l.printLn(l.Logger.Debug(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Traceln(v ...interface{}) {
|
func (l *Logger) Traceln(v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
printLn(l.Logger.Trace(), v...)
|
l.printLn(l.Logger.Trace(), false, v...)
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Verbosef(format string, v ...interface{}) {
|
func (l *Logger) Verbosef(format string, v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.Trace().Msgf(format, v...)
|
l.printLn(l.Logger.Trace(), false, fmt.Sprintf(format, v...))
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Noticef(format string, v ...interface{}) {
|
func (l *Logger) Noticef(format string, v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.Info().Msgf(format, v...)
|
l.printLn(l.Logger.Info(), false, fmt.Sprintf(format, v...))
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
func (l *Logger) Warningf(format string, v ...interface{}) {
|
func (l *Logger) Warningf(format string, v ...interface{}) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.Warn().Msgf(format, v...)
|
l.printLn(l.Logger.Warn(), false, fmt.Sprintf(format, v...))
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) WithPrefix(prefix string) *Logger {
|
func (l *Logger) WithPrefix(prefix string) *Logger {
|
||||||
@ -220,50 +273,30 @@ func (l *Logger) Logf(format string, v ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) WithFields(fields map[string]interface{}) *Logger {
|
func (l *Logger) WithFields(fields map[string]interface{}) *Logger {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
nl := l.Logger.With().Fields(fields).Logger()
|
nl := l.Logger.With().Fields(fields).Logger()
|
||||||
l.Logger = &nl
|
l.Logger = &nl
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLevel is compatibility for ghettovoice/gosip/log.Logger
|
// SetLevel is compatibility for ghettovoice/gosip/log.Logger
|
||||||
func (l *Logger) SetLevel(level uint32) {
|
func (l *Logger) SetLevel(level any) {
|
||||||
l.Lock()
|
l.mu.Lock()
|
||||||
nl := l.Logger.Level(gosipLevelToZerologLevel(level))
|
nl := l.Logger.Level(castToZlogLevel(level))
|
||||||
l.Logger = &nl
|
l.Logger = &nl
|
||||||
l.Unlock()
|
l.mu.Unlock()
|
||||||
}
|
|
||||||
|
|
||||||
func gosipLevelToZerologLevel(level uint32) zerolog.Level {
|
|
||||||
switch level {
|
|
||||||
case 0:
|
|
||||||
return zerolog.PanicLevel
|
|
||||||
case 1:
|
|
||||||
return zerolog.FatalLevel
|
|
||||||
case 2:
|
|
||||||
return zerolog.ErrorLevel
|
|
||||||
case 3:
|
|
||||||
return zerolog.WarnLevel
|
|
||||||
case 4:
|
|
||||||
return zerolog.InfoLevel
|
|
||||||
case 5:
|
|
||||||
return zerolog.DebugLevel
|
|
||||||
case 6:
|
|
||||||
return zerolog.TraceLevel
|
|
||||||
}
|
|
||||||
panic(fmt.Sprintf("invalid log level %d", level))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Write(p []byte) (n int, err error) {
|
func (l *Logger) Write(p []byte) (n int, err error) {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
l.Logger.WithLevel(l.printLevel).Msg(string(bytes.TrimSuffix(p, []byte("\n"))))
|
l.Logger.WithLevel(l.printLevel).Msg(string(bytes.TrimSuffix(p, []byte("\n"))))
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Output(calldepth int, s string) error {
|
func (l *Logger) Output(calldepth int, s string) error {
|
||||||
l.RLock()
|
l.mu.RLock()
|
||||||
event := l.Logger.Info()
|
event := l.Logger.Info()
|
||||||
if calldepth != 2 {
|
if calldepth != 2 {
|
||||||
if l.prefix != "" {
|
if l.prefix != "" {
|
||||||
@ -274,11 +307,48 @@ func (l *Logger) Output(calldepth int, s string) error {
|
|||||||
}
|
}
|
||||||
event.Msg(s)
|
event.Msg(s)
|
||||||
zerolog.CallerFieldName = "caller"
|
zerolog.CallerFieldName = "caller"
|
||||||
l.RUnlock()
|
l.mu.RUnlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func printLn(e *zerolog.Event, v ...interface{}) {
|
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
|
||||||
|
}
|
||||||
strBuf := strBufs.Get().(*strings.Builder)
|
strBuf := strBufs.Get().(*strings.Builder)
|
||||||
for i, val := range v {
|
for i, val := range v {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
@ -292,18 +362,18 @@ func printLn(e *zerolog.Event, v ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type prefixHook struct {
|
type prefixHook struct {
|
||||||
parent StdCompatLogger
|
parent *Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h prefixHook) Run(e *zerolog.Event, _ zerolog.Level, _ string) {
|
func (h prefixHook) Run(e *zerolog.Event, _ zerolog.Level, _ string) {
|
||||||
if h.parent.Prefix() != "" {
|
if h.parent.Prefix() != "" {
|
||||||
e.Str("caller", h.parent.Prefix())
|
e.Str("caller", h.parent.myPrefix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Wrap(l zerolog.Logger) *Logger {
|
func Wrap(l zerolog.Logger) *Logger {
|
||||||
wrapped := &Logger{
|
wrapped := &Logger{
|
||||||
RWMutex: &sync.RWMutex{},
|
mu: &sync.RWMutex{},
|
||||||
printLevel: zerolog.InfoLevel,
|
printLevel: zerolog.InfoLevel,
|
||||||
}
|
}
|
||||||
p := prefixHook{wrapped}
|
p := prefixHook{wrapped}
|
||||||
|
243
wrap_test.go
243
wrap_test.go
@ -14,6 +14,7 @@ type testWriter struct {
|
|||||||
t *testing.T
|
t *testing.T
|
||||||
needsPrefix string
|
needsPrefix string
|
||||||
mustNotHavePrefix string
|
mustNotHavePrefix string
|
||||||
|
mustLevel *zerolog.Level
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrPrefixMismatch = errors.New("prefix mismatch")
|
var ErrPrefixMismatch = errors.New("prefix mismatch")
|
||||||
@ -29,6 +30,20 @@ func (w *testWriter) Write(p []byte) (n int, err error) {
|
|||||||
w.t.Errorf("unexpected prefix %q, got %q", w.mustNotHavePrefix, line)
|
w.t.Errorf("unexpected prefix %q, got %q", w.mustNotHavePrefix, line)
|
||||||
return 0, ErrPrefixMismatch
|
return 0, ErrPrefixMismatch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if w.mustLevel != nil {
|
||||||
|
if !strings.Contains(line, w.mustLevel.String()) {
|
||||||
|
w.t.Errorf("expected level %q, got %q", w.mustLevel.String(), line)
|
||||||
|
return 0, ErrPrefixMismatch
|
||||||
|
}
|
||||||
|
lvl := strings.Split(line, `"level":"`)[1]
|
||||||
|
lvl = strings.Split(lvl, `"`)[0]
|
||||||
|
if lvl != w.mustLevel.String() {
|
||||||
|
w.t.Errorf("expected level %q, got %q", w.mustLevel.String(), lvl)
|
||||||
|
return 0, ErrPrefixMismatch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
w.t.Log(line)
|
w.t.Log(line)
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
@ -46,7 +61,44 @@ func (n *needsLogger) SetLogger(logger aLogger) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *needsLogger) DoSomething() {
|
func (n *needsLogger) DoSomething() {
|
||||||
n.logger.Println("Hello, world!")
|
n.logger.Println("yeet")
|
||||||
|
}
|
||||||
|
|
||||||
|
type leveled struct {
|
||||||
|
name string
|
||||||
|
test func(*Logger, *testing.T)
|
||||||
|
shouldPanic bool
|
||||||
|
panicked bool
|
||||||
|
t *testing.T
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
expected = "expected"
|
||||||
|
unexpected = "unexpected"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l *leveled) expS() string {
|
||||||
|
if l.shouldPanic {
|
||||||
|
return expected
|
||||||
|
}
|
||||||
|
return unexpected
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *leveled) Run() {
|
||||||
|
l.t.Run(l.name, func(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
l.t.Logf("caught panic (%s): %v", l.expS(), r)
|
||||||
|
l.panicked = true
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
zl := zerolog.New(os.Stderr).With().Timestamp().Logger()
|
||||||
|
wrapped := Wrap(zl)
|
||||||
|
l.test(wrapped, t)
|
||||||
|
})
|
||||||
|
if (l.shouldPanic && !l.panicked) || (!l.shouldPanic && l.panicked) {
|
||||||
|
l.t.Errorf("%s panic during test: %s", l.expS(), l.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWrap(t *testing.T) {
|
func TestWrap(t *testing.T) {
|
||||||
@ -55,56 +107,209 @@ func TestWrap(t *testing.T) {
|
|||||||
writah := &testWriter{t: t}
|
writah := &testWriter{t: t}
|
||||||
|
|
||||||
zl := zerolog.New(writah).With().Timestamp().Logger()
|
zl := zerolog.New(writah).With().Timestamp().Logger()
|
||||||
wrapped := Wrap(zl)
|
wzl := Wrap(zl)
|
||||||
myThing := &needsLogger{}
|
myThing := &needsLogger{}
|
||||||
myThing.SetLogger(wrapped)
|
myThing.SetLogger(wzl)
|
||||||
|
|
||||||
multiLog := func(v ...interface{}) {
|
multiLog := func(wrapped *Logger, v ...interface{}) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
toggleFatals := wrapped.noFatal == false
|
||||||
|
togglePanics := wrapped.noPanic == false
|
||||||
wrapped.Print(v...)
|
wrapped.Print(v...)
|
||||||
wrapped.Printf("%v", v)
|
wrapped.Printf("f: %v", v...)
|
||||||
wrapped.Println(v...)
|
wrapped.Println(v...)
|
||||||
wrapped.Error(v...)
|
wrapped.Error(v...)
|
||||||
wrapped.Errorf("%v", v)
|
wrapped.Errorf("f: %v", v...)
|
||||||
wrapped.Errorln(v...)
|
wrapped.Errorln(v...)
|
||||||
wrapped.Debug(v...)
|
wrapped.Debug(v...)
|
||||||
wrapped.Debugf("%v", v)
|
wrapped.Debugf("f: %v", v...)
|
||||||
wrapped.Debugln(v...)
|
wrapped.Debugln(v...)
|
||||||
wrapped.Warn(v...)
|
wrapped.Warn(v...)
|
||||||
wrapped.Warnf("%v", v)
|
wrapped.Warnf("f: %v", v...)
|
||||||
wrapped.Warnln(v...)
|
wrapped.Warnln(v...)
|
||||||
wrapped.Info(v...)
|
wrapped.Info(v...)
|
||||||
wrapped.Infof("%v", v)
|
wrapped.Infof("f: %v", v...)
|
||||||
wrapped.Infoln(v...)
|
wrapped.Infoln(v...)
|
||||||
wrapped.Tracef("%v", v)
|
wrapped.Tracef("f: %v", v...)
|
||||||
wrapped.Trace(v...)
|
wrapped.Trace(v...)
|
||||||
wrapped.Traceln(v...)
|
wrapped.Traceln(v...)
|
||||||
wrapped.Logf("%v", v)
|
wrapped.Logf("f: %v", v...)
|
||||||
wrapped.Warning("%v", v)
|
wrapped.Warning(v...)
|
||||||
wrapped.Warningf("%v", v)
|
wrapped.Warningf("f: %v", v...)
|
||||||
|
wrapped.Println("")
|
||||||
|
wrapped.Println()
|
||||||
|
if toggleFatals {
|
||||||
|
wrapped.NoFatals(true)
|
||||||
|
}
|
||||||
|
wrapped.Fatal(v...)
|
||||||
|
wrapped.Fatalf("f: %v", v...)
|
||||||
|
wrapped.Fatalln(v...)
|
||||||
|
if toggleFatals {
|
||||||
|
wrapped.NoFatals(false)
|
||||||
|
}
|
||||||
|
if togglePanics {
|
||||||
|
wrapped.NoPanics(true)
|
||||||
|
}
|
||||||
|
wrapped.Panic(v...)
|
||||||
|
wrapped.Panicf("f: %v", v...)
|
||||||
|
wrapped.Panicln(v...)
|
||||||
|
if togglePanics {
|
||||||
|
wrapped.NoPanics(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if wrapped.V(0) {
|
if wzl.V(0) {
|
||||||
t.Error("V(0) should always return false")
|
t.Error("V(0) should always return false")
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("generic", func(t *testing.T) {
|
t.Run("generic", func(t *testing.T) {
|
||||||
multiLog("Hello, world!")
|
multiLog(wzl, "yeet")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("prefix", func(t *testing.T) {
|
t.Run("prefix", func(t *testing.T) {
|
||||||
writah.needsPrefix = "prefix: "
|
writah.needsPrefix = "prefix: "
|
||||||
wrapped.SetPrefix("prefix: ")
|
wzl.SetPrefix("prefix: ")
|
||||||
multiLog("Hello, world!")
|
multiLog(wzl, "yeet")
|
||||||
|
writah.needsPrefix = "prefix2: "
|
||||||
|
wzl = wzl.WithPrefix("prefix2: ")
|
||||||
|
multiLog(wzl, "yeet")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("remove prefix", func(t *testing.T) {
|
t.Run("remove prefix", func(t *testing.T) {
|
||||||
writah.needsPrefix = ""
|
writah.needsPrefix = ""
|
||||||
writah.mustNotHavePrefix = "prefix: "
|
writah.mustNotHavePrefix = "prefix: "
|
||||||
wrapped.SetPrefix("")
|
wzl.SetPrefix("")
|
||||||
multiLog("Hello, world!")
|
multiLog(wzl, "yeet")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
forceLevelTests := []leveled{
|
||||||
|
{
|
||||||
|
name: "trace",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.ForceLevel(zerolog.TraceLevel)
|
||||||
|
multiLog(wrapped, "yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: false,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "trace_with_panic",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.ForceLevel(zerolog.TraceLevel)
|
||||||
|
multiLog(wrapped, "yeet")
|
||||||
|
wrapped.Panic("yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: true,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "debug",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.ForceLevel(zerolog.DebugLevel)
|
||||||
|
multiLog(wrapped, "yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: false,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "info",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.ForceLevel(zerolog.InfoLevel)
|
||||||
|
multiLog(wrapped, "yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: false,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "warn",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.ForceLevel(zerolog.WarnLevel)
|
||||||
|
multiLog(wrapped, "yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: false,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.ForceLevel(zerolog.ErrorLevel)
|
||||||
|
multiLog(wrapped, "yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: false,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fatal",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.ForceLevel(zerolog.FatalLevel)
|
||||||
|
wrapped.NoFatals(true)
|
||||||
|
multiLog(wrapped, "yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: false,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "panic",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.ForceLevel(zerolog.PanicLevel)
|
||||||
|
multiLog(wrapped, "yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: true,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "panic_with_panic",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.Panic("yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: true,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range forceLevelTests {
|
||||||
|
test.name = "force_level_" + test.name
|
||||||
|
test.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
panicAndFatalBypassTests := []leveled{
|
||||||
|
{
|
||||||
|
name: "no_panic",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.NoPanics(true)
|
||||||
|
wrapped.Panic("yeet!!")
|
||||||
|
},
|
||||||
|
shouldPanic: false,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no_fatal",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.NoFatals(true)
|
||||||
|
wrapped.Fatal("yeet")
|
||||||
|
},
|
||||||
|
shouldPanic: false, // I guess the test should fail if it os.Exits anyway..? :^)
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no_panic_no_fatal_force_panic",
|
||||||
|
test: func(wrapped *Logger, t *testing.T) {
|
||||||
|
wrapped.NoPanics(true)
|
||||||
|
wrapped.NoFatals(true)
|
||||||
|
wrapped.ForceLevel(zerolog.PanicLevel)
|
||||||
|
multiLog(wrapped, "yeet!!")
|
||||||
|
wrapped.Panic("yeet!!")
|
||||||
|
},
|
||||||
|
shouldPanic: false,
|
||||||
|
t: t,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range panicAndFatalBypassTests {
|
||||||
|
test.name = "bypass_" + test.name
|
||||||
|
test.Run()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleWrap() {
|
func ExampleWrap() {
|
||||||
|
Loading…
Reference in New Issue
Block a user