Allow arbitrary negative levels (#350)

This allows logr to use high V() levels.
This commit is contained in:
Tim Hockin 2021-08-27 13:34:08 -07:00 committed by GitHub
parent fe931004ff
commit cdd74175d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 4 deletions

14
log.go
View File

@ -129,6 +129,7 @@ const (
// TraceLevel defines trace log level. // TraceLevel defines trace log level.
TraceLevel Level = -1 TraceLevel Level = -1
// Values less than TraceLevel are handled as numbers.
) )
func (l Level) String() string { func (l Level) String() string {
@ -152,7 +153,7 @@ func (l Level) String() string {
case NoLevel: case NoLevel:
return "" return ""
} }
return "" return strconv.Itoa(int(l))
} }
// ParseLevel converts a level string into a zerolog Level value. // ParseLevel converts a level string into a zerolog Level value.
@ -178,7 +179,14 @@ func ParseLevel(levelStr string) (Level, error) {
case LevelFieldMarshalFunc(NoLevel): case LevelFieldMarshalFunc(NoLevel):
return NoLevel, nil return NoLevel, nil
} }
return NoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to NoLevel", levelStr) i, err := strconv.Atoi(levelStr)
if err != nil {
return NoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to NoLevel", levelStr)
}
if i > 127 || i < -128 {
return NoLevel, fmt.Errorf("Out-Of-Bounds Level: '%d', defaulting to NoLevel", i)
}
return Level(i), nil
} }
// A Logger represents an active logging object that generates lines // A Logger represents an active logging object that generates lines
@ -377,7 +385,7 @@ func (l *Logger) WithLevel(level Level) *Event {
case Disabled: case Disabled:
return nil return nil
default: default:
panic("zerolog: WithLevel(): invalid level: " + strconv.Itoa(int(level))) return l.newEvent(level, nil)
} }
} }

View File

@ -549,7 +549,11 @@ func TestLevelWriter(t *testing.T) {
p string p string
}{}, }{},
} }
log := New(lw)
// Allow extra-verbose logs.
SetGlobalLevel(TraceLevel - 1)
log := New(lw).Level(TraceLevel - 1)
log.Trace().Msg("0") log.Trace().Msg("0")
log.Debug().Msg("1") log.Debug().Msg("1")
log.Info().Msg("2") log.Info().Msg("2")
@ -562,6 +566,9 @@ func TestLevelWriter(t *testing.T) {
log.WithLevel(WarnLevel).Msg("8") log.WithLevel(WarnLevel).Msg("8")
log.WithLevel(ErrorLevel).Msg("9") log.WithLevel(ErrorLevel).Msg("9")
log.WithLevel(NoLevel).Msg("nolevel-2") log.WithLevel(NoLevel).Msg("nolevel-2")
log.WithLevel(-1).Msg("-1") // Same as TraceLevel
log.WithLevel(-2).Msg("-2") // Will log
log.WithLevel(-3).Msg("-3") // Will not log
want := []struct { want := []struct {
l Level l Level
@ -579,6 +586,8 @@ func TestLevelWriter(t *testing.T) {
{WarnLevel, `{"level":"warn","message":"8"}` + "\n"}, {WarnLevel, `{"level":"warn","message":"8"}` + "\n"},
{ErrorLevel, `{"level":"error","message":"9"}` + "\n"}, {ErrorLevel, `{"level":"error","message":"9"}` + "\n"},
{NoLevel, `{"message":"nolevel-2"}` + "\n"}, {NoLevel, `{"message":"nolevel-2"}` + "\n"},
{Level(-1), `{"level":"trace","message":"-1"}` + "\n"},
{Level(-2), `{"level":"-2","message":"-2"}` + "\n"},
} }
if got := lw.ops; !reflect.DeepEqual(got, want) { if got := lw.ops; !reflect.DeepEqual(got, want) {
t.Errorf("invalid ops:\ngot:\n%v\nwant:\n%v", got, want) t.Errorf("invalid ops:\ngot:\n%v\nwant:\n%v", got, want)
@ -853,6 +862,9 @@ func TestParseLevel(t *testing.T) {
{"panic", args{"panic"}, PanicLevel, false}, {"panic", args{"panic"}, PanicLevel, false},
{"disabled", args{"disabled"}, Disabled, false}, {"disabled", args{"disabled"}, Disabled, false},
{"nolevel", args{""}, NoLevel, false}, {"nolevel", args{""}, NoLevel, false},
{"-1", args{"-1"}, TraceLevel, false},
{"-2", args{"-2"}, Level(-2), false},
{"-3", args{"-3"}, Level(-3), false},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {