diff --git a/pkg/logutil/zap_grpc.go b/pkg/logutil/zap_grpc.go index 0a28dbf85..3f48d813d 100644 --- a/pkg/logutil/zap_grpc.go +++ b/pkg/logutil/zap_grpc.go @@ -31,6 +31,15 @@ func NewGRPCLoggerV2(lcfg zap.Config) (grpclog.LoggerV2, error) { return &zapGRPCLogger{lg: lg, sugar: lg.Sugar()}, nil } +// NewGRPCLoggerV2FromZapCore creates "grpclog.LoggerV2" from "zap.Core" +// and "zapcore.WriteSyncer". It discards all INFO level logging in gRPC, +// if debug level is not enabled in "*zap.Logger". +func NewGRPCLoggerV2FromZapCore(cr zapcore.Core, syncer zapcore.WriteSyncer) grpclog.LoggerV2 { + // "AddCallerSkip" to annotate caller outside of "logutil" + lg := zap.New(cr, zap.AddCaller(), zap.AddCallerSkip(1), zap.ErrorOutput(syncer)) + return &zapGRPCLogger{lg: lg, sugar: lg.Sugar()} +} + type zapGRPCLogger struct { lg *zap.Logger sugar *zap.SugaredLogger diff --git a/pkg/logutil/zap_grpc_test.go b/pkg/logutil/zap_grpc_test.go index 95b114869..7bd71e53b 100644 --- a/pkg/logutil/zap_grpc_test.go +++ b/pkg/logutil/zap_grpc_test.go @@ -20,10 +20,12 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "testing" "time" "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) func TestNewGRPCLoggerV2(t *testing.T) { @@ -70,3 +72,20 @@ func TestNewGRPCLoggerV2(t *testing.T) { t.Fatalf("unexpected caller; %q", string(data)) } } + +func TestNewGRPCLoggerV2FromZapCore(t *testing.T) { + buf := bytes.NewBuffer(nil) + syncer := zapcore.AddSync(buf) + cr := zapcore.NewCore( + zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), + syncer, + zap.NewAtomicLevelAt(zap.InfoLevel), + ) + + lg := NewGRPCLoggerV2FromZapCore(cr, syncer) + lg.Warning("TestNewGRPCLoggerV2FromZapCore") + txt := buf.String() + if !strings.Contains(txt, "TestNewGRPCLoggerV2FromZapCore") { + t.Fatalf("unexpected log %q", txt) + } +}