diff --git a/logging/zap/doc.go b/logging/zap/doc.go index 14735fc38..ffa6b5c31 100644 --- a/logging/zap/doc.go +++ b/logging/zap/doc.go @@ -70,5 +70,6 @@ Note - due to implementation ZAP differs from Logrus in the "grpc.request.conten Please see examples and tests for examples of use. +Please see settable_test.go for canonical integration through "zaptest" with golang testing infrastructure. */ package grpc_zap diff --git a/logging/zap/grpclogger.go b/logging/zap/grpclogger.go index 42842c991..85fc2100a 100644 --- a/logging/zap/grpclogger.go +++ b/logging/zap/grpclogger.go @@ -6,6 +6,7 @@ package grpc_zap import ( "fmt" + grpc_logsettable "github.com/grpc-ecosystem/go-grpc-middleware/logging/settable" "go.uber.org/zap" "google.golang.org/grpc/grpclog" ) @@ -47,11 +48,13 @@ func (l *zapGrpcLogger) Println(args ...interface{}) { } // ReplaceGrpcLoggerV2 replaces the grpc_log.LoggerV2 with the provided logger. +// It should be called before any gRPC functions. func ReplaceGrpcLoggerV2(logger *zap.Logger) { ReplaceGrpcLoggerV2WithVerbosity(logger, 0) } // ReplaceGrpcLoggerV2WithVerbosity replaces the grpc_.LoggerV2 with the provided logger and verbosity. +// It should be called before any gRPC functions. func ReplaceGrpcLoggerV2WithVerbosity(logger *zap.Logger, verbosity int) { zgl := &zapGrpcLoggerV2{ logger: logger.With(SystemField, zap.Bool("grpc_log", true)), @@ -60,6 +63,22 @@ func ReplaceGrpcLoggerV2WithVerbosity(logger *zap.Logger, verbosity int) { grpclog.SetLoggerV2(zgl) } +// SetGrpcLoggerV2 replaces the grpc_log.LoggerV2 with the provided logger. +// It can be used even when grpc infrastructure was initialized. +func SetGrpcLoggerV2(settable grpc_logsettable.SettableLoggerV2, logger *zap.Logger) { + SetGrpcLoggerV2WithVerbosity(settable, logger, 0) +} + +// SetGrpcLoggerV2WithVerbosity replaces the grpc_.LoggerV2 with the provided logger and verbosity. +// It can be used even when grpc infrastructure was initialized. +func SetGrpcLoggerV2WithVerbosity(settable grpc_logsettable.SettableLoggerV2, logger *zap.Logger, verbosity int) { + zgl := &zapGrpcLoggerV2{ + logger: logger.With(SystemField, zap.Bool("grpc_log", true)), + verbosity: verbosity, + } + settable.Set(zgl) +} + type zapGrpcLoggerV2 struct { logger *zap.Logger verbosity int diff --git a/logging/zap/settable_test.go b/logging/zap/settable_test.go new file mode 100644 index 000000000..a5440dba4 --- /dev/null +++ b/logging/zap/settable_test.go @@ -0,0 +1,31 @@ +package grpc_zap_test + +import ( + "testing" + + grpc_logsettable "github.com/grpc-ecosystem/go-grpc-middleware/logging/settable" + grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" + "go.uber.org/zap/zaptest" +) + +var grpc_logger grpc_logsettable.SettableLoggerV2 + +func init() { + grpc_logger = grpc_logsettable.ReplaceGrpcLoggerV2() +} + +func beforeTest(t testing.TB) { + grpc_zap.SetGrpcLoggerV2(grpc_logger, zaptest.NewLogger(t)) + t.Cleanup(func() { + grpc_logger.Reset() + }) +} + +// This test illustrates setting up a testing harness that attributes +// all grpc logs emitted during the test to the test-specific log. +// +// In case of test failure, only logs emitted by this testcase will be printed. +func TestSpecificLogging(t *testing.T) { + beforeTest(t) + grpc_logger.Info("Test specific log-line") +}