Skip to content

Commit 1869fa5

Browse files
authored
FormatPartValueByName for flexible custom formatting for ConsoleWriter (#541)
1 parent 31e7995 commit 1869fa5

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

README.md

+31
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,37 @@ log.Info().Str("foo", "bar").Msg("Hello World")
366366
// Output: 2006-01-02T15:04:05Z07:00 | INFO | ***Hello World**** foo:BAR
367367
```
368368

369+
To use custom advanced formatting:
370+
371+
```go
372+
output := zerolog.ConsoleWriter{Out: os.Stdout, NoColor: true,
373+
PartsOrder: []string{"level", "one", "two", "three", "message"},
374+
FieldsExclude: []string{"one", "two", "three"}}
375+
output.FormatLevel = func(i interface{}) string { return strings.ToUpper(fmt.Sprintf("%-6s", i)) }
376+
output.FormatFieldName = func(i interface{}) string { return fmt.Sprintf("%s:", i) }
377+
output.FormatPartValueByName = func(i interface{}, s string) string {
378+
var ret string
379+
switch s {
380+
case "one":
381+
ret = strings.ToUpper(fmt.Sprintf("%s", i))
382+
case "two":
383+
ret = strings.ToLower(fmt.Sprintf("%s", i))
384+
case "three":
385+
ret = strings.ToLower(fmt.Sprintf("(%s)", i))
386+
}
387+
return ret
388+
}
389+
log := zerolog.New(output)
390+
391+
log.Info().Str("foo", "bar").
392+
Str("two", "TEST_TWO").
393+
Str("one", "test_one").
394+
Str("three", "test_three").
395+
Msg("Hello World")
396+
397+
// Output: INFO TEST_ONE test_two (test_three) Hello World foo:bar
398+
```
399+
369400
### Sub dictionary
370401

371402
```go

console.go

+19-4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ const (
4747
// Formatter transforms the input into a formatted string.
4848
type Formatter func(interface{}) string
4949

50+
// FormatterByFieldName transforms the input into a formatted string,
51+
// being able to differentiate formatting based on field name.
52+
type FormatterByFieldName func(interface{}, string) string
53+
5054
// ConsoleWriter parses the JSON input and writes it in an
5155
// (optionally) colorized, human-friendly format to Out.
5256
type ConsoleWriter struct {
@@ -85,6 +89,9 @@ type ConsoleWriter struct {
8589
FormatFieldValue Formatter
8690
FormatErrFieldName Formatter
8791
FormatErrFieldValue Formatter
92+
// If this is configured it is used for "part" values and
93+
// has precedence on FormatFieldValue
94+
FormatPartValueByName FormatterByFieldName
8895

8996
FormatExtra func(map[string]interface{}, *bytes.Buffer) error
9097

@@ -282,6 +289,7 @@ func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer
282289
// writePart appends a formatted part to buf.
283290
func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{}, p string) {
284291
var f Formatter
292+
var fvn FormatterByFieldName
285293

286294
if len(w.PartsExclude) > 0 {
287295
for _, exclude := range w.PartsExclude {
@@ -317,14 +325,21 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{},
317325
f = w.FormatCaller
318326
}
319327
default:
320-
if w.FormatFieldValue == nil {
321-
f = consoleDefaultFormatFieldValue
322-
} else {
328+
if w.FormatPartValueByName != nil {
329+
fvn = w.FormatPartValueByName
330+
} else if w.FormatFieldValue != nil {
323331
f = w.FormatFieldValue
332+
} else {
333+
f = consoleDefaultFormatFieldValue
324334
}
325335
}
326336

327-
var s = f(evt[p])
337+
var s string
338+
if f == nil {
339+
s = fvn(evt[p], p)
340+
} else {
341+
s = f(evt[p])
342+
}
328343

329344
if len(s) > 0 {
330345
if buf.Len() > 0 {

console_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,34 @@ func ExampleConsoleWriter_customFormatters() {
3030
// Output: <nil> INFO | Hello World foo:BAR
3131
}
3232

33+
func ExampleConsoleWriter_partValueFormatter() {
34+
out := zerolog.ConsoleWriter{Out: os.Stdout, NoColor: true,
35+
PartsOrder: []string{"level", "one", "two", "three", "message"},
36+
FieldsExclude: []string{"one", "two", "three"}}
37+
out.FormatLevel = func(i interface{}) string { return strings.ToUpper(fmt.Sprintf("%-6s", i)) }
38+
out.FormatFieldName = func(i interface{}) string { return fmt.Sprintf("%s:", i) }
39+
out.FormatPartValueByName = func(i interface{}, s string) string {
40+
var ret string
41+
switch s {
42+
case "one":
43+
ret = strings.ToUpper(fmt.Sprintf("%s", i))
44+
case "two":
45+
ret = strings.ToLower(fmt.Sprintf("%s", i))
46+
case "three":
47+
ret = strings.ToLower(fmt.Sprintf("(%s)", i))
48+
}
49+
return ret
50+
}
51+
log := zerolog.New(out)
52+
53+
log.Info().Str("foo", "bar").
54+
Str("two", "TEST_TWO").
55+
Str("one", "test_one").
56+
Str("three", "test_three").
57+
Msg("Hello World")
58+
// Output: INFO TEST_ONE test_two (test_three) Hello World foo:bar
59+
}
60+
3361
func ExampleNewConsoleWriter() {
3462
out := zerolog.NewConsoleWriter()
3563
out.NoColor = true // For testing purposes only

0 commit comments

Comments
 (0)