本文主要研究一下golang的zap的zapgrpc
zap@v1.16.0/zapgrpc/zapgrpc.go
package zapgrpc // import "go.uber.org/zap/zapgrpc" import "go.uber.org/zap" // An Option overrides a Logger's default configuration. type Option interface { apply(*Logger) } type optionFunc func(*Logger) func (f optionFunc) apply(log *Logger) { f(log) } // WithDebug configures a Logger to print at zap's DebugLevel instead of // InfoLevel. func WithDebug() Option { return optionFunc(func(logger *Logger) { logger.print = (*zap.SugaredLogger).Debug logger.printf = (*zap.SugaredLogger).Debugf }) } // 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, } for _, option := range options { option.apply(logger) } return logger } // Logger adapts zap's Logger to be compatible with 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...) } // Print implements grpclog.Logger. func (l *Logger) Print(args ...interface{}) { l.print(l.log, args...) } // Printf implements grpclog.Logger. func (l *Logger) Printf(format string, args ...interface{}) { l.printf(l.log, format, args...) } // Println implements grpclog.Logger. func (l *Logger) Println(args ...interface{}) { l.print(l.log, args...) }
zapgrpc提供了对grpclog.Logger的适配,NewLogger将zap.Logger适配为zapgrpc.Logger,而该logger实现了grpclog.Logger接口
https://github.com/grpc/grpc-...
package grpclog import "google.golang.org/grpc/internal/grpclog" // Logger mimics golang's standard Logger as an interface. // // Deprecated: use LoggerV2. type Logger interface { Fatal(args ...interface{}) Fatalf(format string, args ...interface{}) Fatalln(args ...interface{}) Print(args ...interface{}) Printf(format string, args ...interface{}) Println(args ...interface{}) } // SetLogger sets the logger that is used in grpc. Call only from // init() functions. // // Deprecated: use SetLoggerV2. func SetLogger(l Logger) { grpclog.Logger = &loggerWrapper{Logger: l} } // loggerWrapper wraps Logger into a LoggerV2. type loggerWrapper struct { Logger } func (g *loggerWrapper) Info(args ...interface{}) { g.Logger.Print(args...) } func (g *loggerWrapper) Infoln(args ...interface{}) { g.Logger.Println(args...) } func (g *loggerWrapper) Infof(format string, args ...interface{}) { g.Logger.Printf(format, args...) } func (g *loggerWrapper) Warning(args ...interface{}) { g.Logger.Print(args...) } func (g *loggerWrapper) Warningln(args ...interface{}) { g.Logger.Println(args...) } func (g *loggerWrapper) Warningf(format string, args ...interface{}) { g.Logger.Printf(format, args...) } func (g *loggerWrapper) Error(args ...interface{}) { g.Logger.Print(args...) } func (g *loggerWrapper) Errorln(args ...interface{}) { g.Logger.Println(args...) } func (g *loggerWrapper) Errorf(format string, args ...interface{}) { g.Logger.Printf(format, args...) } func (g *loggerWrapper) V(l int) bool { // Returns true for all verbose level. return true }
grpclog.Logger接口定义了Fatal(args ...interface{})、Fatalf(format string, args ...interface{})、Fatalln(args ...interface{})、Print(args ...interface{})、Printf(format string, args ...interface{})、Println(args ...interface{})方法;而grpclog.loggerWrapper会对grpclog.Logger进行适配,转而提供了Info、Infoln、Infof、Warning、Warningln、Warningf、Error、Errorln、Errorf方法
func Example_initialization() { // Shared options for the logger, with a custom gRPC code to log level function. opts := []grpc_zap.Option{ grpc_zap.WithLevels(customFunc), } // Make sure that log statements internal to gRPC library are logged using the zapLogger as well. grpc_zap.ReplaceGrpcLoggerV2(zapLogger) // Create a server, make sure we put the grpc_ctxtags context before everything else. _ = grpc.NewServer( grpc_middleware.WithUnaryServerChain( grpc_ctxtags.UnaryServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)), grpc_zap.UnaryServerInterceptor(zapLogger, opts...), ), grpc_middleware.WithStreamServerChain( grpc_ctxtags.StreamServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)), grpc_zap.StreamServerInterceptor(zapLogger, opts...), ), ) }
zapgrpc提供了对grpclog.Logger的适配,NewLogger将zap.Logger适配为zapgrpc.Logger,而该logger实现了grpclog.Logger接口。