Skip to content

Commit

Permalink
Add fields order (#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
madkins23 authored May 4, 2024
1 parent 8582bed commit c78e50e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
38 changes: 37 additions & 1 deletion console.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ type ConsoleWriter struct {
// PartsExclude defines parts to not display in output.
PartsExclude []string

// FieldsOrder defines the order of contextual fields in output.
FieldsOrder []string

fieldIsOrdered map[string]int

// FieldsExclude defines contextual fields to not display in output.
FieldsExclude []string

Expand Down Expand Up @@ -191,7 +196,12 @@ func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer
}
fields = append(fields, field)
}
sort.Strings(fields)

if len(w.FieldsOrder) > 0 {
w.orderFields(fields)
} else {
sort.Strings(fields)
}

// Write space only if something has already been written to the buffer, and if there are fields.
if buf.Len() > 0 && len(fields) > 0 {
Expand Down Expand Up @@ -324,6 +334,32 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{},
}
}

// orderFields takes an array of field names and an array representing field order
// and returns an array with any ordered fields at the beginning, in order,
// and the remaining fields after in their original order.
func (w ConsoleWriter) orderFields(fields []string) {
if w.fieldIsOrdered == nil {
w.fieldIsOrdered = make(map[string]int)
for i, fieldName := range w.FieldsOrder {
w.fieldIsOrdered[fieldName] = i
}
}
sort.Slice(fields, func(i, j int) bool {
ii, iOrdered := w.fieldIsOrdered[fields[i]]
jj, jOrdered := w.fieldIsOrdered[fields[j]]
if iOrdered && jOrdered {
return ii < jj
}
if iOrdered {
return true
}
if jOrdered {
return false
}
return fields[i] < fields[j]
})
}

// needsQuote returns true when the string s should be quoted in output.
func needsQuote(s string) bool {
for i := range s {
Expand Down
17 changes: 17 additions & 0 deletions console_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,23 @@ func TestConsoleWriterConfiguration(t *testing.T) {
}
})

t.Run("Sets FieldsOrder", func(t *testing.T) {
buf := &bytes.Buffer{}
w := zerolog.ConsoleWriter{Out: buf, NoColor: true, FieldsOrder: []string{"zebra", "aardvark"}}

evt := `{"level": "info", "message": "Zoo", "aardvark": "Able", "mussel": "Mountain", "zebra": "Zulu"}`
_, err := w.Write([]byte(evt))
if err != nil {
t.Errorf("Unexpected error when writing output: %s", err)
}

expectedOutput := "<nil> INF Zoo zebra=Zulu aardvark=Able mussel=Mountain\n"
actualOutput := buf.String()
if actualOutput != expectedOutput {
t.Errorf("Unexpected output %q, want: %q", actualOutput, expectedOutput)
}
})

t.Run("Sets FieldsExclude", func(t *testing.T) {
buf := &bytes.Buffer{}
w := zerolog.ConsoleWriter{Out: buf, NoColor: true, FieldsExclude: []string{"foo"}}
Expand Down

0 comments on commit c78e50e

Please sign in to comment.