|
| 1 | +package levels |
| 2 | + |
| 3 | +import "github.com/go-kit/kit/log" |
| 4 | + |
| 5 | +// Levels provides a leveled logging wrapper around a logger. It has five |
| 6 | +// levels: debug, info, warning (warn), error, and critical (crit). If you |
| 7 | +// want a different set of levels, you can create your own levels type very |
| 8 | +// easily, and you can elide the configuration. |
| 9 | +type Levels struct { |
| 10 | + ctx log.Context |
| 11 | + levelKey string |
| 12 | + |
| 13 | + // We have a choice between storing level values in string fields or |
| 14 | + // making a separate context for each level. When using string fields the |
| 15 | + // Log method must combine the base context, the level data, and the |
| 16 | + // logged keyvals; but the With method only requires updating one context. |
| 17 | + // If we instead keep a separate context for each level the Log method |
| 18 | + // must only append the new keyvals; but the With method would have to |
| 19 | + // update all five contexts. |
| 20 | + |
| 21 | + // Roughly speaking, storing multiple contexts breaks even if the ratio of |
| 22 | + // Log/With calls is more than the number of levels. We have chosen to |
| 23 | + // make the With method cheap and the Log method a bit more costly because |
| 24 | + // we do not expect most applications to Log more than five times for each |
| 25 | + // call to With. |
| 26 | + |
| 27 | + debugValue string |
| 28 | + infoValue string |
| 29 | + warnValue string |
| 30 | + errorValue string |
| 31 | + critValue string |
| 32 | +} |
| 33 | + |
| 34 | +// New creates a new leveled logger, wrapping the passed logger. |
| 35 | +func New(logger log.Logger, options ...Option) Levels { |
| 36 | + l := Levels{ |
| 37 | + ctx: log.NewContext(logger), |
| 38 | + levelKey: "level", |
| 39 | + |
| 40 | + debugValue: "debug", |
| 41 | + infoValue: "info", |
| 42 | + warnValue: "warn", |
| 43 | + errorValue: "error", |
| 44 | + critValue: "crit", |
| 45 | + } |
| 46 | + for _, option := range options { |
| 47 | + option(&l) |
| 48 | + } |
| 49 | + return l |
| 50 | +} |
| 51 | + |
| 52 | +// With returns a new leveled logger that includes keyvals in all log events. |
| 53 | +func (l Levels) With(keyvals ...interface{}) Levels { |
| 54 | + return Levels{ |
| 55 | + ctx: l.ctx.With(keyvals...), |
| 56 | + levelKey: l.levelKey, |
| 57 | + debugValue: l.debugValue, |
| 58 | + infoValue: l.infoValue, |
| 59 | + warnValue: l.warnValue, |
| 60 | + errorValue: l.errorValue, |
| 61 | + critValue: l.critValue, |
| 62 | + } |
| 63 | +} |
| 64 | + |
| 65 | +// Debug logs a debug event along with keyvals. |
| 66 | +func (l Levels) Debug(keyvals ...interface{}) error { |
| 67 | + return l.ctx.WithPrefix(l.levelKey, l.debugValue).Log(keyvals...) |
| 68 | +} |
| 69 | + |
| 70 | +// Info logs an info event along with keyvals. |
| 71 | +func (l Levels) Info(keyvals ...interface{}) error { |
| 72 | + return l.ctx.WithPrefix(l.levelKey, l.infoValue).Log(keyvals...) |
| 73 | +} |
| 74 | + |
| 75 | +// Warn logs a warn event along with keyvals. |
| 76 | +func (l Levels) Warn(keyvals ...interface{}) error { |
| 77 | + return l.ctx.WithPrefix(l.levelKey, l.warnValue).Log(keyvals...) |
| 78 | +} |
| 79 | + |
| 80 | +// Error logs an error event along with keyvals. |
| 81 | +func (l Levels) Error(keyvals ...interface{}) error { |
| 82 | + return l.ctx.WithPrefix(l.levelKey, l.errorValue).Log(keyvals...) |
| 83 | +} |
| 84 | + |
| 85 | +// Crit logs a crit event along with keyvals. |
| 86 | +func (l Levels) Crit(keyvals ...interface{}) error { |
| 87 | + return l.ctx.WithPrefix(l.levelKey, l.critValue).Log(keyvals...) |
| 88 | +} |
| 89 | + |
| 90 | +// Option sets a parameter for leveled loggers. |
| 91 | +type Option func(*Levels) |
| 92 | + |
| 93 | +// Key sets the key for the field used to indicate log level. By default, |
| 94 | +// the key is "level". |
| 95 | +func Key(key string) Option { |
| 96 | + return func(l *Levels) { l.levelKey = key } |
| 97 | +} |
| 98 | + |
| 99 | +// DebugValue sets the value for the field used to indicate the debug log |
| 100 | +// level. By default, the value is "debug". |
| 101 | +func DebugValue(value string) Option { |
| 102 | + return func(l *Levels) { l.debugValue = value } |
| 103 | +} |
| 104 | + |
| 105 | +// InfoValue sets the value for the field used to indicate the info log level. |
| 106 | +// By default, the value is "info". |
| 107 | +func InfoValue(value string) Option { |
| 108 | + return func(l *Levels) { l.infoValue = value } |
| 109 | +} |
| 110 | + |
| 111 | +// WarnValue sets the value for the field used to indicate the warning log |
| 112 | +// level. By default, the value is "warn". |
| 113 | +func WarnValue(value string) Option { |
| 114 | + return func(l *Levels) { l.warnValue = value } |
| 115 | +} |
| 116 | + |
| 117 | +// ErrorValue sets the value for the field used to indicate the error log |
| 118 | +// level. By default, the value is "error". |
| 119 | +func ErrorValue(value string) Option { |
| 120 | + return func(l *Levels) { l.errorValue = value } |
| 121 | +} |
| 122 | + |
| 123 | +// CritValue sets the value for the field used to indicate the critical log |
| 124 | +// level. By default, the value is "crit". |
| 125 | +func CritValue(value string) Option { |
| 126 | + return func(l *Levels) { l.critValue = value } |
| 127 | +} |
0 commit comments