...

Source file src/github.com/go-kit/log/level/level.go

Documentation: github.com/go-kit/log/level

     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()      {}
   257  

View as plain text