mirror of https://github.com/sirupsen/logrus.git
Have prefixFieldClashes respect the JSON FieldMap
Currently, it will fix clashes that don't exist and miss clashes that do exist due to field remapping. Fixes #708
This commit is contained in:
parent
8c0189d9f6
commit
efab7f37b7
17
formatter.go
17
formatter.go
|
@ -30,16 +30,19 @@ type Formatter interface {
|
||||||
//
|
//
|
||||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
// 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.
|
// avoid code duplication between the two default formatters.
|
||||||
func prefixFieldClashes(data Fields) {
|
func prefixFieldClashes(data Fields, fieldMap FieldMap) {
|
||||||
if t, ok := data["time"]; ok {
|
timeKey := fieldMap.resolve(FieldKeyTime)
|
||||||
data["fields.time"] = t
|
if t, ok := data[timeKey]; ok {
|
||||||
|
data["fields."+timeKey] = t
|
||||||
}
|
}
|
||||||
|
|
||||||
if m, ok := data["msg"]; ok {
|
msgKey := fieldMap.resolve(FieldKeyMsg)
|
||||||
data["fields.msg"] = m
|
if m, ok := data[msgKey]; ok {
|
||||||
|
data["fields."+msgKey] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
if l, ok := data["level"]; ok {
|
levelKey := fieldMap.resolve(FieldKeyLevel)
|
||||||
data["fields.level"] = l
|
if l, ok := data[levelKey]; ok {
|
||||||
|
data["fields."+levelKey] = l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
data[k] = v
|
data[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prefixFieldClashes(data)
|
prefixFieldClashes(data, f.FieldMap)
|
||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if timestampFormat == "" {
|
if timestampFormat == "" {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package logrus
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -106,6 +107,60 @@ func TestFieldClashWithLevel(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFieldClashWithRemappedFields(t *testing.T) {
|
||||||
|
formatter := &JSONFormatter{
|
||||||
|
FieldMap: FieldMap{
|
||||||
|
FieldKeyTime: "@timestamp",
|
||||||
|
FieldKeyLevel: "@level",
|
||||||
|
FieldKeyMsg: "@message",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := formatter.Format(WithFields(Fields{
|
||||||
|
"@timestamp": "@timestamp",
|
||||||
|
"@level": "@level",
|
||||||
|
"@message": "@message",
|
||||||
|
"timestamp": "timestamp",
|
||||||
|
"level": "level",
|
||||||
|
"msg": "msg",
|
||||||
|
}))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to format entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(b, &entry)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, field := range []string{"timestamp", "level", "msg"} {
|
||||||
|
if entry[field] != field {
|
||||||
|
t.Errorf("Expected field %v to be untouched; got %v", field, entry[field])
|
||||||
|
}
|
||||||
|
|
||||||
|
remappedKey := fmt.Sprintf("fields.%s", field)
|
||||||
|
if remapped, ok := entry[remappedKey]; ok {
|
||||||
|
t.Errorf("Expected %s to be empty; got %v", remappedKey, remapped)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, field := range []string{"@timestamp", "@level", "@message"} {
|
||||||
|
if entry[field] == field {
|
||||||
|
t.Errorf("Expected field %v to be mapped to an Entry value", field)
|
||||||
|
}
|
||||||
|
|
||||||
|
remappedKey := fmt.Sprintf("fields.%s", field)
|
||||||
|
if remapped, ok := entry[remappedKey]; ok {
|
||||||
|
if remapped != field {
|
||||||
|
t.Errorf("Expected field %v to be copied to %s; got %v", field, remappedKey, remapped)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("Expected field %v to be copied to %s; was absent", field, remappedKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestJSONEntryEndsWithNewline(t *testing.T) {
|
func TestJSONEntryEndsWithNewline(t *testing.T) {
|
||||||
formatter := &JSONFormatter{}
|
formatter := &JSONFormatter{}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
baseTimestamp time.Time
|
baseTimestamp time.Time
|
||||||
|
emptyFieldMap FieldMap
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -82,7 +83,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
b = &bytes.Buffer{}
|
b = &bytes.Buffer{}
|
||||||
}
|
}
|
||||||
|
|
||||||
prefixFieldClashes(entry.Data)
|
prefixFieldClashes(entry.Data, emptyFieldMap)
|
||||||
|
|
||||||
f.Do(func() { f.init(entry) })
|
f.Do(func() { f.init(entry) })
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue