From 2cafb78db2ffe7e4592a07991f77f9105db898ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C7=8Ei-Li=C3=A0ng=20=22Hal=22=20W=C3=A1ng?= Date: Mon, 5 Nov 2018 12:29:28 +0000 Subject: [PATCH] fix race condition caused by writing to entry.Data, using the same technique as JSONFormatter --- text_formatter.go | 21 ++++++++++++--------- text_formatter_test.go | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/text_formatter.go b/text_formatter.go index 49ec92f..4342d73 100644 --- a/text_formatter.go +++ b/text_formatter.go @@ -107,14 +107,17 @@ func (f *TextFormatter) isColored() bool { // Format renders a single log entry func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { - prefixFieldClashes(entry.Data, f.FieldMap, entry.HasCaller()) - - keys := make([]string, 0, len(entry.Data)) - for k := range entry.Data { + data := make(Fields) + for k, v := range entry.Data { + data[k] = v + } + prefixFieldClashes(data, f.FieldMap, entry.HasCaller()) + keys := make([]string, 0, len(data)) + for k := range data { keys = append(keys, k) } - fixedKeys := make([]string, 0, 4+len(entry.Data)) + fixedKeys := make([]string, 0, 4+len(data)) if !f.DisableTimestamp { fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime)) } @@ -160,7 +163,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { timestampFormat = defaultTimestampFormat } if f.isColored() { - f.printColored(b, entry, keys, timestampFormat) + f.printColored(b, entry, keys, nil, timestampFormat) } else { for _, key := range fixedKeys { var value interface{} @@ -178,7 +181,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller(): value = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) default: - value = entry.Data[key] + value = data[key] } f.appendKeyValue(b, key, value) } @@ -188,7 +191,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { return b.Bytes(), nil } -func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) { +func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) { var levelColor int switch entry.Level { case DebugLevel, TraceLevel: @@ -225,7 +228,7 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message) } for _, k := range keys { - v := entry.Data[k] + v := data[k] fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) f.appendValue(b, v) } diff --git a/text_formatter_test.go b/text_formatter_test.go index b0d3a91..e07809d 100644 --- a/text_formatter_test.go +++ b/text_formatter_test.go @@ -144,7 +144,7 @@ func TestDisableLevelTruncation(t *testing.T) { tf := &TextFormatter{DisableLevelTruncation: disabled} var b bytes.Buffer entry.Level = level - tf.printColored(&b, entry, keys, timestampFormat) + tf.printColored(&b, entry, keys, nil, timestampFormat) logLine := (&b).String() if disabled { expected := strings.ToUpper(level.String())