gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/go-grpc-middleware/logging/logrus/options.go (about)

     1  // Copyright 2017 Michal Witkowski. All Rights Reserved.
     2  // See LICENSE for licensing terms.
     3  
     4  package grpc_logrus
     5  
     6  import (
     7  	"time"
     8  
     9  	grpclogging "gitee.com/zhaochuninhefei/gmgo/go-grpc-middleware/logging"
    10  	"gitee.com/zhaochuninhefei/gmgo/grpc/codes"
    11  	"github.com/sirupsen/logrus"
    12  )
    13  
    14  var (
    15  	defaultOptions = &options{
    16  		levelFunc:    nil,
    17  		shouldLog:    grpclogging.DefaultDeciderMethod,
    18  		codeFunc:     grpclogging.DefaultErrorToCode,
    19  		durationFunc: DefaultDurationToField,
    20  	}
    21  )
    22  
    23  type options struct {
    24  	levelFunc    CodeToLevel
    25  	shouldLog    grpclogging.Decider
    26  	codeFunc     grpclogging.ErrorToCode
    27  	durationFunc DurationToField
    28  }
    29  
    30  func evaluateServerOpt(opts []Option) *options {
    31  	optCopy := &options{}
    32  	*optCopy = *defaultOptions
    33  	optCopy.levelFunc = DefaultCodeToLevel
    34  	for _, o := range opts {
    35  		o(optCopy)
    36  	}
    37  	return optCopy
    38  }
    39  
    40  func evaluateClientOpt(opts []Option) *options {
    41  	optCopy := &options{}
    42  	*optCopy = *defaultOptions
    43  	optCopy.levelFunc = DefaultClientCodeToLevel
    44  	for _, o := range opts {
    45  		o(optCopy)
    46  	}
    47  	return optCopy
    48  }
    49  
    50  type Option func(*options)
    51  
    52  // CodeToLevel function defines the mapping between gRPC return codes and interceptor log level.
    53  type CodeToLevel func(code codes.Code) logrus.Level
    54  
    55  // DurationToField function defines how to produce duration fields for logging
    56  type DurationToField func(duration time.Duration) (key string, value interface{})
    57  
    58  // WithDecider customizes the function for deciding if the gRPC interceptor logs should log.
    59  func WithDecider(f grpclogging.Decider) Option {
    60  	return func(o *options) {
    61  		o.shouldLog = f
    62  	}
    63  }
    64  
    65  // WithLevels customizes the function for mapping gRPC return codes and interceptor log level statements.
    66  func WithLevels(f CodeToLevel) Option {
    67  	return func(o *options) {
    68  		o.levelFunc = f
    69  	}
    70  }
    71  
    72  // WithCodes customizes the function for mapping errors to error codes.
    73  //goland:noinspection GoUnusedExportedFunction
    74  func WithCodes(f grpclogging.ErrorToCode) Option {
    75  	return func(o *options) {
    76  		o.codeFunc = f
    77  	}
    78  }
    79  
    80  // WithDurationField customizes the function for mapping request durations to log fields.
    81  func WithDurationField(f DurationToField) Option {
    82  	return func(o *options) {
    83  		o.durationFunc = f
    84  	}
    85  }
    86  
    87  // DefaultCodeToLevel is the default implementation of gRPC return codes to log levels for server side.
    88  func DefaultCodeToLevel(code codes.Code) logrus.Level {
    89  	switch code {
    90  	case codes.OK:
    91  		return logrus.InfoLevel
    92  	case codes.Canceled:
    93  		return logrus.InfoLevel
    94  	case codes.Unknown:
    95  		return logrus.ErrorLevel
    96  	case codes.InvalidArgument:
    97  		return logrus.InfoLevel
    98  	case codes.DeadlineExceeded:
    99  		return logrus.WarnLevel
   100  	case codes.NotFound:
   101  		return logrus.InfoLevel
   102  	case codes.AlreadyExists:
   103  		return logrus.InfoLevel
   104  	case codes.PermissionDenied:
   105  		return logrus.WarnLevel
   106  	case codes.Unauthenticated:
   107  		return logrus.InfoLevel // unauthenticated requests can happen
   108  	case codes.ResourceExhausted:
   109  		return logrus.WarnLevel
   110  	case codes.FailedPrecondition:
   111  		return logrus.WarnLevel
   112  	case codes.Aborted:
   113  		return logrus.WarnLevel
   114  	case codes.OutOfRange:
   115  		return logrus.WarnLevel
   116  	case codes.Unimplemented:
   117  		return logrus.ErrorLevel
   118  	case codes.Internal:
   119  		return logrus.ErrorLevel
   120  	case codes.Unavailable:
   121  		return logrus.WarnLevel
   122  	case codes.DataLoss:
   123  		return logrus.ErrorLevel
   124  	default:
   125  		return logrus.ErrorLevel
   126  	}
   127  }
   128  
   129  // DefaultClientCodeToLevel is the default implementation of gRPC return codes to log levels for client side.
   130  func DefaultClientCodeToLevel(code codes.Code) logrus.Level {
   131  	switch code {
   132  	case codes.OK:
   133  		return logrus.DebugLevel
   134  	case codes.Canceled:
   135  		return logrus.DebugLevel
   136  	case codes.Unknown:
   137  		return logrus.InfoLevel
   138  	case codes.InvalidArgument:
   139  		return logrus.DebugLevel
   140  	case codes.DeadlineExceeded:
   141  		return logrus.InfoLevel
   142  	case codes.NotFound:
   143  		return logrus.DebugLevel
   144  	case codes.AlreadyExists:
   145  		return logrus.DebugLevel
   146  	case codes.PermissionDenied:
   147  		return logrus.InfoLevel
   148  	case codes.Unauthenticated:
   149  		return logrus.InfoLevel // unauthenticated requests can happen
   150  	case codes.ResourceExhausted:
   151  		return logrus.DebugLevel
   152  	case codes.FailedPrecondition:
   153  		return logrus.DebugLevel
   154  	case codes.Aborted:
   155  		return logrus.DebugLevel
   156  	case codes.OutOfRange:
   157  		return logrus.DebugLevel
   158  	case codes.Unimplemented:
   159  		return logrus.WarnLevel
   160  	case codes.Internal:
   161  		return logrus.WarnLevel
   162  	case codes.Unavailable:
   163  		return logrus.WarnLevel
   164  	case codes.DataLoss:
   165  		return logrus.WarnLevel
   166  	default:
   167  		return logrus.InfoLevel
   168  	}
   169  }
   170  
   171  // DefaultDurationToField is the default implementation of converting request duration to a log field (key and value).
   172  var DefaultDurationToField = DurationToTimeMillisField
   173  
   174  // DurationToTimeMillisField converts the duration to milliseconds and uses the key `grpc.time_ms`.
   175  func DurationToTimeMillisField(duration time.Duration) (key string, value interface{}) {
   176  	return "grpc.time_ms", durationToMilliseconds(duration)
   177  }
   178  
   179  // DurationToDurationField uses the duration value to log the request duration.
   180  func DurationToDurationField(duration time.Duration) (key string, value interface{}) {
   181  	return "grpc.duration", duration
   182  }
   183  
   184  func durationToMilliseconds(duration time.Duration) float32 {
   185  	return float32(duration.Nanoseconds()/1000) / 1000
   186  }