From 6d63a2cec1c093306da599d5f750737d13d3fb24 Mon Sep 17 00:00:00 2001 From: Rodrigo Martell Date: Fri, 30 May 2025 10:48:35 +1000 Subject: [PATCH] feat/message-formatter-from-event --- README.md | 15 +++++++++++++++ console.go | 34 ++++++++++++++++++++-------------- console_test.go | 14 +++++++++++++- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9d4e8e8d..55aff5fd 100644 --- a/README.md +++ b/README.md @@ -352,6 +352,21 @@ output.FormatLevel = func(i interface{}) string { output.FormatMessage = func(i interface{}) string { return fmt.Sprintf("***%s****", i) } +output.FormatMessageFromEvent = func(evt map[string]interface{}) zerolog.Formatter { + return func(i interface{}) string { + level := evt[zerolog.LevelFieldName] + switch level { + case zerolog.LevelInfoValue: + return fmt.Sprintf("=> %s %s", level, i) + case zerolog.LevelWarnValue: + return fmt.Sprintf("!! %s %s", level, i) + case zerolog.LevelErrorValue, zerolog.LevelFatalValue, zerolog.LevelPanicValue: + return fmt.Sprintf("XX %s %s", level, i) + default: + return fmt.Sprintf("%s", i) + } + } +} output.FormatFieldName = func(i interface{}) string { return fmt.Sprintf("%s:", i) } diff --git a/console.go b/console.go index 6c881ef6..6eb417b6 100644 --- a/console.go +++ b/console.go @@ -51,6 +51,9 @@ type Formatter func(interface{}) string // being able to differentiate formatting based on field name. type FormatterByFieldName func(interface{}, string) string +// FormatterFromEvent generates a Formatter from an event. +type FormatterFromEvent func(map[string]interface{}) Formatter + // ConsoleWriter parses the JSON input and writes it in an // (optionally) colorized, human-friendly format to Out. type ConsoleWriter struct { @@ -81,14 +84,15 @@ type ConsoleWriter struct { // FieldsExclude defines contextual fields to not display in output. FieldsExclude []string - FormatTimestamp Formatter - FormatLevel Formatter - FormatCaller Formatter - FormatMessage Formatter - FormatFieldName Formatter - FormatFieldValue Formatter - FormatErrFieldName Formatter - FormatErrFieldValue Formatter + FormatTimestamp Formatter + FormatLevel Formatter + FormatCaller Formatter + FormatMessage Formatter + FormatMessageFromEvent FormatterFromEvent + FormatFieldName Formatter + FormatFieldValue Formatter + FormatErrFieldName Formatter + FormatErrFieldValue Formatter // If this is configured it is used for "part" values and // has precedence on FormatFieldValue FormatPartValueByName FormatterByFieldName @@ -101,9 +105,9 @@ type ConsoleWriter struct { // NewConsoleWriter creates and initializes a new ConsoleWriter. func NewConsoleWriter(options ...func(w *ConsoleWriter)) ConsoleWriter { w := ConsoleWriter{ - Out: os.Stdout, - TimeFormat: consoleDefaultTimeFormat, - PartsOrder: consoleDefaultPartsOrder(), + Out: os.Stdout, + TimeFormat: consoleDefaultTimeFormat, + PartsOrder: consoleDefaultPartsOrder(), } for _, opt := range options { @@ -313,10 +317,12 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{}, f = w.FormatTimestamp } case MessageFieldName: - if w.FormatMessage == nil { - f = consoleDefaultFormatMessage(w.NoColor, evt[LevelFieldName]) - } else { + if w.FormatMessageFromEvent != nil { + f = w.FormatMessageFromEvent(evt) + } else if w.FormatMessage != nil { f = w.FormatMessage + } else { + f = consoleDefaultFormatMessage(w.NoColor, evt[LevelFieldName]) } case CallerFieldName: if w.FormatCaller == nil { diff --git a/console_test.go b/console_test.go index 6b97f6ca..891efc96 100644 --- a/console_test.go +++ b/console_test.go @@ -26,10 +26,22 @@ func ExampleConsoleWriter_customFormatters() { out.FormatLevel = func(i interface{}) string { return strings.ToUpper(fmt.Sprintf("%-6s|", i)) } out.FormatFieldName = func(i interface{}) string { return fmt.Sprintf("%s:", i) } out.FormatFieldValue = func(i interface{}) string { return strings.ToUpper(fmt.Sprintf("%s", i)) } + out.FormatMessageFromEvent = func(evt map[string]interface{}) zerolog.Formatter { + return func(i interface{}) string { + level := evt[zerolog.LevelFieldName] + switch level { + case zerolog.LevelInfoValue, zerolog.LevelWarnValue, zerolog.LevelErrorValue, zerolog.LevelFatalValue, zerolog.LevelPanicValue: + return fmt.Sprintf("%s (%q formatted message)", i, level) + default: + return fmt.Sprintf("%s", i) + } + } + } + log := zerolog.New(out) log.Info().Str("foo", "bar").Msg("Hello World") - // Output: INFO | Hello World foo:BAR + // Output: INFO | Hello World ("info" formatted message) foo:BAR } func ExampleConsoleWriter_partValueFormatter() {