diff --git a/README.md b/README.md index 6241b59..eefc1f6 100644 --- a/README.md +++ b/README.md @@ -479,6 +479,7 @@ Some settings can be changed and will by applied to all loggers: // using the Dur method. * `DurationFieldUnit`: Sets the unit of the fields added by `Dur` (default: `time.Millisecond`). * `DurationFieldInteger`: If set to true, `Dur` fields are formatted as integers instead of floats. +* `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. ## Field Types diff --git a/event.go b/event.go index c08214b..a0e090a 100644 --- a/event.go +++ b/event.go @@ -137,7 +137,11 @@ func (e *Event) msg(msg string) { defer e.done(msg) } if err := e.write(); err != nil { - fmt.Fprintf(os.Stderr, "zerolog: could not write event: %v\n", err) + if ErrorHandler != nil { + ErrorHandler(err) + } else { + fmt.Fprintf(os.Stderr, "zerolog: could not write event: %v\n", err) + } } } diff --git a/globals.go b/globals.go index 1a7dbcf..1c66904 100644 --- a/globals.go +++ b/globals.go @@ -37,6 +37,11 @@ var ( // DurationFieldInteger renders Dur fields as integer instead of float if // set to true. DurationFieldInteger = false + + // ErrorHandler is 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. + ErrorHandler func(err error) ) var ( diff --git a/log_test.go b/log_test.go index 3ae0238..50cd1a6 100644 --- a/log_test.go +++ b/log_test.go @@ -640,3 +640,24 @@ func TestErrorMarshalFunc(t *testing.T) { t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) } } + +type errWriter struct { + error +} + +func (w errWriter) Write(p []byte) (n int, err error) { + return 0, w.error +} + +func TestErrorHandler(t *testing.T) { + var got error + want := errors.New("write error") + ErrorHandler = func(err error) { + got = err + } + log := New(errWriter{want}) + log.Log().Msg("test") + if got != want { + t.Errorf("ErrorHandler err = %#v, want %#v", got, want) + } +}