From bf1fb70b2b4308a0aed02f31c5f327be46620269 Mon Sep 17 00:00:00 2001 From: Neil Isaac Date: Tue, 21 Nov 2017 22:43:47 -0500 Subject: [PATCH 1/4] Add FieldMap support to TestFormatter --- text_formatter.go | 15 ++++++++++++--- text_formatter_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/text_formatter.go b/text_formatter.go index be412aa..8592825 100644 --- a/text_formatter.go +++ b/text_formatter.go @@ -60,6 +60,15 @@ type TextFormatter struct { // Whether the logger's out is to a terminal isTerminal bool + // FieldMap allows users to customize the names of keys for default fields. + // As an example: + // formatter := &JSONFormatter{ + // FieldMap: FieldMap{ + // FieldKeyTime: "@timestamp", + // FieldKeyLevel: "@level", + // FieldKeyMsg: "@message"}} + FieldMap FieldMap + sync.Once } @@ -109,11 +118,11 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { f.printColored(b, entry, keys, timestampFormat) } else { if !f.DisableTimestamp { - f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat)) + f.appendKeyValue(b, f.FieldMap.resolve(FieldKeyTime), entry.Time.Format(timestampFormat)) } - f.appendKeyValue(b, "level", entry.Level.String()) + f.appendKeyValue(b, f.FieldMap.resolve(FieldKeyLevel), entry.Level.String()) if entry.Message != "" { - f.appendKeyValue(b, "msg", entry.Message) + f.appendKeyValue(b, f.FieldMap.resolve(FieldKeyMsg), entry.Message) } for _, key := range keys { f.appendKeyValue(b, key, entry.Data[key]) diff --git a/text_formatter_test.go b/text_formatter_test.go index d93b931..789d52d 100644 --- a/text_formatter_test.go +++ b/text_formatter_test.go @@ -7,6 +7,8 @@ import ( "strings" "testing" "time" + + "github.com/stretchr/testify/assert" ) func TestFormatting(t *testing.T) { @@ -137,5 +139,32 @@ func TestDisableTimestampWithColoredOutput(t *testing.T) { } } +func TestTextFormatterFieldMap(t *testing.T) { + formatter := &TextFormatter{ + DisableColors: true, + FieldMap: FieldMap{ + FieldKeyMsg: "message", + FieldKeyLevel: "somelevel", + FieldKeyTime: "timeywimey", + }, + } + + entry := &Entry{ + Message: "oh hi", + Level: WarnLevel, + Time: time.Date(1981, time.February, 24, 4, 28, 3, 100, time.UTC), + } + + b, err := formatter.Format(entry) + if err != nil { + t.Fatal("Unable to format entry: ", err) + } + + assert.Equal(t, + `timeywimey="1981-02-24T04:28:03Z" somelevel=warning message="oh hi"`+"\n", + string(b), + "Formatted doesn't respect correct FieldMap") +} + // TODO add tests for sorting etc., this requires a parser for the text // formatter output. From b9eceae8f663facb1b89f517fa03e4ae43a5c517 Mon Sep 17 00:00:00 2001 From: Neil Isaac Date: Tue, 21 Nov 2017 22:56:37 -0500 Subject: [PATCH 2/4] fix example --- text_formatter.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/text_formatter.go b/text_formatter.go index 8592825..aa0694c 100644 --- a/text_formatter.go +++ b/text_formatter.go @@ -62,11 +62,11 @@ type TextFormatter struct { // FieldMap allows users to customize the names of keys for default fields. // As an example: - // formatter := &JSONFormatter{ + // formatter := &TextFormatter{ // FieldMap: FieldMap{ - // FieldKeyTime: "@timestamp", + // FieldKeyTime: "@timestamp", // FieldKeyLevel: "@level", - // FieldKeyMsg: "@message"}} + // FieldKeyMsg: "@message"}} FieldMap FieldMap sync.Once From 5d60369ef3a5c165e66ece9cdebb2d4177729d84 Mon Sep 17 00:00:00 2001 From: Neil Isaac Date: Mon, 18 Jun 2018 21:32:35 -0400 Subject: [PATCH 3/4] Fixed prefixFieldClashes for TextFormatter and added coverage --- formatter.go | 3 +++ text_formatter.go | 8 ++++---- text_formatter_test.go | 14 +++++++++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/formatter.go b/formatter.go index 849dc8b..83c7494 100644 --- a/formatter.go +++ b/formatter.go @@ -34,15 +34,18 @@ func prefixFieldClashes(data Fields, fieldMap FieldMap) { timeKey := fieldMap.resolve(FieldKeyTime) if t, ok := data[timeKey]; ok { data["fields."+timeKey] = t + delete(data, timeKey) } msgKey := fieldMap.resolve(FieldKeyMsg) if m, ok := data[msgKey]; ok { data["fields."+msgKey] = m + delete(data, msgKey) } levelKey := fieldMap.resolve(FieldKeyLevel) if l, ok := data[levelKey]; ok { data["fields."+levelKey] = l + delete(data, levelKey) } } diff --git a/text_formatter.go b/text_formatter.go index 5af4e56..3e55040 100644 --- a/text_formatter.go +++ b/text_formatter.go @@ -51,7 +51,6 @@ type TextFormatter struct { // be desired. DisableSorting bool - // Disables the truncation of the level text to 4 characters. DisableLevelTruncation bool @@ -81,7 +80,8 @@ func (f *TextFormatter) init(entry *Entry) { // Format renders a single log entry func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { - var b *bytes.Buffer + prefixFieldClashes(entry.Data, f.FieldMap) + keys := make([]string, 0, len(entry.Data)) for k := range entry.Data { keys = append(keys, k) @@ -90,14 +90,14 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { if !f.DisableSorting { sort.Strings(keys) } + + var b *bytes.Buffer if entry.Buffer != nil { b = entry.Buffer } else { b = &bytes.Buffer{} } - prefixFieldClashes(entry.Data, emptyFieldMap) - f.Do(func() { f.init(entry) }) isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors diff --git a/text_formatter_test.go b/text_formatter_test.go index 4f21861..7245f94 100644 --- a/text_formatter_test.go +++ b/text_formatter_test.go @@ -191,6 +191,12 @@ func TestTextFormatterFieldMap(t *testing.T) { Message: "oh hi", Level: WarnLevel, Time: time.Date(1981, time.February, 24, 4, 28, 3, 100, time.UTC), + Data: Fields{ + "field1": "f1", + "message": "messagefield", + "somelevel": "levelfield", + "timeywimey": "timeywimeyfield", + }, } b, err := formatter.Format(entry) @@ -199,7 +205,13 @@ func TestTextFormatterFieldMap(t *testing.T) { } assert.Equal(t, - `timeywimey="1981-02-24T04:28:03Z" somelevel=warning message="oh hi"`+"\n", + `timeywimey="1981-02-24T04:28:03Z" `+ + `somelevel=warning `+ + `message="oh hi" `+ + `field1=f1 `+ + `fields.message=messagefield `+ + `fields.somelevel=levelfield `+ + `fields.timeywimey=timeywimeyfield`+"\n", string(b), "Formatted doesn't respect correct FieldMap") } From 6b28c2c7d76fb49e829b83ab6dc2f25327db3189 Mon Sep 17 00:00:00 2001 From: Neil Isaac Date: Mon, 18 Jun 2018 21:39:53 -0400 Subject: [PATCH 4/4] error message --- text_formatter_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text_formatter_test.go b/text_formatter_test.go index 7245f94..921d052 100644 --- a/text_formatter_test.go +++ b/text_formatter_test.go @@ -213,7 +213,7 @@ func TestTextFormatterFieldMap(t *testing.T) { `fields.somelevel=levelfield `+ `fields.timeywimey=timeywimeyfield`+"\n", string(b), - "Formatted doesn't respect correct FieldMap") + "Formatted output doesn't respect FieldMap") } // TODO add tests for sorting etc., this requires a parser for the text