diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 24b673849..c0f5e5c85 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -26,6 +26,18 @@ import ( "go.uber.org/zap/zapcore" ) +var ( + // grpc2zapLvl maps gRPC log levels to zap log levels. + // See https://github.com/grpc/grpc-go/blob/v1.35.0/grpclog/loggerv2.go#L77-L86 + // See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level + grpc2zapLvl = map[int]zapcore.Level{ + 0: zapcore.InfoLevel, + 1: zapcore.WarnLevel, + 2: zapcore.ErrorLevel, + 3: zapcore.FatalLevel, + } +) + // An Option overrides a Logger's default configuration. type Option interface { apply(*Logger) @@ -90,7 +102,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 +112,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 +127,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 +142,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 +161,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 +175,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..dd01900ee 100644 --- a/zapgrpc/zapgrpc_test.go +++ b/zapgrpc/zapgrpc_test.go @@ -33,74 +33,100 @@ 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") }) }