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 }