From 62b915c008602a0c106771ce7652415bdc495cda Mon Sep 17 00:00:00 2001 From: Antoine Grondin Date: Tue, 9 Dec 2014 21:53:14 -0500 Subject: [PATCH 1/2] regression test for issue #88 --- logrus_test.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/logrus_test.go b/logrus_test.go index 15157d1..d3c489d 100644 --- a/logrus_test.go +++ b/logrus_test.go @@ -204,6 +204,38 @@ func TestDefaultFieldsAreNotPrefixed(t *testing.T) { }) } +func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) { + + var buffer bytes.Buffer + var fields Fields + + logger := New() + logger.Out = &buffer + logger.Formatter = new(JSONFormatter) + + llog := logger.WithField("context", "eating raw fish") + + llog.Info("looks delicious") + + err := json.Unmarshal(buffer.Bytes(), &fields) + assert.NoError(t, err, "should have decoded first message") + assert.Len(t, fields, 4, "should only msg/time/level fields") + assert.Equal(t, fields["msg"], "looks delicious") + assert.Equal(t, fields["context"], "eating raw fish") + + buffer.Reset() + + llog.Warn("omg it is!") + + err = json.Unmarshal(buffer.Bytes(), &fields) + assert.NoError(t, err, "should have decoded second message") + assert.Len(t, fields, 4, "should only msg/time/level/context fields") + assert.Equal(t, fields["msg"], "omg it is!") + assert.Equal(t, fields["context"], "eating raw fish") + assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry") + +} + func TestConvertLevelToString(t *testing.T) { assert.Equal(t, "debug", DebugLevel.String()) assert.Equal(t, "info", InfoLevel.String()) From 2835e150d968bd0cd8acaed3a97016342bcb2dea Mon Sep 17 00:00:00 2001 From: Antoine Grondin Date: Tue, 9 Dec 2014 21:53:40 -0500 Subject: [PATCH 2/2] fixes #88 --- formatter.go | 14 +++++++------- json_formatter.go | 14 +++++++++----- logrus_test.go | 4 ++-- text_formatter.go | 2 +- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/formatter.go b/formatter.go index 74c49a0..038ce9f 100644 --- a/formatter.go +++ b/formatter.go @@ -26,19 +26,19 @@ type Formatter interface { // // It's not exported because it's still using Data in an opinionated way. It's to // avoid code duplication between the two default formatters. -func prefixFieldClashes(entry *Entry) { - _, ok := entry.Data["time"] +func prefixFieldClashes(data Fields) { + _, ok := data["time"] if ok { - entry.Data["fields.time"] = entry.Data["time"] + data["fields.time"] = data["time"] } - _, ok = entry.Data["msg"] + _, ok = data["msg"] if ok { - entry.Data["fields.msg"] = entry.Data["msg"] + data["fields.msg"] = data["msg"] } - _, ok = entry.Data["level"] + _, ok = data["level"] if ok { - entry.Data["fields.level"] = entry.Data["level"] + data["fields.level"] = data["level"] } } diff --git a/json_formatter.go b/json_formatter.go index 9d11b64..b09227c 100644 --- a/json_formatter.go +++ b/json_formatter.go @@ -9,12 +9,16 @@ import ( type JSONFormatter struct{} func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { - prefixFieldClashes(entry) - entry.Data["time"] = entry.Time.Format(time.RFC3339) - entry.Data["msg"] = entry.Message - entry.Data["level"] = entry.Level.String() + data := make(Fields, len(entry.Data)+3) + for k, v := range entry.Data { + data[k] = v + } + prefixFieldClashes(data) + data["time"] = entry.Time.Format(time.RFC3339) + data["msg"] = entry.Message + data["level"] = entry.Level.String() - serialized, err := json.Marshal(entry.Data) + serialized, err := json.Marshal(data) if err != nil { return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) } diff --git a/logrus_test.go b/logrus_test.go index d3c489d..348ad53 100644 --- a/logrus_test.go +++ b/logrus_test.go @@ -219,7 +219,7 @@ func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) { err := json.Unmarshal(buffer.Bytes(), &fields) assert.NoError(t, err, "should have decoded first message") - assert.Len(t, fields, 4, "should only msg/time/level fields") + assert.Len(t, fields, 4, "should only have msg/time/level/context fields") assert.Equal(t, fields["msg"], "looks delicious") assert.Equal(t, fields["context"], "eating raw fish") @@ -229,7 +229,7 @@ func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) { err = json.Unmarshal(buffer.Bytes(), &fields) assert.NoError(t, err, "should have decoded second message") - assert.Len(t, fields, 4, "should only msg/time/level/context fields") + assert.Len(t, fields, 4, "should only have msg/time/level/context fields") assert.Equal(t, fields["msg"], "omg it is!") assert.Equal(t, fields["context"], "eating raw fish") assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry") diff --git a/text_formatter.go b/text_formatter.go index fc0a408..e77da11 100644 --- a/text_formatter.go +++ b/text_formatter.go @@ -46,7 +46,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { b := &bytes.Buffer{} - prefixFieldClashes(entry) + prefixFieldClashes(entry.Data) isColored := (f.ForceColors || isTerminal) && !f.DisableColors