From e013d3b774f605d4e0265b110de08a3d17c4da2f Mon Sep 17 00:00:00 2001 From: Peijun Zhu Date: Mon, 11 Apr 2022 12:58:33 +0900 Subject: [PATCH] Add *ln variants of methods to the SugaredLogger --- sugar.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ sugar_test.go | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/sugar.go b/sugar.go index 4f9d491a0..298e6457e 100644 --- a/sugar.go +++ b/sugar.go @@ -220,11 +220,48 @@ func (s *SugaredLogger) Fatalw(msg string, keysAndValues ...interface{}) { s.log(FatalLevel, msg, nil, keysAndValues) } +// Debugln uses fmt.Sprintln to construct and log a message. +func (s *SugaredLogger) Debugln(args ...interface{}) { + s.logln(DebugLevel, "", args, nil) +} + +// Infoln uses fmt.Sprintln to construct and log a message. +func (s *SugaredLogger) Infoln(args ...interface{}) { + s.logln(InfoLevel, "", args, nil) +} + +// Warnln uses fmt.Sprintln to construct and log a message. +func (s *SugaredLogger) Warnln(args ...interface{}) { + s.logln(WarnLevel, "", args, nil) +} + +// Errorln uses fmt.Sprintln to construct and log a message. +func (s *SugaredLogger) Errorln(args ...interface{}) { + s.logln(ErrorLevel, "", args, nil) +} + +// DPanicln uses fmt.Sprintln to construct and log a message. In development, the +// logger then panics. (See DPanicLevel for details.) +func (s *SugaredLogger) DPanicln(args ...interface{}) { + s.logln(DPanicLevel, "", args, nil) +} + +// Panicln uses fmt.Sprintln to construct and log a message, then panics. +func (s *SugaredLogger) Panicln(args ...interface{}) { + s.logln(PanicLevel, "", args, nil) +} + +// Fatalln uses fmt.Sprintln to construct and log a message, then calls os.Exit. +func (s *SugaredLogger) Fatalln(args ...interface{}) { + s.logln(FatalLevel, "", args, nil) +} + // Sync flushes any buffered log entries. func (s *SugaredLogger) Sync() error { return s.base.Sync() } +// log message with Sprint, Sprintf, or neither. func (s *SugaredLogger) log(lvl zapcore.Level, template string, fmtArgs []interface{}, context []interface{}) { // If logging at this level is completely disabled, skip the overhead of // string formatting. @@ -238,6 +275,18 @@ func (s *SugaredLogger) log(lvl zapcore.Level, template string, fmtArgs []interf } } +// logln message with Sprintln +func (s *SugaredLogger) logln(lvl zapcore.Level, template string, fmtArgs []interface{}, context []interface{}) { + if lvl < DPanicLevel && !s.base.Core().Enabled(lvl) { + return + } + + msg := getMessageln(fmtArgs) + if ce := s.base.Check(lvl, msg); ce != nil { + ce.Write(s.sweetenFields(context)...) + } +} + // getMessage format with Sprint, Sprintf, or neither. func getMessage(template string, fmtArgs []interface{}) string { if len(fmtArgs) == 0 { @@ -256,6 +305,12 @@ func getMessage(template string, fmtArgs []interface{}) string { return fmt.Sprint(fmtArgs...) } +// getMessageln format with Sprintln. +func getMessageln(fmtArgs []interface{}) string { + msg := fmt.Sprintln(fmtArgs...) + return msg[:len(msg)-1] +} + func (s *SugaredLogger) sweetenFields(args []interface{}) []Field { if len(args) == 0 { return nil diff --git a/sugar_test.go b/sugar_test.go index 8cb0f9443..f186112b3 100644 --- a/sugar_test.go +++ b/sugar_test.go @@ -261,6 +261,42 @@ func TestSugarTemplatedLogging(t *testing.T) { } } +func TestSugarLnLogging(t *testing.T) { + tests := []struct { + args []interface{} + expect string + }{ + {nil, ""}, + {[]interface{}{}, ""}, + {[]interface{}{""}, ""}, + {[]interface{}{"foo"}, "foo"}, + {[]interface{}{"foo", "bar"}, "foo bar"}, + } + + // Common to all test cases. + context := []interface{}{"foo", "bar"} + expectedFields := []Field{String("foo", "bar")} + + for _, tt := range tests { + withSugar(t, DebugLevel, nil, func(logger *SugaredLogger, logs *observer.ObservedLogs) { + logger.With(context...).Debugln(tt.args...) + logger.With(context...).Infoln(tt.args...) + logger.With(context...).Warnln(tt.args...) + logger.With(context...).Errorln(tt.args...) + logger.With(context...).DPanicln(tt.args...) + + expected := make([]observer.LoggedEntry, 5) + for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel} { + expected[i] = observer.LoggedEntry{ + Entry: zapcore.Entry{Message: tt.expect, Level: lvl}, + Context: expectedFields, + } + } + assert.Equal(t, expected, logs.AllUntimed(), "Unexpected log output.") + }) + } +} + func TestSugarPanicLogging(t *testing.T) { tests := []struct { loggerLevel zapcore.Level @@ -276,6 +312,9 @@ func TestSugarPanicLogging(t *testing.T) { {FatalLevel, func(s *SugaredLogger) { s.Panicw("foo") }, ""}, {PanicLevel, func(s *SugaredLogger) { s.Panicw("foo") }, "foo"}, {DebugLevel, func(s *SugaredLogger) { s.Panicw("foo") }, "foo"}, + {FatalLevel, func(s *SugaredLogger) { s.Panicln("foo") }, ""}, + {PanicLevel, func(s *SugaredLogger) { s.Panicln("foo") }, "foo"}, + {DebugLevel, func(s *SugaredLogger) { s.Panicln("foo") }, "foo"}, } for _, tt := range tests { @@ -308,6 +347,9 @@ func TestSugarFatalLogging(t *testing.T) { {FatalLevel + 1, func(s *SugaredLogger) { s.Fatalw("foo") }, ""}, {FatalLevel, func(s *SugaredLogger) { s.Fatalw("foo") }, "foo"}, {DebugLevel, func(s *SugaredLogger) { s.Fatalw("foo") }, "foo"}, + {FatalLevel + 1, func(s *SugaredLogger) { s.Fatalln("foo") }, ""}, + {FatalLevel, func(s *SugaredLogger) { s.Fatalln("foo") }, "foo"}, + {DebugLevel, func(s *SugaredLogger) { s.Fatalln("foo") }, "foo"}, } for _, tt := range tests { @@ -385,6 +427,22 @@ func TestSugarWithOptionsIncreaseLevel(t *testing.T) { }) } +func TestSugarLnWithOptionsIncreaseLevel(t *testing.T) { + withSugar(t, DebugLevel, nil, func(logger *SugaredLogger, logs *observer.ObservedLogs) { + logger = logger.WithOptions(IncreaseLevel(WarnLevel)) + logger.Infoln("logger.Infoln") + logger.Warnln("logger.Warnln") + logger.Errorln("logger.Errorln") + require.Equal(t, 2, logs.Len(), "expected only warn + error logs due to IncreaseLevel.") + assert.Equal( + t, + logs.AllUntimed()[0].Message, + "logger.Warnln", + "Expected first logged message to be warn level message", + ) + }) +} + func BenchmarkSugarSingleStrArg(b *testing.B) { withSugar(b, InfoLevel, nil /* opts* */, func(log *SugaredLogger, logs *observer.ObservedLogs) { for i := 0; i < b.N; i++ {