Repository: go-kit/kit
Pull request #962 (2020-02-21 15:58:46)

allow to use specific logrus level in the adaptor


Patch:
diff --git a/log/logrus/logrus_logger.go b/log/logrus/logrus_logger.go
index c8a11d5..a5dc9ca 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
 }


Test patch:
diff --git a/log/logrus/logrus_logger_test.go b/log/logrus/logrus_logger_test.go
index cc656ce..cc68184 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)
+			}
+
+		})
+	}
+}