From a64e515cb91915584cc6c9fb5eb931d6e660ec9d Mon Sep 17 00:00:00 2001 From: Rodrigo Martell Date: Wed, 23 Oct 2024 10:43:54 +1000 Subject: [PATCH] feat/message-formatter-from-event --- README.md | 23 +++++++++++++++++++---- console.go | 28 +++++++++++++++++----------- console_test.go | 14 +++++++++++++- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 1306a6c1..22934265 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ func main() { Str("Scale", "833 cents"). Float64("Interval", 833.09). Msg("Fibonacci is everywhere") - + log.Debug(). Str("Name", "Tom"). Send() @@ -232,7 +232,7 @@ func main() { #### Error Logging with Stacktrace -Using `github.com/pkg/errors`, you can add a formatted stacktrace to your errors. +Using `github.com/pkg/errors`, you can add a formatted stacktrace to your errors. ```go package main @@ -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) } @@ -609,7 +624,7 @@ if err := http.ListenAndServe(":8080", nil); err != nil { ``` ## Multiple Log Output -`zerolog.MultiLevelWriter` may be used to send the log message to multiple outputs. +`zerolog.MultiLevelWriter` may be used to send the log message to multiple outputs. In this example, we send the log message to both `os.Stdout` and the in-built ConsoleWriter. ```go func main() { @@ -640,7 +655,7 @@ Some settings can be changed and will be applied to all loggers: * `zerolog.ErrorFieldName`: Can be set to customize `Err` field name. * `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with `zerolog.TimeFormatUnix`, `zerolog.TimeFormatUnixMs` or `zerolog.TimeFormatUnixMicro`, times are formatted as UNIX timestamp. * `zerolog.DurationFieldUnit`: Can be set to customize the unit for time.Duration type fields added by `Dur` (default: `time.Millisecond`). -* `zerolog.DurationFieldInteger`: If set to `true`, `Dur` fields are formatted as integers instead of floats (default: `false`). +* `zerolog.DurationFieldInteger`: If set to `true`, `Dur` fields are formatted as integers instead of floats (default: `false`). * `zerolog.ErrorHandler`: Called whenever zerolog fails to write an event on its output. If not set, an error is printed on the stderr. This handler must be thread safe and non-blocking. * `zerolog.FloatingPointPrecision`: If set to a value other than -1, controls the number of digits when formatting float numbers in JSON. See diff --git a/console.go b/console.go index 7e65e86f..d03e36e7 100644 --- a/console.go +++ b/console.go @@ -47,6 +47,9 @@ const ( // Formatter transforms the input into a formatted string. type Formatter func(interface{}) 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 { @@ -77,14 +80,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 FormatExtra func(map[string]interface{}, *bytes.Buffer) error @@ -305,10 +309,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 179dfeef..7d8c7d41 100644 --- a/console_test.go +++ b/console_test.go @@ -24,10 +24,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 ExampleNewConsoleWriter() {