diff --git a/log/logrus/logrus_logger.go b/log/logrus/logrus_logger.go index c8a11d569..a5dc9ca47 100644 --- a/log/logrus/logrus_logger.go +++ b/log/logrus/logrus_logger.go @@ -10,18 +10,37 @@ import ( "github.com/sirupsen/logrus" ) -type logrusLogger struct { - logrus.FieldLogger +type Logger struct { + field logrus.FieldLogger + level logrus.Level } +type Option func(*Logger) + var errMissingValue = errors.New("(MISSING)") -// NewLogrusLogger returns a go-kit log.Logger that sends log events to a Logrus logger. -func NewLogrusLogger(logger logrus.FieldLogger) log.Logger { - return &logrusLogger{logger} +// NewLogger returns a Go kit log.Logger that sends log events to a logrus.Logger. +func NewLogger(logger logrus.FieldLogger, options ...Option) log.Logger { + l := &Logger{ + field: logger, + level: logrus.InfoLevel, + } + + for _, optFunc := range options { + optFunc(l) + } + + return l } -func (l logrusLogger) Log(keyvals ...interface{}) error { +// WithLevel configures a logrus logger to log at level for all events. +func WithLevel(level logrus.Level) Option { + return func(c *Logger) { + c.level = level + } +} + +func (l Logger) Log(keyvals ...interface{}) error { fields := logrus.Fields{} for i := 0; i < len(keyvals); i += 2 { if i+1 < len(keyvals) { @@ -30,6 +49,21 @@ func (l logrusLogger) Log(keyvals ...interface{}) error { fields[fmt.Sprint(keyvals[i])] = errMissingValue } } - l.WithFields(fields).Info() + + switch l.level { + case logrus.InfoLevel: + l.field.WithFields(fields).Info() + case logrus.ErrorLevel: + l.field.WithFields(fields).Error() + case logrus.DebugLevel: + l.field.WithFields(fields).Debug() + case logrus.WarnLevel: + l.field.WithFields(fields).Warn() + case logrus.TraceLevel: + l.field.WithFields(fields).Trace() + default: + l.field.WithFields(fields).Print() + } + return nil } diff --git a/log/logrus/logrus_logger_test.go b/log/logrus/logrus_logger_test.go index cc656ce0f..cc6818437 100644 --- a/log/logrus/logrus_logger_test.go +++ b/log/logrus/logrus_logger_test.go @@ -2,6 +2,7 @@ package logrus_test import ( "bytes" + "encoding/json" "errors" "strings" "testing" @@ -16,7 +17,7 @@ func TestLogrusLogger(t *testing.T) { logrusLogger := logrus.New() logrusLogger.Out = buf logrusLogger.Formatter = &logrus.TextFormatter{TimestampFormat: "02-01-2006 15:04:05", FullTimestamp: true} - logger := log.NewLogrusLogger(logrusLogger) + logger := log.NewLogger(logrusLogger) if err := logger.Log("hello", "world"); err != nil { t.Fatal(err) @@ -53,3 +54,66 @@ func TestLogrusLogger(t *testing.T) { type mymap map[int]int func (m mymap) String() string { return "special_behavior" } + +func TestWithLevel(t *testing.T) { + tests := []struct { + name string + level logrus.Level + expectedLevel logrus.Level + }{ + { + name: "Test Debug level", + level: logrus.DebugLevel, + expectedLevel: logrus.DebugLevel, + }, + { + name: "Test Error level", + level: logrus.ErrorLevel, + expectedLevel: logrus.ErrorLevel, + }, + { + name: "Test Warn level", + level: logrus.WarnLevel, + expectedLevel: logrus.WarnLevel, + }, + { + name: "Test Info level", + level: logrus.InfoLevel, + expectedLevel: logrus.InfoLevel, + }, + { + name: "Test Trace level", + level: logrus.TraceLevel, + expectedLevel: logrus.TraceLevel, + }, + { + name: "Test not existing level", + level: 999, + expectedLevel: logrus.InfoLevel, + }, + } + for _, tt := range tests { + buf := &bytes.Buffer{} + logrusLogger := logrus.New() + logrusLogger.Out = buf + logrusLogger.Level = tt.level + logrusLogger.Formatter = &logrus.JSONFormatter{} + logger := log.NewLogger(logrusLogger, log.WithLevel(tt.level)) + + t.Run(tt.name, func(t *testing.T) { + if err := logger.Log(); err != nil { + t.Fatal(err) + } + + l := map[string]interface{}{} + if err := json.Unmarshal(buf.Bytes(), &l); err != nil { + t.Fatal(err) + } + + if v, ok := l["level"].(string); !ok || v != tt.expectedLevel.String() { + t.Fatalf("Logging levels doesn't match. Expected: %s, got: %s", tt.level, v) + } + + }) + } +}