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