github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/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  	grpc_logging "github.com/hxx258456/ccgo/go-grpc-middleware/logging"
    10  	"github.com/hxx258456/ccgo/grpc/codes"
    11  	"github.com/sirupsen/logrus"
    12  )
    13  
    14  var (
    15  	defaultOptions = &options{
    16  		levelFunc:    nil,
    17  		shouldLog:    grpc_logging.DefaultDeciderMethod,
    18  		codeFunc:     grpc_logging.DefaultErrorToCode,
    19  		durationFunc: DefaultDurationToField,
    20  	}
    21  )
    22  
    23  type options struct {
    24  	levelFunc    CodeToLevel
    25  	shouldLog    grpc_logging.Decider
    26  	codeFunc     grpc_logging.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 grpc_logging.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  func WithCodes(f grpc_logging.ErrorToCode) Option {
    74  	return func(o *options) {
    75  		o.codeFunc = f
    76  	}
    77  }
    78  
    79  // WithDurationField customizes the function for mapping request durations to log fields.
    80  func WithDurationField(f DurationToField) Option {
    81  	return func(o *options) {
    82  		o.durationFunc = f
    83  	}
    84  }
    85  
    86  // DefaultCodeToLevel is the default implementation of gRPC return codes to log levels for server side.
    87  func DefaultCodeToLevel(code codes.Code) logrus.Level {
    88  	switch code {
    89  	case codes.OK:
    90  		return logrus.InfoLevel
    91  	case codes.Canceled:
    92  		return logrus.InfoLevel
    93  	case codes.Unknown:
    94  		return logrus.ErrorLevel
    95  	case codes.InvalidArgument:
    96  		return logrus.InfoLevel
    97  	case codes.DeadlineExceeded:
    98  		return logrus.WarnLevel
    99  	case codes.NotFound:
   100  		return logrus.InfoLevel
   101  	case codes.AlreadyExists:
   102  		return logrus.InfoLevel
   103  	case codes.PermissionDenied:
   104  		return logrus.WarnLevel
   105  	case codes.Unauthenticated:
   106  		return logrus.InfoLevel // unauthenticated requests can happen
   107  	case codes.ResourceExhausted:
   108  		return logrus.WarnLevel
   109  	case codes.FailedPrecondition:
   110  		return logrus.WarnLevel
   111  	case codes.Aborted:
   112  		return logrus.WarnLevel
   113  	case codes.OutOfRange:
   114  		return logrus.WarnLevel
   115  	case codes.Unimplemented:
   116  		return logrus.ErrorLevel
   117  	case codes.Internal:
   118  		return logrus.ErrorLevel
   119  	case codes.Unavailable:
   120  		return logrus.WarnLevel
   121  	case codes.DataLoss:
   122  		return logrus.ErrorLevel
   123  	default:
   124  		return logrus.ErrorLevel
   125  	}
   126  }
   127  
   128  // DefaultClientCodeToLevel is the default implementation of gRPC return codes to log levels for client side.
   129  func DefaultClientCodeToLevel(code codes.Code) logrus.Level {
   130  	switch code {
   131  	case codes.OK:
   132  		return logrus.DebugLevel
   133  	case codes.Canceled:
   134  		return logrus.DebugLevel
   135  	case codes.Unknown:
   136  		return logrus.InfoLevel
   137  	case codes.InvalidArgument:
   138  		return logrus.DebugLevel
   139  	case codes.DeadlineExceeded:
   140  		return logrus.InfoLevel
   141  	case codes.NotFound:
   142  		return logrus.DebugLevel
   143  	case codes.AlreadyExists:
   144  		return logrus.DebugLevel
   145  	case codes.PermissionDenied:
   146  		return logrus.InfoLevel
   147  	case codes.Unauthenticated:
   148  		return logrus.InfoLevel // unauthenticated requests can happen
   149  	case codes.ResourceExhausted:
   150  		return logrus.DebugLevel
   151  	case codes.FailedPrecondition:
   152  		return logrus.DebugLevel
   153  	case codes.Aborted:
   154  		return logrus.DebugLevel
   155  	case codes.OutOfRange:
   156  		return logrus.DebugLevel
   157  	case codes.Unimplemented:
   158  		return logrus.WarnLevel
   159  	case codes.Internal:
   160  		return logrus.WarnLevel
   161  	case codes.Unavailable:
   162  		return logrus.WarnLevel
   163  	case codes.DataLoss:
   164  		return logrus.WarnLevel
   165  	default:
   166  		return logrus.InfoLevel
   167  	}
   168  }
   169  
   170  // DefaultDurationToField is the default implementation of converting request duration to a log field (key and value).
   171  var DefaultDurationToField = DurationToTimeMillisField
   172  
   173  // DurationToTimeMillisField converts the duration to milliseconds and uses the key `grpc.time_ms`.
   174  func DurationToTimeMillisField(duration time.Duration) (key string, value interface{}) {
   175  	return "grpc.time_ms", durationToMilliseconds(duration)
   176  }
   177  
   178  // DurationToDurationField uses the duration value to log the request duration.
   179  func DurationToDurationField(duration time.Duration) (key string, value interface{}) {
   180  	return "grpc.duration", duration
   181  }
   182  
   183  func durationToMilliseconds(duration time.Duration) float32 {
   184  	return float32(duration.Nanoseconds()/1000) / 1000
   185  }