github.com/go-kit/log@v0.2.1/level/level.go (about) 1 package level 2 3 import ( 4 "errors" 5 "strings" 6 7 "github.com/go-kit/log" 8 ) 9 10 // ErrInvalidLevelString is returned whenever an invalid string is passed to Parse. 11 var ErrInvalidLevelString = errors.New("invalid level string") 12 13 // Error returns a logger that includes a Key/ErrorValue pair. 14 func Error(logger log.Logger) log.Logger { 15 return log.WithPrefix(logger, Key(), ErrorValue()) 16 } 17 18 // Warn returns a logger that includes a Key/WarnValue pair. 19 func Warn(logger log.Logger) log.Logger { 20 return log.WithPrefix(logger, Key(), WarnValue()) 21 } 22 23 // Info returns a logger that includes a Key/InfoValue pair. 24 func Info(logger log.Logger) log.Logger { 25 return log.WithPrefix(logger, Key(), InfoValue()) 26 } 27 28 // Debug returns a logger that includes a Key/DebugValue pair. 29 func Debug(logger log.Logger) log.Logger { 30 return log.WithPrefix(logger, Key(), DebugValue()) 31 } 32 33 // NewFilter wraps next and implements level filtering. See the commentary on 34 // the Option functions for a detailed description of how to configure levels. 35 // If no options are provided, all leveled log events created with Debug, 36 // Info, Warn or Error helper methods are squelched and non-leveled log 37 // events are passed to next unmodified. 38 func NewFilter(next log.Logger, options ...Option) log.Logger { 39 l := &logger{ 40 next: next, 41 } 42 for _, option := range options { 43 option(l) 44 } 45 return l 46 } 47 48 type logger struct { 49 next log.Logger 50 allowed level 51 squelchNoLevel bool 52 errNotAllowed error 53 errNoLevel error 54 } 55 56 func (l *logger) Log(keyvals ...interface{}) error { 57 var hasLevel, levelAllowed bool 58 for i := 1; i < len(keyvals); i += 2 { 59 if v, ok := keyvals[i].(*levelValue); ok { 60 hasLevel = true 61 levelAllowed = l.allowed&v.level != 0 62 break 63 } 64 } 65 if !hasLevel && l.squelchNoLevel { 66 return l.errNoLevel 67 } 68 if hasLevel && !levelAllowed { 69 return l.errNotAllowed 70 } 71 return l.next.Log(keyvals...) 72 } 73 74 // Option sets a parameter for the leveled logger. 75 type Option func(*logger) 76 77 // Allow the provided log level to pass. 78 func Allow(v Value) Option { 79 switch v { 80 case debugValue: 81 return AllowDebug() 82 case infoValue: 83 return AllowInfo() 84 case warnValue: 85 return AllowWarn() 86 case errorValue: 87 return AllowError() 88 default: 89 return AllowNone() 90 } 91 } 92 93 // AllowAll is an alias for AllowDebug. 94 func AllowAll() Option { 95 return AllowDebug() 96 } 97 98 // AllowDebug allows error, warn, info and debug level log events to pass. 99 func AllowDebug() Option { 100 return allowed(levelError | levelWarn | levelInfo | levelDebug) 101 } 102 103 // AllowInfo allows error, warn and info level log events to pass. 104 func AllowInfo() Option { 105 return allowed(levelError | levelWarn | levelInfo) 106 } 107 108 // AllowWarn allows error and warn level log events to pass. 109 func AllowWarn() Option { 110 return allowed(levelError | levelWarn) 111 } 112 113 // AllowError allows only error level log events to pass. 114 func AllowError() Option { 115 return allowed(levelError) 116 } 117 118 // AllowNone allows no leveled log events to pass. 119 func AllowNone() Option { 120 return allowed(0) 121 } 122 123 func allowed(allowed level) Option { 124 return func(l *logger) { l.allowed = allowed } 125 } 126 127 // Parse a string to its corresponding level value. Valid strings are "debug", 128 // "info", "warn", and "error". Strings are normalized via strings.TrimSpace and 129 // strings.ToLower. 130 func Parse(level string) (Value, error) { 131 switch strings.TrimSpace(strings.ToLower(level)) { 132 case debugValue.name: 133 return debugValue, nil 134 case infoValue.name: 135 return infoValue, nil 136 case warnValue.name: 137 return warnValue, nil 138 case errorValue.name: 139 return errorValue, nil 140 default: 141 return nil, ErrInvalidLevelString 142 } 143 } 144 145 // ParseDefault calls Parse and returns the default Value on error. 146 func ParseDefault(level string, def Value) Value { 147 v, err := Parse(level) 148 if err != nil { 149 return def 150 } 151 return v 152 } 153 154 // ErrNotAllowed sets the error to return from Log when it squelches a log 155 // event disallowed by the configured Allow[Level] option. By default, 156 // ErrNotAllowed is nil; in this case the log event is squelched with no 157 // error. 158 func ErrNotAllowed(err error) Option { 159 return func(l *logger) { l.errNotAllowed = err } 160 } 161 162 // SquelchNoLevel instructs Log to squelch log events with no level, so that 163 // they don't proceed through to the wrapped logger. If SquelchNoLevel is set 164 // to true and a log event is squelched in this way, the error value 165 // configured with ErrNoLevel is returned to the caller. 166 func SquelchNoLevel(squelch bool) Option { 167 return func(l *logger) { l.squelchNoLevel = squelch } 168 } 169 170 // ErrNoLevel sets the error to return from Log when it squelches a log event 171 // with no level. By default, ErrNoLevel is nil; in this case the log event is 172 // squelched with no error. 173 func ErrNoLevel(err error) Option { 174 return func(l *logger) { l.errNoLevel = err } 175 } 176 177 // NewInjector wraps next and returns a logger that adds a Key/level pair to 178 // the beginning of log events that don't already contain a level. In effect, 179 // this gives a default level to logs without a level. 180 func NewInjector(next log.Logger, level Value) log.Logger { 181 return &injector{ 182 next: next, 183 level: level, 184 } 185 } 186 187 type injector struct { 188 next log.Logger 189 level interface{} 190 } 191 192 func (l *injector) Log(keyvals ...interface{}) error { 193 for i := 1; i < len(keyvals); i += 2 { 194 if _, ok := keyvals[i].(*levelValue); ok { 195 return l.next.Log(keyvals...) 196 } 197 } 198 kvs := make([]interface{}, len(keyvals)+2) 199 kvs[0], kvs[1] = key, l.level 200 copy(kvs[2:], keyvals) 201 return l.next.Log(kvs...) 202 } 203 204 // Value is the interface that each of the canonical level values implement. 205 // It contains unexported methods that prevent types from other packages from 206 // implementing it and guaranteeing that NewFilter can distinguish the levels 207 // defined in this package from all other values. 208 type Value interface { 209 String() string 210 levelVal() 211 } 212 213 // Key returns the unique key added to log events by the loggers in this 214 // package. 215 func Key() interface{} { return key } 216 217 // ErrorValue returns the unique value added to log events by Error. 218 func ErrorValue() Value { return errorValue } 219 220 // WarnValue returns the unique value added to log events by Warn. 221 func WarnValue() Value { return warnValue } 222 223 // InfoValue returns the unique value added to log events by Info. 224 func InfoValue() Value { return infoValue } 225 226 // DebugValue returns the unique value added to log events by Debug. 227 func DebugValue() Value { return debugValue } 228 229 var ( 230 // key is of type interface{} so that it allocates once during package 231 // initialization and avoids allocating every time the value is added to a 232 // []interface{} later. 233 key interface{} = "level" 234 235 errorValue = &levelValue{level: levelError, name: "error"} 236 warnValue = &levelValue{level: levelWarn, name: "warn"} 237 infoValue = &levelValue{level: levelInfo, name: "info"} 238 debugValue = &levelValue{level: levelDebug, name: "debug"} 239 ) 240 241 type level byte 242 243 const ( 244 levelDebug level = 1 << iota 245 levelInfo 246 levelWarn 247 levelError 248 ) 249 250 type levelValue struct { 251 name string 252 level 253 } 254 255 func (v *levelValue) String() string { return v.name } 256 func (v *levelValue) levelVal() {}