From 3180cc179ba8c7906f40eeef222ddf66469173cd Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Sun, 22 Nov 2020 17:40:02 +1100 Subject: [PATCH 01/13] Add support for grpclog.LoggerV2 --- zapgrpc/zapgrpc.go | 134 ++++++++++++++++++++++++++++++---------- zapgrpc/zapgrpc_test.go | 61 +++++++++++++++++- 2 files changed, 159 insertions(+), 36 deletions(-) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 1181e6a0d..0381622a6 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -21,7 +21,10 @@ // Package zapgrpc provides a logger that is compatible with grpclog. package zapgrpc // import "go.uber.org/zap/zapgrpc" -import "go.uber.org/zap" +import ( + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) // An Option overrides a Logger's default configuration. type Option interface { @@ -36,23 +39,19 @@ func (f optionFunc) apply(log *Logger) { // WithDebug configures a Logger to print at zap's DebugLevel instead of // InfoLevel. +// Deprecated: use grpclog.SetLoggerV2() for v2 API. func WithDebug() Option { return optionFunc(func(logger *Logger) { - logger.print = (*zap.SugaredLogger).Debug - logger.printf = (*zap.SugaredLogger).Debugf + logger.printToDebug = true }) } // NewLogger returns a new Logger. -// -// By default, Loggers print at zap's InfoLevel. func NewLogger(l *zap.Logger, options ...Option) *Logger { logger := &Logger{ - log: l.Sugar(), - fatal: (*zap.SugaredLogger).Fatal, - fatalf: (*zap.SugaredLogger).Fatalf, - print: (*zap.SugaredLogger).Info, - printf: (*zap.SugaredLogger).Infof, + delegate: l.Sugar(), + printToDebug: false, + fatalToWarn: false, } for _, option := range options { option.apply(logger) @@ -60,41 +59,108 @@ func NewLogger(l *zap.Logger, options ...Option) *Logger { return logger } -// Logger adapts zap's Logger to be compatible with grpclog.Logger. +// Logger adapts zap's Logger to be compatible with grpclog.LoggerV2 and the deprecated grpclog.Logger. type Logger struct { - log *zap.SugaredLogger - fatal func(*zap.SugaredLogger, ...interface{}) - fatalf func(*zap.SugaredLogger, string, ...interface{}) - print func(*zap.SugaredLogger, ...interface{}) - printf func(*zap.SugaredLogger, string, ...interface{}) -} - -// Fatal implements grpclog.Logger. -func (l *Logger) Fatal(args ...interface{}) { - l.fatal(l.log, args...) -} - -// Fatalf implements grpclog.Logger. -func (l *Logger) Fatalf(format string, args ...interface{}) { - l.fatalf(l.log, format, args...) -} - -// Fatalln implements grpclog.Logger. -func (l *Logger) Fatalln(args ...interface{}) { - l.fatal(l.log, args...) + delegate *zap.SugaredLogger + printToDebug bool + fatalToWarn bool } // Print implements grpclog.Logger. +// Deprecated: use Info(). func (l *Logger) Print(args ...interface{}) { - l.print(l.log, args...) + if l.printToDebug { + l.delegate.Debug(args...) + } else { + l.delegate.Info(args...) + } } // Printf implements grpclog.Logger. +// Deprecated: use Infof(). func (l *Logger) Printf(format string, args ...interface{}) { - l.printf(l.log, format, args...) + if l.printToDebug { + l.delegate.Debugf(format, args...) + } else { + l.delegate.Infof(format, args...) + } } // Println implements grpclog.Logger. +// Deprecated: use Info(). func (l *Logger) Println(args ...interface{}) { - l.print(l.log, args...) + l.Print(args...) +} + +// Info implements grpclog.LoggerV2. +func (l *Logger) Info(args ...interface{}) { + l.delegate.Info(args...) +} + +// Infoln implements grpclog.LoggerV2. +func (l *Logger) Infoln(args ...interface{}) { + l.delegate.Info(args...) +} + +// Infof implements grpclog.LoggerV2. +func (l *Logger) Infof(format string, args ...interface{}) { + l.delegate.Infof(format, args...) +} + +// Warning implements grpclog.LoggerV2. +func (l *Logger) Warning(args ...interface{}) { + l.delegate.Warn(args...) +} + +// Warningln implements grpclog.LoggerV2. +func (l *Logger) Warningln(args ...interface{}) { + l.delegate.Warn(args...) +} + +// Warningf implements grpclog.LoggerV2. +func (l *Logger) Warningf(format string, args ...interface{}) { + l.delegate.Warnf(format, args...) +} + +// Error implements grpclog.LoggerV2. +func (l *Logger) Error(args ...interface{}) { + l.delegate.Error(args...) +} + +// Errorln implements grpclog.LoggerV2. +func (l *Logger) Errorln(args ...interface{}) { + l.delegate.Error(args...) +} + +// Errorf implements grpclog.LoggerV2. +func (l *Logger) Errorf(format string, args ...interface{}) { + l.delegate.Errorf(format, args...) +} + +// Fatal implements grpclog.LoggerV2. +func (l *Logger) Fatal(args ...interface{}) { + if l.fatalToWarn { + l.delegate.Warn(args...) + } else { + l.delegate.Fatal(args...) + } +} + +// Fatalln implements grpclog.LoggerV2. +func (l *Logger) Fatalln(args ...interface{}) { + l.Fatal(args...) +} + +// Fatalf implements grpclog.LoggerV2. +func (l *Logger) Fatalf(format string, args ...interface{}) { + if l.fatalToWarn { + l.delegate.Warnf(format, args...) + } else { + l.delegate.Fatalf(format, args...) + } +} + +// V implements grpclog.LoggerV2. +func (l *Logger) V(level int) bool { + return l.delegate.Desugar().Core().Enabled(zapcore.Level(level)) } diff --git a/zapgrpc/zapgrpc_test.go b/zapgrpc/zapgrpc_test.go index 036f3d764..ed827bf7f 100644 --- a/zapgrpc/zapgrpc_test.go +++ b/zapgrpc/zapgrpc_test.go @@ -35,7 +35,13 @@ func TestLoggerInfoExpected(t *testing.T) { "hello", "world", "foo", + "hello", + "world", + "foo", }, func(logger *Logger) { + logger.Info("hello") + logger.Infof("world") + logger.Infoln("foo") logger.Print("hello") logger.Printf("world") logger.Println("foo") @@ -62,6 +68,30 @@ func TestLoggerDebugSuppressed(t *testing.T) { }) } +func TestLoggerWarningExpected(t *testing.T) { + checkMessages(t, zapcore.DebugLevel, nil, zapcore.WarnLevel, []string{ + "hello", + "world", + "foo", + }, func(logger *Logger) { + logger.Warning("hello") + logger.Warningf("world") + logger.Warningln("foo") + }) +} + +func TestLoggerErrorExpected(t *testing.T) { + checkMessages(t, zapcore.DebugLevel, nil, zapcore.ErrorLevel, []string{ + "hello", + "world", + "foo", + }, func(logger *Logger) { + logger.Error("hello") + logger.Errorf("world") + logger.Errorln("foo") + }) +} + func TestLoggerFatalExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, nil, zapcore.FatalLevel, []string{ "hello", @@ -74,6 +104,34 @@ func TestLoggerFatalExpected(t *testing.T) { }) } +func TestLoggerVTrueExpected(t *testing.T) { + checkLevel(t, zapcore.DebugLevel, true, func(logger *Logger) bool { + return logger.V(0) + }) +} + +func TestLoggerVFalseExpected(t *testing.T) { + checkLevel(t, zapcore.WarnLevel, false, func(logger *Logger) bool { + return logger.V(0) + }) +} + +func checkLevel( + t testing.TB, + enab zapcore.LevelEnabler, + expectedBool bool, + f func(*Logger) bool, +) { + withLogger(enab, nil, func(logger *Logger, observedLogs *observer.ObservedLogs) { + actualBool := f(logger) + if expectedBool { + require.True(t, actualBool) + } else { + require.False(t, actualBool) + } + }) +} + func checkMessages( t testing.TB, enab zapcore.LevelEnabler, @@ -109,7 +167,6 @@ func withLogger( // easier. func withWarn() Option { return optionFunc(func(logger *Logger) { - logger.fatal = (*zap.SugaredLogger).Warn - logger.fatalf = (*zap.SugaredLogger).Warnf + logger.fatalToWarn = true }) } From a10bb533d6c6ad6d7bd7c69c5b4777fc070028ff Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Thu, 28 Jan 2021 21:04:28 +1100 Subject: [PATCH 02/13] Add comment --- zapgrpc/zapgrpc.go | 1 + 1 file changed, 1 insertion(+) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 0381622a6..24b673849 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -39,6 +39,7 @@ func (f optionFunc) apply(log *Logger) { // WithDebug configures a Logger to print at zap's DebugLevel instead of // InfoLevel. +// It only affects the Printf, Println and Print methods, which are only used in the gRPC v1 grpclog.Logger API. // Deprecated: use grpclog.SetLoggerV2() for v2 API. func WithDebug() Option { return optionFunc(func(logger *Logger) { From cb9e579248045aa267b17302e2ab2ac22608ac67 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Wed, 3 Feb 2021 20:57:57 +1100 Subject: [PATCH 03/13] Correctly map log levels and add spaces for *ln() methods --- zapgrpc/zapgrpc.go | 51 +++++++++++++++-- zapgrpc/zapgrpc_test.go | 123 +++++++++++++++++++++++++++++++++------- 2 files changed, 149 insertions(+), 25 deletions(-) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 24b673849..19aeb356f 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -26,6 +26,26 @@ import ( "go.uber.org/zap/zapcore" ) +const ( + // See https://github.com/grpc/grpc-go/blob/v1.35.0/grpclog/loggerv2.go#L77-L86 + + grpcLvlInfo = 0 + grpcLvlWarn = 1 + grpcLvlError = 2 + grpcLvlFatal = 3 +) + +var ( + // grpc2zapLvl maps gRPC log levels to zap log levels. + // See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level + grpc2zapLvl = map[int]zapcore.Level{ + grpcLvlInfo: zapcore.InfoLevel, + grpcLvlWarn: zapcore.WarnLevel, + grpcLvlError: zapcore.ErrorLevel, + grpcLvlFatal: zapcore.FatalLevel, + } +) + // An Option overrides a Logger's default configuration. type Option interface { apply(*Logger) @@ -90,7 +110,7 @@ func (l *Logger) Printf(format string, args ...interface{}) { // Println implements grpclog.Logger. // Deprecated: use Info(). func (l *Logger) Println(args ...interface{}) { - l.Print(args...) + l.Print(addSpaces(args)...) } // Info implements grpclog.LoggerV2. @@ -100,7 +120,7 @@ func (l *Logger) Info(args ...interface{}) { // Infoln implements grpclog.LoggerV2. func (l *Logger) Infoln(args ...interface{}) { - l.delegate.Info(args...) + l.delegate.Info(addSpaces(args)...) } // Infof implements grpclog.LoggerV2. @@ -115,7 +135,7 @@ func (l *Logger) Warning(args ...interface{}) { // Warningln implements grpclog.LoggerV2. func (l *Logger) Warningln(args ...interface{}) { - l.delegate.Warn(args...) + l.delegate.Warn(addSpaces(args)...) } // Warningf implements grpclog.LoggerV2. @@ -130,7 +150,7 @@ func (l *Logger) Error(args ...interface{}) { // Errorln implements grpclog.LoggerV2. func (l *Logger) Errorln(args ...interface{}) { - l.delegate.Error(args...) + l.delegate.Error(addSpaces(args)...) } // Errorf implements grpclog.LoggerV2. @@ -149,7 +169,7 @@ func (l *Logger) Fatal(args ...interface{}) { // Fatalln implements grpclog.LoggerV2. func (l *Logger) Fatalln(args ...interface{}) { - l.Fatal(args...) + l.Fatal(addSpaces(args)...) } // Fatalf implements grpclog.LoggerV2. @@ -163,5 +183,24 @@ func (l *Logger) Fatalf(format string, args ...interface{}) { // V implements grpclog.LoggerV2. func (l *Logger) V(level int) bool { - return l.delegate.Desugar().Core().Enabled(zapcore.Level(level)) + return l.delegate.Desugar().Core().Enabled(grpc2zapLvl[level]) +} + +// addSpaces always adds spaces between arguments like https://golang.org/pkg/fmt/#Println +func addSpaces(args []interface{}) []interface{} { + l := len(args) + if l == 0 || l == 1 { + return args + } + res := make([]interface{}, 0, l+l-1) + first := true + for _, arg := range args { + if first { + first = false + res = append(res, arg) + } else { + res = append(res, " ", arg) + } + } + return res } diff --git a/zapgrpc/zapgrpc_test.go b/zapgrpc/zapgrpc_test.go index ed827bf7f..055c2153c 100644 --- a/zapgrpc/zapgrpc_test.go +++ b/zapgrpc/zapgrpc_test.go @@ -21,6 +21,7 @@ package zapgrpc import ( + "fmt" "testing" "go.uber.org/zap" @@ -33,87 +34,171 @@ import ( func TestLoggerInfoExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, nil, zapcore.InfoLevel, []string{ "hello", - "world", + "hello world", + "", "foo", + "foo bar", "hello", - "world", + "hello world", + "", "foo", + "foo bar", }, func(logger *Logger) { logger.Info("hello") - logger.Infof("world") + logger.Infof("%s world", "hello") + logger.Infoln() logger.Infoln("foo") + logger.Infoln("foo", "bar") logger.Print("hello") - logger.Printf("world") + logger.Printf("%s world", "hello") + logger.Println() logger.Println("foo") + logger.Println("foo", "bar") }) } func TestLoggerDebugExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, []Option{WithDebug()}, zapcore.DebugLevel, []string{ "hello", - "world", + "hello world", + "", "foo", + "foo bar", }, func(logger *Logger) { logger.Print("hello") - logger.Printf("world") + logger.Printf("%s world", "hello") + logger.Println() logger.Println("foo") + logger.Println("foo", "bar") }) } func TestLoggerDebugSuppressed(t *testing.T) { checkMessages(t, zapcore.InfoLevel, []Option{WithDebug()}, zapcore.DebugLevel, nil, func(logger *Logger) { logger.Print("hello") - logger.Printf("world") + logger.Printf("%s world", "hello") + logger.Println() logger.Println("foo") + logger.Println("foo", "bar") }) } func TestLoggerWarningExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, nil, zapcore.WarnLevel, []string{ "hello", - "world", + "hello world", + "", "foo", + "foo bar", }, func(logger *Logger) { logger.Warning("hello") - logger.Warningf("world") + logger.Warningf("%s world", "hello") + logger.Warningln() logger.Warningln("foo") + logger.Warningln("foo", "bar") }) } func TestLoggerErrorExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, nil, zapcore.ErrorLevel, []string{ "hello", - "world", + "hello world", + "", "foo", + "foo bar", }, func(logger *Logger) { logger.Error("hello") - logger.Errorf("world") + logger.Errorf("%s world", "hello") + logger.Errorln() logger.Errorln("foo") + logger.Errorln("foo", "bar") }) } func TestLoggerFatalExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, nil, zapcore.FatalLevel, []string{ "hello", - "world", + "hello world", + "", "foo", + "foo bar", }, func(logger *Logger) { logger.Fatal("hello") - logger.Fatalf("world") + logger.Fatalf("%s world", "hello") + logger.Fatalln() logger.Fatalln("foo") + logger.Fatalln("foo", "bar") }) } func TestLoggerVTrueExpected(t *testing.T) { - checkLevel(t, zapcore.DebugLevel, true, func(logger *Logger) bool { - return logger.V(0) - }) + enabled := map[zapcore.Level][]int{ + zapcore.DebugLevel: { + grpcLvlInfo, grpcLvlWarn, grpcLvlError, grpcLvlFatal, + }, + zapcore.InfoLevel: { + grpcLvlInfo, grpcLvlWarn, grpcLvlError, grpcLvlFatal, + }, + zapcore.WarnLevel: { + grpcLvlWarn, grpcLvlError, grpcLvlFatal, + }, + zapcore.ErrorLevel: { + grpcLvlError, grpcLvlFatal, + }, + zapcore.DPanicLevel: { + grpcLvlFatal, + }, + zapcore.PanicLevel: { + grpcLvlFatal, + }, + zapcore.FatalLevel: { + grpcLvlFatal, + }, + } + for zapLvl, grpcLvls := range enabled { + for _, grpcLvl := range grpcLvls { + t.Run(fmt.Sprintf("%s %d", zapLvl, grpcLvl), func(t *testing.T) { + checkLevel(t, zapLvl, true, func(logger *Logger) bool { + return logger.V(grpcLvl) + }) + }) + } + } } func TestLoggerVFalseExpected(t *testing.T) { - checkLevel(t, zapcore.WarnLevel, false, func(logger *Logger) bool { - return logger.V(0) - }) + disabled := map[zapcore.Level][]int{ + zapcore.DebugLevel: { + // everything is enabled, nothing is disabled + }, + zapcore.InfoLevel: { + // everything is enabled, nothing is disabled + }, + zapcore.WarnLevel: { + grpcLvlInfo, + }, + zapcore.ErrorLevel: { + grpcLvlInfo, grpcLvlWarn, + }, + zapcore.DPanicLevel: { + grpcLvlInfo, grpcLvlWarn, grpcLvlError, + }, + zapcore.PanicLevel: { + grpcLvlInfo, grpcLvlWarn, grpcLvlError, + }, + zapcore.FatalLevel: { + grpcLvlInfo, grpcLvlWarn, grpcLvlError, + }, + } + for zapLvl, grpcLvls := range disabled { + for _, grpcLvl := range grpcLvls { + t.Run(fmt.Sprintf("%s %d", zapLvl, grpcLvl), func(t *testing.T) { + checkLevel(t, zapLvl, false, func(logger *Logger) bool { + return logger.V(grpcLvl) + }) + }) + } + } } func checkLevel( From c83c545f9b826d445ca7e936ae93cfba9700e383 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy <126021+ash2k@users.noreply.github.com> Date: Thu, 4 Feb 2021 14:18:53 +1100 Subject: [PATCH 04/13] Update zapgrpc/zapgrpc.go Co-authored-by: Prashant Varanasi --- zapgrpc/zapgrpc.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 19aeb356f..216d81054 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -26,9 +26,8 @@ import ( "go.uber.org/zap/zapcore" ) +// See https://github.com/grpc/grpc-go/blob/v1.35.0/grpclog/loggerv2.go#L77-L86 const ( - // See https://github.com/grpc/grpc-go/blob/v1.35.0/grpclog/loggerv2.go#L77-L86 - grpcLvlInfo = 0 grpcLvlWarn = 1 grpcLvlError = 2 From aba3594886f09ea4960e42255570096d7caeabaa Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Thu, 4 Feb 2021 14:41:15 +1100 Subject: [PATCH 05/13] Rename global --- zapgrpc/zapgrpc.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 216d81054..7e4fed9ac 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -35,9 +35,9 @@ const ( ) var ( - // grpc2zapLvl maps gRPC log levels to zap log levels. + // _grpcToZapLevel maps gRPC log levels to zap log levels. // See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level - grpc2zapLvl = map[int]zapcore.Level{ + _grpcToZapLevel = map[int]zapcore.Level{ grpcLvlInfo: zapcore.InfoLevel, grpcLvlWarn: zapcore.WarnLevel, grpcLvlError: zapcore.ErrorLevel, @@ -182,7 +182,7 @@ func (l *Logger) Fatalf(format string, args ...interface{}) { // V implements grpclog.LoggerV2. func (l *Logger) V(level int) bool { - return l.delegate.Desugar().Core().Enabled(grpc2zapLvl[level]) + return l.delegate.Desugar().Core().Enabled(_grpcToZapLevel[level]) } // addSpaces always adds spaces between arguments like https://golang.org/pkg/fmt/#Println From 2a0779f1fa5d6b3af92e1cb7de05cb4f70b867b8 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Tue, 9 Feb 2021 11:08:45 +1100 Subject: [PATCH 06/13] Use fmt.Sprintln() --- zapgrpc/zapgrpc.go | 54 +++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 7e4fed9ac..2b6bf8fa5 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -22,6 +22,8 @@ package zapgrpc // import "go.uber.org/zap/zapgrpc" import ( + "fmt" + "go.uber.org/zap" "go.uber.org/zap/zapcore" ) @@ -109,7 +111,15 @@ func (l *Logger) Printf(format string, args ...interface{}) { // Println implements grpclog.Logger. // Deprecated: use Info(). func (l *Logger) Println(args ...interface{}) { - l.Print(addSpaces(args)...) + if l.printToDebug { + if l.delegate.Desugar().Core().Enabled(zapcore.DebugLevel) { + l.delegate.Debug(sprintln(args)) + } + } else { + if l.delegate.Desugar().Core().Enabled(zapcore.InfoLevel) { + l.delegate.Info(sprintln(args)) + } + } } // Info implements grpclog.LoggerV2. @@ -119,7 +129,9 @@ func (l *Logger) Info(args ...interface{}) { // Infoln implements grpclog.LoggerV2. func (l *Logger) Infoln(args ...interface{}) { - l.delegate.Info(addSpaces(args)...) + if l.delegate.Desugar().Core().Enabled(zapcore.InfoLevel) { + l.delegate.Info(sprintln(args)) + } } // Infof implements grpclog.LoggerV2. @@ -134,7 +146,9 @@ func (l *Logger) Warning(args ...interface{}) { // Warningln implements grpclog.LoggerV2. func (l *Logger) Warningln(args ...interface{}) { - l.delegate.Warn(addSpaces(args)...) + if l.delegate.Desugar().Core().Enabled(zapcore.WarnLevel) { + l.delegate.Warn(sprintln(args)) + } } // Warningf implements grpclog.LoggerV2. @@ -149,7 +163,9 @@ func (l *Logger) Error(args ...interface{}) { // Errorln implements grpclog.LoggerV2. func (l *Logger) Errorln(args ...interface{}) { - l.delegate.Error(addSpaces(args)...) + if l.delegate.Desugar().Core().Enabled(zapcore.ErrorLevel) { + l.delegate.Error(sprintln(args)) + } } // Errorf implements grpclog.LoggerV2. @@ -168,7 +184,15 @@ func (l *Logger) Fatal(args ...interface{}) { // Fatalln implements grpclog.LoggerV2. func (l *Logger) Fatalln(args ...interface{}) { - l.Fatal(addSpaces(args)...) + if l.fatalToWarn { + if l.delegate.Desugar().Core().Enabled(zapcore.WarnLevel) { + l.delegate.Warn(sprintln(args)) + } + } else { + if l.delegate.Desugar().Core().Enabled(zapcore.FatalLevel) { + l.delegate.Fatal(sprintln(args)) + } + } } // Fatalf implements grpclog.LoggerV2. @@ -185,21 +209,7 @@ func (l *Logger) V(level int) bool { return l.delegate.Desugar().Core().Enabled(_grpcToZapLevel[level]) } -// addSpaces always adds spaces between arguments like https://golang.org/pkg/fmt/#Println -func addSpaces(args []interface{}) []interface{} { - l := len(args) - if l == 0 || l == 1 { - return args - } - res := make([]interface{}, 0, l+l-1) - first := true - for _, arg := range args { - if first { - first = false - res = append(res, arg) - } else { - res = append(res, " ", arg) - } - } - return res +func sprintln(args []interface{}) string { + s := fmt.Sprintln(args...) + return s[:len(s)-1] } From bb6d5a3beb602bfa676cc21a9731e549870532d7 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Tue, 9 Feb 2021 11:12:26 +1100 Subject: [PATCH 07/13] Extract LevelEnabler into a field to avoid memory allocation --- zapgrpc/zapgrpc.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 2b6bf8fa5..b7dbaea41 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -72,6 +72,7 @@ func WithDebug() Option { func NewLogger(l *zap.Logger, options ...Option) *Logger { logger := &Logger{ delegate: l.Sugar(), + levelEnabler: l.Core(), printToDebug: false, fatalToWarn: false, } @@ -84,6 +85,7 @@ func NewLogger(l *zap.Logger, options ...Option) *Logger { // Logger adapts zap's Logger to be compatible with grpclog.LoggerV2 and the deprecated grpclog.Logger. type Logger struct { delegate *zap.SugaredLogger + levelEnabler zapcore.LevelEnabler printToDebug bool fatalToWarn bool } @@ -112,11 +114,11 @@ func (l *Logger) Printf(format string, args ...interface{}) { // Deprecated: use Info(). func (l *Logger) Println(args ...interface{}) { if l.printToDebug { - if l.delegate.Desugar().Core().Enabled(zapcore.DebugLevel) { + if l.levelEnabler.Enabled(zapcore.DebugLevel) { l.delegate.Debug(sprintln(args)) } } else { - if l.delegate.Desugar().Core().Enabled(zapcore.InfoLevel) { + if l.levelEnabler.Enabled(zapcore.InfoLevel) { l.delegate.Info(sprintln(args)) } } @@ -129,7 +131,7 @@ func (l *Logger) Info(args ...interface{}) { // Infoln implements grpclog.LoggerV2. func (l *Logger) Infoln(args ...interface{}) { - if l.delegate.Desugar().Core().Enabled(zapcore.InfoLevel) { + if l.levelEnabler.Enabled(zapcore.InfoLevel) { l.delegate.Info(sprintln(args)) } } @@ -146,7 +148,7 @@ func (l *Logger) Warning(args ...interface{}) { // Warningln implements grpclog.LoggerV2. func (l *Logger) Warningln(args ...interface{}) { - if l.delegate.Desugar().Core().Enabled(zapcore.WarnLevel) { + if l.levelEnabler.Enabled(zapcore.WarnLevel) { l.delegate.Warn(sprintln(args)) } } @@ -163,7 +165,7 @@ func (l *Logger) Error(args ...interface{}) { // Errorln implements grpclog.LoggerV2. func (l *Logger) Errorln(args ...interface{}) { - if l.delegate.Desugar().Core().Enabled(zapcore.ErrorLevel) { + if l.levelEnabler.Enabled(zapcore.ErrorLevel) { l.delegate.Error(sprintln(args)) } } @@ -185,11 +187,11 @@ func (l *Logger) Fatal(args ...interface{}) { // Fatalln implements grpclog.LoggerV2. func (l *Logger) Fatalln(args ...interface{}) { if l.fatalToWarn { - if l.delegate.Desugar().Core().Enabled(zapcore.WarnLevel) { + if l.levelEnabler.Enabled(zapcore.WarnLevel) { l.delegate.Warn(sprintln(args)) } } else { - if l.delegate.Desugar().Core().Enabled(zapcore.FatalLevel) { + if l.levelEnabler.Enabled(zapcore.FatalLevel) { l.delegate.Fatal(sprintln(args)) } } @@ -206,7 +208,7 @@ func (l *Logger) Fatalf(format string, args ...interface{}) { // V implements grpclog.LoggerV2. func (l *Logger) V(level int) bool { - return l.delegate.Desugar().Core().Enabled(_grpcToZapLevel[level]) + return l.levelEnabler.Enabled(_grpcToZapLevel[level]) } func sprintln(args []interface{}) string { From 3e969dba2bb7498265d95a8847f0f1c9c974ccd5 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Tue, 9 Feb 2021 11:20:27 +1100 Subject: [PATCH 08/13] More tests --- zapgrpc/zapgrpc_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/zapgrpc/zapgrpc_test.go b/zapgrpc/zapgrpc_test.go index 055c2153c..edc0bc59f 100644 --- a/zapgrpc/zapgrpc_test.go +++ b/zapgrpc/zapgrpc_test.go @@ -34,42 +34,54 @@ import ( func TestLoggerInfoExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, nil, zapcore.InfoLevel, []string{ "hello", + "s1s21 2 3s34s56", "hello world", "", "foo", "foo bar", + "s1 s2 1 2 3 s3 4 s5 6", "hello", + "s1s21 2 3s34s56", "hello world", "", "foo", "foo bar", + "s1 s2 1 2 3 s3 4 s5 6", }, func(logger *Logger) { logger.Info("hello") + logger.Info("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) logger.Infof("%s world", "hello") logger.Infoln() logger.Infoln("foo") logger.Infoln("foo", "bar") + logger.Infoln("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) logger.Print("hello") + logger.Print("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) logger.Printf("%s world", "hello") logger.Println() logger.Println("foo") logger.Println("foo", "bar") + logger.Println("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) }) } func TestLoggerDebugExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, []Option{WithDebug()}, zapcore.DebugLevel, []string{ "hello", + "s1s21 2 3s34s56", "hello world", "", "foo", "foo bar", + "s1 s2 1 2 3 s3 4 s5 6", }, func(logger *Logger) { logger.Print("hello") + logger.Print("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) logger.Printf("%s world", "hello") logger.Println() logger.Println("foo") logger.Println("foo", "bar") + logger.Println("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) }) } @@ -86,48 +98,60 @@ func TestLoggerDebugSuppressed(t *testing.T) { func TestLoggerWarningExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, nil, zapcore.WarnLevel, []string{ "hello", + "s1s21 2 3s34s56", "hello world", "", "foo", "foo bar", + "s1 s2 1 2 3 s3 4 s5 6", }, func(logger *Logger) { logger.Warning("hello") + logger.Warning("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) logger.Warningf("%s world", "hello") logger.Warningln() logger.Warningln("foo") logger.Warningln("foo", "bar") + logger.Warningln("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) }) } func TestLoggerErrorExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, nil, zapcore.ErrorLevel, []string{ "hello", + "s1s21 2 3s34s56", "hello world", "", "foo", "foo bar", + "s1 s2 1 2 3 s3 4 s5 6", }, func(logger *Logger) { logger.Error("hello") + logger.Error("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) logger.Errorf("%s world", "hello") logger.Errorln() logger.Errorln("foo") logger.Errorln("foo", "bar") + logger.Errorln("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) }) } func TestLoggerFatalExpected(t *testing.T) { checkMessages(t, zapcore.DebugLevel, nil, zapcore.FatalLevel, []string{ "hello", + "s1s21 2 3s34s56", "hello world", "", "foo", "foo bar", + "s1 s2 1 2 3 s3 4 s5 6", }, func(logger *Logger) { logger.Fatal("hello") + logger.Fatal("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) logger.Fatalf("%s world", "hello") logger.Fatalln() logger.Fatalln("foo") logger.Fatalln("foo", "bar") + logger.Fatalln("s1", "s2", 1, 2, 3, "s3", 4, "s5", 6) }) } From 5648c2f62350ebda1896741037039d0398f9f8db Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy <126021+ash2k@users.noreply.github.com> Date: Wed, 10 Feb 2021 10:02:39 +1100 Subject: [PATCH 09/13] Update zapgrpc/zapgrpc.go Co-authored-by: Prashant Varanasi --- zapgrpc/zapgrpc.go | 1 + 1 file changed, 1 insertion(+) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index b7dbaea41..1a5170d61 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -213,5 +213,6 @@ func (l *Logger) V(level int) bool { func sprintln(args []interface{}) string { s := fmt.Sprintln(args...) + // Drop the new line character added by Sprintln return s[:len(s)-1] } From 7c1ae7160ebb833e6fbc06ba51f3d5ec927696ae Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Wed, 10 Feb 2021 10:10:03 +1100 Subject: [PATCH 10/13] Refactor tests --- zapgrpc/zapgrpc_test.go | 92 ++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 51 deletions(-) diff --git a/zapgrpc/zapgrpc_test.go b/zapgrpc/zapgrpc_test.go index edc0bc59f..3f1e42f0c 100644 --- a/zapgrpc/zapgrpc_test.go +++ b/zapgrpc/zapgrpc_test.go @@ -155,69 +155,59 @@ func TestLoggerFatalExpected(t *testing.T) { }) } -func TestLoggerVTrueExpected(t *testing.T) { - enabled := map[zapcore.Level][]int{ - zapcore.DebugLevel: { - grpcLvlInfo, grpcLvlWarn, grpcLvlError, grpcLvlFatal, +func TestLoggerV(t *testing.T) { + tests := []struct { + zapLevel zapcore.Level + grpcEnabled []int + grpcDisabled []int + }{ + { + zapLevel: zapcore.DebugLevel, + grpcEnabled: []int{grpcLvlInfo, grpcLvlWarn, grpcLvlError, grpcLvlFatal}, + grpcDisabled: []int{}, // everything is enabled, nothing is disabled }, - zapcore.InfoLevel: { - grpcLvlInfo, grpcLvlWarn, grpcLvlError, grpcLvlFatal, + { + zapLevel: zapcore.InfoLevel, + grpcEnabled: []int{grpcLvlInfo, grpcLvlWarn, grpcLvlError, grpcLvlFatal}, + grpcDisabled: []int{}, // everything is enabled, nothing is disabled }, - zapcore.WarnLevel: { - grpcLvlWarn, grpcLvlError, grpcLvlFatal, + { + zapLevel: zapcore.WarnLevel, + grpcEnabled: []int{grpcLvlWarn, grpcLvlError, grpcLvlFatal}, + grpcDisabled: []int{grpcLvlInfo}, }, - zapcore.ErrorLevel: { - grpcLvlError, grpcLvlFatal, + { + zapLevel: zapcore.ErrorLevel, + grpcEnabled: []int{grpcLvlError, grpcLvlFatal}, + grpcDisabled: []int{grpcLvlInfo, grpcLvlWarn}, }, - zapcore.DPanicLevel: { - grpcLvlFatal, + { + zapLevel: zapcore.DPanicLevel, + grpcEnabled: []int{grpcLvlFatal}, + grpcDisabled: []int{grpcLvlInfo, grpcLvlWarn, grpcLvlError}, }, - zapcore.PanicLevel: { - grpcLvlFatal, + { + zapLevel: zapcore.PanicLevel, + grpcEnabled: []int{grpcLvlFatal}, + grpcDisabled: []int{grpcLvlInfo, grpcLvlWarn, grpcLvlError}, }, - zapcore.FatalLevel: { - grpcLvlFatal, + { + zapLevel: zapcore.FatalLevel, + grpcEnabled: []int{grpcLvlFatal}, + grpcDisabled: []int{grpcLvlInfo, grpcLvlWarn, grpcLvlError}, }, } - for zapLvl, grpcLvls := range enabled { - for _, grpcLvl := range grpcLvls { - t.Run(fmt.Sprintf("%s %d", zapLvl, grpcLvl), func(t *testing.T) { - checkLevel(t, zapLvl, true, func(logger *Logger) bool { + for _, tst := range tests { + for _, grpcLvl := range tst.grpcEnabled { + t.Run(fmt.Sprintf("enabled %s %d", tst.zapLevel, grpcLvl), func(t *testing.T) { + checkLevel(t, tst.zapLevel, true, func(logger *Logger) bool { return logger.V(grpcLvl) }) }) } - } -} - -func TestLoggerVFalseExpected(t *testing.T) { - disabled := map[zapcore.Level][]int{ - zapcore.DebugLevel: { - // everything is enabled, nothing is disabled - }, - zapcore.InfoLevel: { - // everything is enabled, nothing is disabled - }, - zapcore.WarnLevel: { - grpcLvlInfo, - }, - zapcore.ErrorLevel: { - grpcLvlInfo, grpcLvlWarn, - }, - zapcore.DPanicLevel: { - grpcLvlInfo, grpcLvlWarn, grpcLvlError, - }, - zapcore.PanicLevel: { - grpcLvlInfo, grpcLvlWarn, grpcLvlError, - }, - zapcore.FatalLevel: { - grpcLvlInfo, grpcLvlWarn, grpcLvlError, - }, - } - for zapLvl, grpcLvls := range disabled { - for _, grpcLvl := range grpcLvls { - t.Run(fmt.Sprintf("%s %d", zapLvl, grpcLvl), func(t *testing.T) { - checkLevel(t, zapLvl, false, func(logger *Logger) bool { + for _, grpcLvl := range tst.grpcDisabled { + t.Run(fmt.Sprintf("disabled %s %d", tst.zapLevel, grpcLvl), func(t *testing.T) { + checkLevel(t, tst.zapLevel, false, func(logger *Logger) bool { return logger.V(grpcLvl) }) }) From 9d034a298508c721896de588ab478d61e53bfe76 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Fri, 12 Feb 2021 09:27:39 -0800 Subject: [PATCH 11/13] grpclog: Fix lint issue --- zapgrpc/zapgrpc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 1a5170d61..50a4296f1 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -213,6 +213,6 @@ func (l *Logger) V(level int) bool { func sprintln(args []interface{}) string { s := fmt.Sprintln(args...) - // Drop the new line character added by Sprintln + // Drop the new line character added by Sprintln return s[:len(s)-1] } From 6bbb45d3d8bd9a92f44cf29bd6e75304a7cab894 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Fri, 12 Feb 2021 10:59:22 -0800 Subject: [PATCH 12/13] zapgrpc: Simplify fatal/print redirection Instead of an if/else on each Print and Fatal log statement, handle the indirection once with function references. --- zapgrpc/zapgrpc.go | 109 ++++++++++++++++++++++++---------------- zapgrpc/zapgrpc_test.go | 8 --- 2 files changed, 66 insertions(+), 51 deletions(-) diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 50a4296f1..356e12741 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -64,7 +64,25 @@ func (f optionFunc) apply(log *Logger) { // Deprecated: use grpclog.SetLoggerV2() for v2 API. func WithDebug() Option { return optionFunc(func(logger *Logger) { - logger.printToDebug = true + logger.print = &printer{ + enab: logger.levelEnabler, + level: zapcore.DebugLevel, + print: logger.delegate.Debug, + printf: logger.delegate.Debugf, + } + }) +} + +// withWarn redirects the fatal level to the warn level, which makes testing +// easier. This is intentionally unexported. +func withWarn() Option { + return optionFunc(func(logger *Logger) { + logger.fatal = &printer{ + enab: logger.levelEnabler, + level: zapcore.WarnLevel, + print: logger.delegate.Warn, + printf: logger.delegate.Warnf, + } }) } @@ -73,8 +91,18 @@ func NewLogger(l *zap.Logger, options ...Option) *Logger { logger := &Logger{ delegate: l.Sugar(), levelEnabler: l.Core(), - printToDebug: false, - fatalToWarn: false, + } + logger.print = &printer{ + enab: logger.levelEnabler, + level: zapcore.InfoLevel, + print: logger.delegate.Info, + printf: logger.delegate.Infof, + } + logger.fatal = &printer{ + enab: logger.levelEnabler, + level: zapcore.FatalLevel, + print: logger.delegate.Fatal, + printf: logger.delegate.Fatalf, } for _, option := range options { option.apply(logger) @@ -82,46 +110,57 @@ func NewLogger(l *zap.Logger, options ...Option) *Logger { return logger } +// printer implements Print, Printf, and Println operations for a Zap level. +// +// We use it to customize Debug vs Info, and Warn vs Fatal for Print and Fatal +// respectively. +type printer struct { + enab zapcore.LevelEnabler + level zapcore.Level + print func(...interface{}) + printf func(string, ...interface{}) +} + +func (v *printer) Print(args ...interface{}) { + v.print(args...) +} + +func (v *printer) Printf(format string, args ...interface{}) { + v.printf(format, args...) +} + +func (v *printer) Println(args ...interface{}) { + if v.enab.Enabled(v.level) { + v.print(sprintln(args)) + } +} + // Logger adapts zap's Logger to be compatible with grpclog.LoggerV2 and the deprecated grpclog.Logger. type Logger struct { delegate *zap.SugaredLogger levelEnabler zapcore.LevelEnabler - printToDebug bool - fatalToWarn bool + print *printer + fatal *printer + // printToDebug bool + // fatalToWarn bool } // Print implements grpclog.Logger. // Deprecated: use Info(). func (l *Logger) Print(args ...interface{}) { - if l.printToDebug { - l.delegate.Debug(args...) - } else { - l.delegate.Info(args...) - } + l.print.Print(args...) } // Printf implements grpclog.Logger. // Deprecated: use Infof(). func (l *Logger) Printf(format string, args ...interface{}) { - if l.printToDebug { - l.delegate.Debugf(format, args...) - } else { - l.delegate.Infof(format, args...) - } + l.print.Printf(format, args...) } // Println implements grpclog.Logger. // Deprecated: use Info(). func (l *Logger) Println(args ...interface{}) { - if l.printToDebug { - if l.levelEnabler.Enabled(zapcore.DebugLevel) { - l.delegate.Debug(sprintln(args)) - } - } else { - if l.levelEnabler.Enabled(zapcore.InfoLevel) { - l.delegate.Info(sprintln(args)) - } - } + l.print.Println(args...) } // Info implements grpclog.LoggerV2. @@ -177,33 +216,17 @@ func (l *Logger) Errorf(format string, args ...interface{}) { // Fatal implements grpclog.LoggerV2. func (l *Logger) Fatal(args ...interface{}) { - if l.fatalToWarn { - l.delegate.Warn(args...) - } else { - l.delegate.Fatal(args...) - } + l.fatal.Print(args...) } // Fatalln implements grpclog.LoggerV2. func (l *Logger) Fatalln(args ...interface{}) { - if l.fatalToWarn { - if l.levelEnabler.Enabled(zapcore.WarnLevel) { - l.delegate.Warn(sprintln(args)) - } - } else { - if l.levelEnabler.Enabled(zapcore.FatalLevel) { - l.delegate.Fatal(sprintln(args)) - } - } + l.fatal.Println(args...) } // Fatalf implements grpclog.LoggerV2. func (l *Logger) Fatalf(format string, args ...interface{}) { - if l.fatalToWarn { - l.delegate.Warnf(format, args...) - } else { - l.delegate.Fatalf(format, args...) - } + l.fatal.Printf(format, args...) } // V implements grpclog.LoggerV2. diff --git a/zapgrpc/zapgrpc_test.go b/zapgrpc/zapgrpc_test.go index 3f1e42f0c..a231d65ec 100644 --- a/zapgrpc/zapgrpc_test.go +++ b/zapgrpc/zapgrpc_test.go @@ -261,11 +261,3 @@ func withLogger( core, observedLogs := observer.New(enab) f(NewLogger(zap.New(core), append(opts, withWarn())...), observedLogs) } - -// withWarn redirects the fatal level to the warn level, which makes testing -// easier. -func withWarn() Option { - return optionFunc(func(logger *Logger) { - logger.fatalToWarn = true - }) -} From 4b0ccf681470caf35614e7c22f616e2c8389aab0 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Fri, 12 Feb 2021 09:27:26 -0800 Subject: [PATCH 13/13] zapgrpc: Add submodule to test against grpc-go Add a zapgrpc/internal/test submodule that tests the zapgrpc logger against grpc-go directly. Because this is a submodule, it will not add grpc as a dependency of zap. --- Makefile | 2 +- zapgrpc/internal/test/README.md | 2 + zapgrpc/internal/test/go.mod | 11 +++ zapgrpc/internal/test/go.sum | 123 +++++++++++++++++++++++++++++ zapgrpc/internal/test/grpc_test.go | 51 ++++++++++++ 5 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 zapgrpc/internal/test/README.md create mode 100644 zapgrpc/internal/test/go.mod create mode 100644 zapgrpc/internal/test/go.sum create mode 100644 zapgrpc/internal/test/grpc_test.go diff --git a/Makefile b/Makefile index dfaf6406e..d30209cff 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ BENCH_FLAGS ?= -cpuprofile=cpu.pprof -memprofile=mem.pprof -benchmem # Directories containing independent Go modules. # # We track coverage only for the main module. -MODULE_DIRS = . ./benchmarks +MODULE_DIRS = . ./benchmarks ./zapgrpc/internal/test # Many Go tools take file globs or directories as arguments instead of packages. GO_FILES := $(shell \ diff --git a/zapgrpc/internal/test/README.md b/zapgrpc/internal/test/README.md new file mode 100644 index 000000000..b2f3f0f80 --- /dev/null +++ b/zapgrpc/internal/test/README.md @@ -0,0 +1,2 @@ +This submodule exists to test zapgrpc against grpc-go without adding a +dependency on grpc-go to Zap. diff --git a/zapgrpc/internal/test/go.mod b/zapgrpc/internal/test/go.mod new file mode 100644 index 000000000..a8b1683a7 --- /dev/null +++ b/zapgrpc/internal/test/go.mod @@ -0,0 +1,11 @@ +module go.uber.org/zap/zapgrpc/internal/test + +go 1.15 + +require ( + github.com/stretchr/testify v1.5.1 + go.uber.org/zap v1.16.0 + google.golang.org/grpc v1.35.0 +) + +replace go.uber.org/zap => ../../.. diff --git a/zapgrpc/internal/test/go.sum b/zapgrpc/internal/test/go.sum new file mode 100644 index 000000000..735587620 --- /dev/null +++ b/zapgrpc/internal/test/go.sum @@ -0,0 +1,123 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/zapgrpc/internal/test/grpc_test.go b/zapgrpc/internal/test/grpc_test.go new file mode 100644 index 000000000..f4befeb26 --- /dev/null +++ b/zapgrpc/internal/test/grpc_test.go @@ -0,0 +1,51 @@ +// Copyright (c) 2021 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package main + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zapgrpc" + "go.uber.org/zap/zaptest/observer" + "google.golang.org/grpc/grpclog" +) + +func TestLoggerV2(t *testing.T) { + core, observedLogs := observer.New(zapcore.InfoLevel) + zlog := zap.New(core) + + grpclog.SetLoggerV2(zapgrpc.NewLogger(zlog)) + + grpclog.Info("hello from grpc") + + logs := observedLogs.TakeAll() + require.Len(t, logs, 1, "Expected one log entry.") + entry := logs[0] + + assert.Equal(t, zapcore.InfoLevel, entry.Level, + "Log entry level did not match.") + assert.Equal(t, "hello from grpc", entry.Message, + "Log entry message did not match.") +}