fix: avoid duplicate in logx plain mode (#4080)

This commit is contained in:
Kevin Wan
2024-04-17 17:43:22 +08:00
committed by GitHub
parent 164f5aa86c
commit 36088ea0d4
2 changed files with 46 additions and 10 deletions

View File

@@ -254,11 +254,10 @@ func (n nopWriter) Stack(_ any) {
func (n nopWriter) Stat(_ any, _ ...LogField) {
}
func buildPlainFields(fields ...LogField) []string {
var items []string
for _, field := range fields {
items = append(items, fmt.Sprintf("%s=%+v", field.Key, field.Value))
func buildPlainFields(fields logEntry) []string {
items := make([]string, 0, len(fields))
for k, v := range fields {
items = append(items, fmt.Sprintf("%s=%+v", k, v))
}
return items
@@ -289,15 +288,17 @@ func output(writer io.Writer, level string, val any, fields ...LogField) {
}
fields = combineGlobalFields(fields)
// +3 for timestamp, level and content
entry := make(logEntry, len(fields)+3)
for _, field := range fields {
entry[field.Key] = field.Value
}
switch atomic.LoadUint32(&encoding) {
case plainEncodingType:
writePlainAny(writer, level, val, buildPlainFields(fields...)...)
plainFields := buildPlainFields(entry)
writePlainAny(writer, level, val, plainFields...)
default:
entry := make(logEntry)
for _, field := range fields {
entry[field.Key] = field.Value
}
entry[timestampKey] = getTimestamp()
entry[levelKey] = level
entry[contentKey] = val

View File

@@ -189,6 +189,41 @@ func TestWritePlainAny(t *testing.T) {
assert.Contains(t, buf.String(), "runtime/debug.Stack")
}
func TestWritePlainDuplicate(t *testing.T) {
old := atomic.SwapUint32(&encoding, plainEncodingType)
t.Cleanup(func() {
atomic.StoreUint32(&encoding, old)
})
var buf bytes.Buffer
output(&buf, levelInfo, "foo", LogField{
Key: "first",
Value: "a",
}, LogField{
Key: "first",
Value: "b",
})
assert.Contains(t, buf.String(), "foo")
assert.NotContains(t, buf.String(), "first=a")
assert.Contains(t, buf.String(), "first=b")
buf.Reset()
output(&buf, levelInfo, "foo", LogField{
Key: "first",
Value: "a",
}, LogField{
Key: "first",
Value: "b",
}, LogField{
Key: "second",
Value: "c",
})
assert.Contains(t, buf.String(), "foo")
assert.NotContains(t, buf.String(), "first=a")
assert.Contains(t, buf.String(), "first=b")
assert.Contains(t, buf.String(), "second=c")
}
func TestLogWithLimitContentLength(t *testing.T) {
maxLen := atomic.LoadUint32(&maxContentLength)
atomic.StoreUint32(&maxContentLength, 10)