From 956a21c19cf77ea7a78f9f08ca44b6f77f95053a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kut=C3=A1=C4=8D?= Date: Tue, 13 Feb 2024 19:36:32 +0100 Subject: [PATCH] Add methods for logging with level as argument (#1406) Adding generic `Log`, `Logf`, `Logw` and `Logln` methods to Sugared logger. When I need to do a wrapper around Zap logger to pass that into 3rd party library for unifying logging, it might come handy to use zap.Log(level, ...) instead of switch or if-else if chain. However, now I need to do a same wrapper but with Sugared logger. And that doesn't support general Log method. More description in https://github.com/uber-go/zap/issues/1405 --- sugar.go | 24 ++++++++++++++++++++++++ sugar_test.go | 20 ++++++++++++-------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/sugar.go b/sugar.go index dce9341db..8904cd087 100644 --- a/sugar.go +++ b/sugar.go @@ -137,6 +137,12 @@ func (s *SugaredLogger) Level() zapcore.Level { return zapcore.LevelOf(s.base.core) } +// Log logs the provided arguments at provided level. +// Spaces are added between arguments when neither is a string. +func (s *SugaredLogger) Log(lvl zapcore.Level, args ...interface{}) { + s.log(lvl, "", args, nil) +} + // Debug logs the provided arguments at [DebugLevel]. // Spaces are added between arguments when neither is a string. func (s *SugaredLogger) Debug(args ...interface{}) { @@ -180,6 +186,12 @@ func (s *SugaredLogger) Fatal(args ...interface{}) { s.log(FatalLevel, "", args, nil) } +// Logf formats the message according to the format specifier +// and logs it at provided level. +func (s *SugaredLogger) Logf(lvl zapcore.Level, template string, args ...interface{}) { + s.log(lvl, template, args, nil) +} + // Debugf formats the message according to the format specifier // and logs it at [DebugLevel]. func (s *SugaredLogger) Debugf(template string, args ...interface{}) { @@ -223,6 +235,12 @@ func (s *SugaredLogger) Fatalf(template string, args ...interface{}) { s.log(FatalLevel, template, args, nil) } +// Logw logs a message with some additional context. The variadic key-value +// pairs are treated as they are in With. +func (s *SugaredLogger) Logw(lvl zapcore.Level, msg string, keysAndValues ...interface{}) { + s.log(lvl, msg, nil, keysAndValues) +} + // Debugw logs a message with some additional context. The variadic key-value // pairs are treated as they are in With. // @@ -270,6 +288,12 @@ func (s *SugaredLogger) Fatalw(msg string, keysAndValues ...interface{}) { s.log(FatalLevel, msg, nil, keysAndValues) } +// Logln logs a message at provided level. +// Spaces are always added between arguments. +func (s *SugaredLogger) Logln(lvl zapcore.Level, args ...interface{}) { + s.logln(lvl, args, nil) +} + // Debugln logs a message at [DebugLevel]. // Spaces are always added between arguments. func (s *SugaredLogger) Debugln(args ...interface{}) { diff --git a/sugar_test.go b/sugar_test.go index 0f608cb50..8ca2bddfa 100644 --- a/sugar_test.go +++ b/sugar_test.go @@ -311,9 +311,10 @@ func TestSugarStructuredLogging(t *testing.T) { logger.With(context...).Warnw(tt.msg, extra...) logger.With(context...).Errorw(tt.msg, extra...) logger.With(context...).DPanicw(tt.msg, extra...) + logger.With(context...).Logw(WarnLevel, tt.msg, extra...) - expected := make([]observer.LoggedEntry, 5) - for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel} { + expected := make([]observer.LoggedEntry, 6) + for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, WarnLevel} { expected[i] = observer.LoggedEntry{ Entry: zapcore.Entry{Message: tt.expectMsg, Level: lvl}, Context: expectedFields, @@ -343,9 +344,10 @@ func TestSugarConcatenatingLogging(t *testing.T) { logger.With(context...).Warn(tt.args...) logger.With(context...).Error(tt.args...) logger.With(context...).DPanic(tt.args...) + logger.With(context...).Log(InfoLevel, tt.args...) - expected := make([]observer.LoggedEntry, 5) - for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel} { + expected := make([]observer.LoggedEntry, 6) + for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, InfoLevel} { expected[i] = observer.LoggedEntry{ Entry: zapcore.Entry{Message: tt.expect, Level: lvl}, Context: expectedFields, @@ -379,9 +381,10 @@ func TestSugarTemplatedLogging(t *testing.T) { logger.With(context...).Warnf(tt.format, tt.args...) logger.With(context...).Errorf(tt.format, tt.args...) logger.With(context...).DPanicf(tt.format, tt.args...) + logger.With(context...).Logf(ErrorLevel, tt.format, tt.args...) - expected := make([]observer.LoggedEntry, 5) - for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel} { + expected := make([]observer.LoggedEntry, 6) + for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, ErrorLevel} { expected[i] = observer.LoggedEntry{ Entry: zapcore.Entry{Message: tt.expect, Level: lvl}, Context: expectedFields, @@ -415,9 +418,10 @@ func TestSugarLnLogging(t *testing.T) { logger.With(context...).Warnln(tt.args...) logger.With(context...).Errorln(tt.args...) logger.With(context...).DPanicln(tt.args...) + logger.With(context...).Logln(InfoLevel, tt.args...) - expected := make([]observer.LoggedEntry, 5) - for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel} { + expected := make([]observer.LoggedEntry, 6) + for i, lvl := range []zapcore.Level{DebugLevel, InfoLevel, WarnLevel, ErrorLevel, DPanicLevel, InfoLevel} { expected[i] = observer.LoggedEntry{ Entry: zapcore.Entry{Message: tt.expect, Level: lvl}, Context: expectedFields,