2
0

level.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. package level
  2. import "github.com/go-kit/kit/log"
  3. // Error returns a logger that includes a Key/ErrorValue pair.
  4. func Error(logger log.Logger) log.Logger {
  5. return log.WithPrefix(logger, Key(), ErrorValue())
  6. }
  7. // Warn returns a logger that includes a Key/WarnValue pair.
  8. func Warn(logger log.Logger) log.Logger {
  9. return log.WithPrefix(logger, Key(), WarnValue())
  10. }
  11. // Info returns a logger that includes a Key/InfoValue pair.
  12. func Info(logger log.Logger) log.Logger {
  13. return log.WithPrefix(logger, Key(), InfoValue())
  14. }
  15. // Debug returns a logger that includes a Key/DebugValue pair.
  16. func Debug(logger log.Logger) log.Logger {
  17. return log.WithPrefix(logger, Key(), DebugValue())
  18. }
  19. // NewFilter wraps next and implements level filtering. See the commentary on
  20. // the Option functions for a detailed description of how to configure levels.
  21. // If no options are provided, all leveled log events created with Debug,
  22. // Info, Warn or Error helper methods are squelched and non-leveled log
  23. // events are passed to next unmodified.
  24. func NewFilter(next log.Logger, options ...Option) log.Logger {
  25. l := &logger{
  26. next: next,
  27. }
  28. for _, option := range options {
  29. option(l)
  30. }
  31. return l
  32. }
  33. type logger struct {
  34. next log.Logger
  35. allowed level
  36. squelchNoLevel bool
  37. errNotAllowed error
  38. errNoLevel error
  39. }
  40. func (l *logger) Log(keyvals ...interface{}) error {
  41. var hasLevel, levelAllowed bool
  42. for i := 1; i < len(keyvals); i += 2 {
  43. if v, ok := keyvals[i].(*levelValue); ok {
  44. hasLevel = true
  45. levelAllowed = l.allowed&v.level != 0
  46. break
  47. }
  48. }
  49. if !hasLevel && l.squelchNoLevel {
  50. return l.errNoLevel
  51. }
  52. if hasLevel && !levelAllowed {
  53. return l.errNotAllowed
  54. }
  55. return l.next.Log(keyvals...)
  56. }
  57. // Option sets a parameter for the leveled logger.
  58. type Option func(*logger)
  59. // AllowAll is an alias for AllowDebug.
  60. func AllowAll() Option {
  61. return AllowDebug()
  62. }
  63. // AllowDebug allows error, warn, info and debug level log events to pass.
  64. func AllowDebug() Option {
  65. return allowed(levelError | levelWarn | levelInfo | levelDebug)
  66. }
  67. // AllowInfo allows error, warn and info level log events to pass.
  68. func AllowInfo() Option {
  69. return allowed(levelError | levelWarn | levelInfo)
  70. }
  71. // AllowWarn allows error and warn level log events to pass.
  72. func AllowWarn() Option {
  73. return allowed(levelError | levelWarn)
  74. }
  75. // AllowError allows only error level log events to pass.
  76. func AllowError() Option {
  77. return allowed(levelError)
  78. }
  79. // AllowNone allows no leveled log events to pass.
  80. func AllowNone() Option {
  81. return allowed(0)
  82. }
  83. func allowed(allowed level) Option {
  84. return func(l *logger) { l.allowed = allowed }
  85. }
  86. // ErrNotAllowed sets the error to return from Log when it squelches a log
  87. // event disallowed by the configured Allow[Level] option. By default,
  88. // ErrNotAllowed is nil; in this case the log event is squelched with no
  89. // error.
  90. func ErrNotAllowed(err error) Option {
  91. return func(l *logger) { l.errNotAllowed = err }
  92. }
  93. // SquelchNoLevel instructs Log to squelch log events with no level, so that
  94. // they don't proceed through to the wrapped logger. If SquelchNoLevel is set
  95. // to true and a log event is squelched in this way, the error value
  96. // configured with ErrNoLevel is returned to the caller.
  97. func SquelchNoLevel(squelch bool) Option {
  98. return func(l *logger) { l.squelchNoLevel = squelch }
  99. }
  100. // ErrNoLevel sets the error to return from Log when it squelches a log event
  101. // with no level. By default, ErrNoLevel is nil; in this case the log event is
  102. // squelched with no error.
  103. func ErrNoLevel(err error) Option {
  104. return func(l *logger) { l.errNoLevel = err }
  105. }
  106. // NewInjector wraps next and returns a logger that adds a Key/level pair to
  107. // the beginning of log events that don't already contain a level. In effect,
  108. // this gives a default level to logs without a level.
  109. func NewInjector(next log.Logger, level Value) log.Logger {
  110. return &injector{
  111. next: next,
  112. level: level,
  113. }
  114. }
  115. type injector struct {
  116. next log.Logger
  117. level interface{}
  118. }
  119. func (l *injector) Log(keyvals ...interface{}) error {
  120. for i := 1; i < len(keyvals); i += 2 {
  121. if _, ok := keyvals[i].(*levelValue); ok {
  122. return l.next.Log(keyvals...)
  123. }
  124. }
  125. kvs := make([]interface{}, len(keyvals)+2)
  126. kvs[0], kvs[1] = key, l.level
  127. copy(kvs[2:], keyvals)
  128. return l.next.Log(kvs...)
  129. }
  130. // Value is the interface that each of the canonical level values implement.
  131. // It contains unexported methods that prevent types from other packages from
  132. // implementing it and guaranteeing that NewFilter can distinguish the levels
  133. // defined in this package from all other values.
  134. type Value interface {
  135. String() string
  136. levelVal()
  137. }
  138. // Key returns the unique key added to log events by the loggers in this
  139. // package.
  140. func Key() interface{} { return key }
  141. // ErrorValue returns the unique value added to log events by Error.
  142. func ErrorValue() Value { return errorValue }
  143. // WarnValue returns the unique value added to log events by Warn.
  144. func WarnValue() Value { return warnValue }
  145. // InfoValue returns the unique value added to log events by Info.
  146. func InfoValue() Value { return infoValue }
  147. // DebugValue returns the unique value added to log events by Warn.
  148. func DebugValue() Value { return debugValue }
  149. var (
  150. // key is of type interface{} so that it allocates once during package
  151. // initialization and avoids allocating every time the value is added to a
  152. // []interface{} later.
  153. key interface{} = "level"
  154. errorValue = &levelValue{level: levelError, name: "error"}
  155. warnValue = &levelValue{level: levelWarn, name: "warn"}
  156. infoValue = &levelValue{level: levelInfo, name: "info"}
  157. debugValue = &levelValue{level: levelDebug, name: "debug"}
  158. )
  159. type level byte
  160. const (
  161. levelDebug level = 1 << iota
  162. levelInfo
  163. levelWarn
  164. levelError
  165. )
  166. type levelValue struct {
  167. name string
  168. level
  169. }
  170. func (v *levelValue) String() string { return v.name }
  171. func (v *levelValue) levelVal() {}