Skip to content

Commit cdd7417

Browse files
authored
Allow arbitrary negative levels (#350)
This allows logr to use high V() levels.
1 parent fe93100 commit cdd7417

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

log.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ const (
129129

130130
// TraceLevel defines trace log level.
131131
TraceLevel Level = -1
132+
// Values less than TraceLevel are handled as numbers.
132133
)
133134

134135
func (l Level) String() string {
@@ -152,7 +153,7 @@ func (l Level) String() string {
152153
case NoLevel:
153154
return ""
154155
}
155-
return ""
156+
return strconv.Itoa(int(l))
156157
}
157158

158159
// ParseLevel converts a level string into a zerolog Level value.
@@ -178,7 +179,14 @@ func ParseLevel(levelStr string) (Level, error) {
178179
case LevelFieldMarshalFunc(NoLevel):
179180
return NoLevel, nil
180181
}
181-
return NoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to NoLevel", levelStr)
182+
i, err := strconv.Atoi(levelStr)
183+
if err != nil {
184+
return NoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to NoLevel", levelStr)
185+
}
186+
if i > 127 || i < -128 {
187+
return NoLevel, fmt.Errorf("Out-Of-Bounds Level: '%d', defaulting to NoLevel", i)
188+
}
189+
return Level(i), nil
182190
}
183191

184192
// A Logger represents an active logging object that generates lines
@@ -377,7 +385,7 @@ func (l *Logger) WithLevel(level Level) *Event {
377385
case Disabled:
378386
return nil
379387
default:
380-
panic("zerolog: WithLevel(): invalid level: " + strconv.Itoa(int(level)))
388+
return l.newEvent(level, nil)
381389
}
382390
}
383391

log_test.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,11 @@ func TestLevelWriter(t *testing.T) {
549549
p string
550550
}{},
551551
}
552-
log := New(lw)
552+
553+
// Allow extra-verbose logs.
554+
SetGlobalLevel(TraceLevel - 1)
555+
log := New(lw).Level(TraceLevel - 1)
556+
553557
log.Trace().Msg("0")
554558
log.Debug().Msg("1")
555559
log.Info().Msg("2")
@@ -562,6 +566,9 @@ func TestLevelWriter(t *testing.T) {
562566
log.WithLevel(WarnLevel).Msg("8")
563567
log.WithLevel(ErrorLevel).Msg("9")
564568
log.WithLevel(NoLevel).Msg("nolevel-2")
569+
log.WithLevel(-1).Msg("-1") // Same as TraceLevel
570+
log.WithLevel(-2).Msg("-2") // Will log
571+
log.WithLevel(-3).Msg("-3") // Will not log
565572

566573
want := []struct {
567574
l Level
@@ -579,6 +586,8 @@ func TestLevelWriter(t *testing.T) {
579586
{WarnLevel, `{"level":"warn","message":"8"}` + "\n"},
580587
{ErrorLevel, `{"level":"error","message":"9"}` + "\n"},
581588
{NoLevel, `{"message":"nolevel-2"}` + "\n"},
589+
{Level(-1), `{"level":"trace","message":"-1"}` + "\n"},
590+
{Level(-2), `{"level":"-2","message":"-2"}` + "\n"},
582591
}
583592
if got := lw.ops; !reflect.DeepEqual(got, want) {
584593
t.Errorf("invalid ops:\ngot:\n%v\nwant:\n%v", got, want)
@@ -853,6 +862,9 @@ func TestParseLevel(t *testing.T) {
853862
{"panic", args{"panic"}, PanicLevel, false},
854863
{"disabled", args{"disabled"}, Disabled, false},
855864
{"nolevel", args{""}, NoLevel, false},
865+
{"-1", args{"-1"}, TraceLevel, false},
866+
{"-2", args{"-2"}, Level(-2), false},
867+
{"-3", args{"-3"}, Level(-3), false},
856868
}
857869
for _, tt := range tests {
858870
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)