diff --git a/logger.go b/logger.go index e1a9ff78a..6bb992450 100644 --- a/logger.go +++ b/logger.go @@ -190,6 +190,14 @@ func (log *Logger) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { return log.check(lvl, msg) } +// Log logs a message at the specified level. The message includes any fields +// passed at the log site, as well as any fields accumulated on the logger. +func (log *Logger) Log(lvl zapcore.Level, msg string, fields ...Field) { + if ce := log.check(lvl, msg); ce != nil { + ce.Write(fields...) + } +} + // Debug logs a message at DebugLevel. The message includes any fields passed // at the log site, as well as any fields accumulated on the logger. func (log *Logger) Debug(msg string, fields ...Field) { diff --git a/logger_test.go b/logger_test.go index 58b756a56..063d5dd16 100644 --- a/logger_test.go +++ b/logger_test.go @@ -119,7 +119,8 @@ func TestLoggerLogPanic(t *testing.T) { should bool expected string }{ - {func(logger *Logger) { logger.Check(PanicLevel, "bar").Write() }, true, "bar"}, + {func(logger *Logger) { logger.Check(PanicLevel, "foo").Write() }, true, "foo"}, + {func(logger *Logger) { logger.Log(PanicLevel, "bar") }, true, "bar"}, {func(logger *Logger) { logger.Panic("baz") }, true, "baz"}, } { withLogger(t, DebugLevel, nil, func(logger *Logger, logs *observer.ObservedLogs) { @@ -147,7 +148,8 @@ func TestLoggerLogFatal(t *testing.T) { do func(*Logger) expected string }{ - {func(logger *Logger) { logger.Check(FatalLevel, "bar").Write() }, "bar"}, + {func(logger *Logger) { logger.Check(FatalLevel, "foo").Write() }, "foo"}, + {func(logger *Logger) { logger.Log(FatalLevel, "bar") }, "bar"}, {func(logger *Logger) { logger.Fatal("baz") }, "baz"}, } { withLogger(t, DebugLevel, nil, func(logger *Logger, logs *observer.ObservedLogs) { @@ -194,12 +196,36 @@ func TestLoggerLeveledMethods(t *testing.T) { }) } +func TestLoggerLogLevels(t *testing.T) { + withLogger(t, DebugLevel, nil, func(logger *Logger, logs *observer.ObservedLogs) { + levels := []zapcore.Level{ + DebugLevel, + InfoLevel, + WarnLevel, + ErrorLevel, + DPanicLevel, + } + for i, level := range levels { + logger.Log(level, "") + output := logs.AllUntimed() + assert.Equal(t, i+1, len(output), "Unexpected number of logs.") + assert.Equal(t, 0, len(output[i].Context), "Unexpected context on first log.") + assert.Equal( + t, + zapcore.Entry{Level: level}, + output[i].Entry, + "Unexpected output from %s-level logger method.", level) + } + }) +} + func TestLoggerAlwaysPanics(t *testing.T) { // Users can disable writing out panic-level logs, but calls to logger.Panic() // should still call panic(). withLogger(t, FatalLevel, nil, func(logger *Logger, logs *observer.ObservedLogs) { msg := "Even if output is disabled, logger.Panic should always panic." assert.Panics(t, func() { logger.Panic("foo") }, msg) + assert.Panics(t, func() { logger.Log(PanicLevel, "foo") }, msg) assert.Panics(t, func() { if ce := logger.Check(PanicLevel, "foo"); ce != nil { ce.Write() @@ -216,6 +242,9 @@ func TestLoggerAlwaysFatals(t *testing.T) { stub := exit.WithStub(func() { logger.Fatal("") }) assert.True(t, stub.Exited, "Expected calls to logger.Fatal to terminate process.") + stub = exit.WithStub(func() { logger.Log(FatalLevel, "") }) + assert.True(t, stub.Exited, "Expected calls to logger.Fatal to terminate process.") + stub = exit.WithStub(func() { if ce := logger.Check(FatalLevel, ""); ce != nil { ce.Write()