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 }