From ff695daa3663a818e6a54032d49328e41acdcce5 Mon Sep 17 00:00:00 2001 From: David Bariod Date: Wed, 26 Dec 2018 17:43:14 +0100 Subject: [PATCH] Implement TextUnmarshaller interface for Level type Since the implementation of the TextMarshaller interface we could not unmarshal previously json marshalled Level value. Fixes #873 --- level_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ logrus.go | 42 ++++++++++++++++++++-------------- logrus_test.go | 13 ----------- 3 files changed, 87 insertions(+), 30 deletions(-) create mode 100644 level_test.go diff --git a/level_test.go b/level_test.go new file mode 100644 index 000000000..78915c4f2 --- /dev/null +++ b/level_test.go @@ -0,0 +1,62 @@ +package logrus_test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" +) + +func TestLevelJsonEncoding(t *testing.T) { + type X struct { + Level logrus.Level + } + + var x X + x.Level = logrus.WarnLevel + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + require.NoError(t, enc.Encode(x)) + dec := json.NewDecoder(&buf) + var y X + require.NoError(t, dec.Decode(&y)) +} + +func TestLevelUnmarshalText(t *testing.T) { + var u logrus.Level + for _, level := range logrus.AllLevels { + t.Run(level.String(), func(t *testing.T) { + require.NoError(t, u.UnmarshalText([]byte(level.String()))) + require.Equal(t, level, u) + }) + } + t.Run("invalid", func(t *testing.T) { + require.Error(t, u.UnmarshalText([]byte("invalid"))) + }) +} + +func TestLevelMarshalText(t *testing.T) { + levelStrings := []string{ + "panic", + "fatal", + "error", + "warning", + "info", + "debug", + "trace", + } + for idx, val := range logrus.AllLevels { + level := val + t.Run(level.String(), func(t *testing.T) { + var cmp logrus.Level + b, err := level.MarshalText() + require.NoError(t, err) + require.Equal(t, levelStrings[idx], string(b)) + err = cmp.UnmarshalText(b) + require.NoError(t, err) + require.Equal(t, level, cmp) + }) + } +} diff --git a/logrus.go b/logrus.go index 4ef451866..c1ca88990 100644 --- a/logrus.go +++ b/logrus.go @@ -14,24 +14,11 @@ type Level uint32 // Convert the Level to a string. E.g. PanicLevel becomes "panic". func (level Level) String() string { - switch level { - case TraceLevel: - return "trace" - case DebugLevel: - return "debug" - case InfoLevel: - return "info" - case WarnLevel: - return "warning" - case ErrorLevel: - return "error" - case FatalLevel: - return "fatal" - case PanicLevel: - return "panic" + if b, err := level.MarshalText(); err == nil { + return string(b) + } else { + return "unknown" } - - return "unknown" } // ParseLevel takes a string level and returns the Logrus log level constant. @@ -69,6 +56,27 @@ func (level *Level) UnmarshalText(text []byte) error { return nil } +func (level Level) MarshalText() ([]byte, error) { + switch level { + case TraceLevel: + return []byte("trace"), nil + case DebugLevel: + return []byte("debug"), nil + case InfoLevel: + return []byte("info"), nil + case WarnLevel: + return []byte("warning"), nil + case ErrorLevel: + return []byte("error"), nil + case FatalLevel: + return []byte("fatal"), nil + case PanicLevel: + return []byte("panic"), nil + } + + return nil, fmt.Errorf("not a valid lorus level %q", level) +} + // A constant exposing all logging levels var AllLevels = []Level{ PanicLevel, diff --git a/logrus_test.go b/logrus_test.go index b12d71c8c..5c740fded 100644 --- a/logrus_test.go +++ b/logrus_test.go @@ -508,19 +508,6 @@ func TestParseLevel(t *testing.T) { assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error()) } -func TestUnmarshalText(t *testing.T) { - var u Level - for _, level := range AllLevels { - t.Run(level.String(), func(t *testing.T) { - assert.NoError(t, u.UnmarshalText([]byte(level.String()))) - assert.Equal(t, level, u) - }) - } - t.Run("invalid", func(t *testing.T) { - assert.Error(t, u.UnmarshalText([]byte("invalid"))) - }) -} - func TestGetSetLevelRace(t *testing.T) { wg := sync.WaitGroup{} for i := 0; i < 100; i++ {