...

Source file src/go.uber.org/zap/zapgrpc/zapgrpc.go

Documentation: go.uber.org/zap/zapgrpc

     1  // Copyright (c) 2016 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  // Package zapgrpc provides a logger that is compatible with grpclog.
    22  package zapgrpc // import "go.uber.org/zap/zapgrpc"
    23  
    24  import (
    25  	"fmt"
    26  
    27  	"go.uber.org/zap"
    28  	"go.uber.org/zap/zapcore"
    29  )
    30  
    31  // See https://github.com/grpc/grpc-go/blob/v1.35.0/grpclog/loggerv2.go#L77-L86
    32  const (
    33  	grpcLvlInfo int = iota
    34  	grpcLvlWarn
    35  	grpcLvlError
    36  	grpcLvlFatal
    37  )
    38  
    39  // _grpcToZapLevel maps gRPC log levels to zap log levels.
    40  // See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level
    41  var _grpcToZapLevel = map[int]zapcore.Level{
    42  	grpcLvlInfo:  zapcore.InfoLevel,
    43  	grpcLvlWarn:  zapcore.WarnLevel,
    44  	grpcLvlError: zapcore.ErrorLevel,
    45  	grpcLvlFatal: zapcore.FatalLevel,
    46  }
    47  
    48  // An Option overrides a Logger's default configuration.
    49  type Option interface {
    50  	apply(*Logger)
    51  }
    52  
    53  type optionFunc func(*Logger)
    54  
    55  func (f optionFunc) apply(log *Logger) {
    56  	f(log)
    57  }
    58  
    59  // WithDebug configures a Logger to print at zap's DebugLevel instead of
    60  // InfoLevel.
    61  // It only affects the Printf, Println and Print methods, which are only used in the gRPC v1 grpclog.Logger API.
    62  //
    63  // Deprecated: use grpclog.SetLoggerV2() for v2 API.
    64  func WithDebug() Option {
    65  	return optionFunc(func(logger *Logger) {
    66  		logger.print = &printer{
    67  			enab:   logger.levelEnabler,
    68  			level:  zapcore.DebugLevel,
    69  			print:  logger.delegate.Debug,
    70  			printf: logger.delegate.Debugf,
    71  		}
    72  	})
    73  }
    74  
    75  // withWarn redirects the fatal level to the warn level, which makes testing
    76  // easier. This is intentionally unexported.
    77  func withWarn() Option {
    78  	return optionFunc(func(logger *Logger) {
    79  		logger.fatal = &printer{
    80  			enab:   logger.levelEnabler,
    81  			level:  zapcore.WarnLevel,
    82  			print:  logger.delegate.Warn,
    83  			printf: logger.delegate.Warnf,
    84  		}
    85  	})
    86  }
    87  
    88  // NewLogger returns a new Logger.
    89  func NewLogger(l *zap.Logger, options ...Option) *Logger {
    90  	logger := &Logger{
    91  		delegate:     l.Sugar(),
    92  		levelEnabler: l.Core(),
    93  	}
    94  	logger.print = &printer{
    95  		enab:   logger.levelEnabler,
    96  		level:  zapcore.InfoLevel,
    97  		print:  logger.delegate.Info,
    98  		printf: logger.delegate.Infof,
    99  	}
   100  	logger.fatal = &printer{
   101  		enab:   logger.levelEnabler,
   102  		level:  zapcore.FatalLevel,
   103  		print:  logger.delegate.Fatal,
   104  		printf: logger.delegate.Fatalf,
   105  	}
   106  	for _, option := range options {
   107  		option.apply(logger)
   108  	}
   109  	return logger
   110  }
   111  
   112  // printer implements Print, Printf, and Println operations for a Zap level.
   113  //
   114  // We use it to customize Debug vs Info, and Warn vs Fatal for Print and Fatal
   115  // respectively.
   116  type printer struct {
   117  	enab   zapcore.LevelEnabler
   118  	level  zapcore.Level
   119  	print  func(...interface{})
   120  	printf func(string, ...interface{})
   121  }
   122  
   123  func (v *printer) Print(args ...interface{}) {
   124  	v.print(args...)
   125  }
   126  
   127  func (v *printer) Printf(format string, args ...interface{}) {
   128  	v.printf(format, args...)
   129  }
   130  
   131  func (v *printer) Println(args ...interface{}) {
   132  	if v.enab.Enabled(v.level) {
   133  		v.print(sprintln(args))
   134  	}
   135  }
   136  
   137  // Logger adapts zap's Logger to be compatible with grpclog.LoggerV2 and the deprecated grpclog.Logger.
   138  type Logger struct {
   139  	delegate     *zap.SugaredLogger
   140  	levelEnabler zapcore.LevelEnabler
   141  	print        *printer
   142  	fatal        *printer
   143  	// printToDebug bool
   144  	// fatalToWarn  bool
   145  }
   146  
   147  // Print implements grpclog.Logger.
   148  //
   149  // Deprecated: use [Logger.Info].
   150  func (l *Logger) Print(args ...interface{}) {
   151  	l.print.Print(args...)
   152  }
   153  
   154  // Printf implements grpclog.Logger.
   155  //
   156  // Deprecated: use [Logger.Infof].
   157  func (l *Logger) Printf(format string, args ...interface{}) {
   158  	l.print.Printf(format, args...)
   159  }
   160  
   161  // Println implements grpclog.Logger.
   162  //
   163  // Deprecated: use [Logger.Info].
   164  func (l *Logger) Println(args ...interface{}) {
   165  	l.print.Println(args...)
   166  }
   167  
   168  // Info implements grpclog.LoggerV2.
   169  func (l *Logger) Info(args ...interface{}) {
   170  	l.delegate.Info(args...)
   171  }
   172  
   173  // Infoln implements grpclog.LoggerV2.
   174  func (l *Logger) Infoln(args ...interface{}) {
   175  	if l.levelEnabler.Enabled(zapcore.InfoLevel) {
   176  		l.delegate.Info(sprintln(args))
   177  	}
   178  }
   179  
   180  // Infof implements grpclog.LoggerV2.
   181  func (l *Logger) Infof(format string, args ...interface{}) {
   182  	l.delegate.Infof(format, args...)
   183  }
   184  
   185  // Warning implements grpclog.LoggerV2.
   186  func (l *Logger) Warning(args ...interface{}) {
   187  	l.delegate.Warn(args...)
   188  }
   189  
   190  // Warningln implements grpclog.LoggerV2.
   191  func (l *Logger) Warningln(args ...interface{}) {
   192  	if l.levelEnabler.Enabled(zapcore.WarnLevel) {
   193  		l.delegate.Warn(sprintln(args))
   194  	}
   195  }
   196  
   197  // Warningf implements grpclog.LoggerV2.
   198  func (l *Logger) Warningf(format string, args ...interface{}) {
   199  	l.delegate.Warnf(format, args...)
   200  }
   201  
   202  // Error implements grpclog.LoggerV2.
   203  func (l *Logger) Error(args ...interface{}) {
   204  	l.delegate.Error(args...)
   205  }
   206  
   207  // Errorln implements grpclog.LoggerV2.
   208  func (l *Logger) Errorln(args ...interface{}) {
   209  	if l.levelEnabler.Enabled(zapcore.ErrorLevel) {
   210  		l.delegate.Error(sprintln(args))
   211  	}
   212  }
   213  
   214  // Errorf implements grpclog.LoggerV2.
   215  func (l *Logger) Errorf(format string, args ...interface{}) {
   216  	l.delegate.Errorf(format, args...)
   217  }
   218  
   219  // Fatal implements grpclog.LoggerV2.
   220  func (l *Logger) Fatal(args ...interface{}) {
   221  	l.fatal.Print(args...)
   222  }
   223  
   224  // Fatalln implements grpclog.LoggerV2.
   225  func (l *Logger) Fatalln(args ...interface{}) {
   226  	l.fatal.Println(args...)
   227  }
   228  
   229  // Fatalf implements grpclog.LoggerV2.
   230  func (l *Logger) Fatalf(format string, args ...interface{}) {
   231  	l.fatal.Printf(format, args...)
   232  }
   233  
   234  // V implements grpclog.LoggerV2.
   235  func (l *Logger) V(level int) bool {
   236  	return l.levelEnabler.Enabled(_grpcToZapLevel[level])
   237  }
   238  
   239  func sprintln(args []interface{}) string {
   240  	s := fmt.Sprintln(args...)
   241  	// Drop the new line character added by Sprintln
   242  	return s[:len(s)-1]
   243  }
   244  

View as plain text