Skip to content

Commit c78e50e

Browse files
authored
Add fields order (#550)
1 parent 8582bed commit c78e50e

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

console.go

+37-1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ type ConsoleWriter struct {
6969
// PartsExclude defines parts to not display in output.
7070
PartsExclude []string
7171

72+
// FieldsOrder defines the order of contextual fields in output.
73+
FieldsOrder []string
74+
75+
fieldIsOrdered map[string]int
76+
7277
// FieldsExclude defines contextual fields to not display in output.
7378
FieldsExclude []string
7479

@@ -191,7 +196,12 @@ func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer
191196
}
192197
fields = append(fields, field)
193198
}
194-
sort.Strings(fields)
199+
200+
if len(w.FieldsOrder) > 0 {
201+
w.orderFields(fields)
202+
} else {
203+
sort.Strings(fields)
204+
}
195205

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

337+
// orderFields takes an array of field names and an array representing field order
338+
// and returns an array with any ordered fields at the beginning, in order,
339+
// and the remaining fields after in their original order.
340+
func (w ConsoleWriter) orderFields(fields []string) {
341+
if w.fieldIsOrdered == nil {
342+
w.fieldIsOrdered = make(map[string]int)
343+
for i, fieldName := range w.FieldsOrder {
344+
w.fieldIsOrdered[fieldName] = i
345+
}
346+
}
347+
sort.Slice(fields, func(i, j int) bool {
348+
ii, iOrdered := w.fieldIsOrdered[fields[i]]
349+
jj, jOrdered := w.fieldIsOrdered[fields[j]]
350+
if iOrdered && jOrdered {
351+
return ii < jj
352+
}
353+
if iOrdered {
354+
return true
355+
}
356+
if jOrdered {
357+
return false
358+
}
359+
return fields[i] < fields[j]
360+
})
361+
}
362+
327363
// needsQuote returns true when the string s should be quoted in output.
328364
func needsQuote(s string) bool {
329365
for i := range s {

console_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,23 @@ func TestConsoleWriterConfiguration(t *testing.T) {
486486
}
487487
})
488488

489+
t.Run("Sets FieldsOrder", func(t *testing.T) {
490+
buf := &bytes.Buffer{}
491+
w := zerolog.ConsoleWriter{Out: buf, NoColor: true, FieldsOrder: []string{"zebra", "aardvark"}}
492+
493+
evt := `{"level": "info", "message": "Zoo", "aardvark": "Able", "mussel": "Mountain", "zebra": "Zulu"}`
494+
_, err := w.Write([]byte(evt))
495+
if err != nil {
496+
t.Errorf("Unexpected error when writing output: %s", err)
497+
}
498+
499+
expectedOutput := "<nil> INF Zoo zebra=Zulu aardvark=Able mussel=Mountain\n"
500+
actualOutput := buf.String()
501+
if actualOutput != expectedOutput {
502+
t.Errorf("Unexpected output %q, want: %q", actualOutput, expectedOutput)
503+
}
504+
})
505+
489506
t.Run("Sets FieldsExclude", func(t *testing.T) {
490507
buf := &bytes.Buffer{}
491508
w := zerolog.ConsoleWriter{Out: buf, NoColor: true, FieldsExclude: []string{"foo"}}

0 commit comments

Comments
 (0)