diff --git a/globals.go b/globals.go index b38a7fce..ac1d9c48 100644 --- a/globals.go +++ b/globals.go @@ -1,6 +1,7 @@ package zerolog import ( + "bytes" "encoding/json" "strconv" "sync/atomic" @@ -81,8 +82,22 @@ var ( } // InterfaceMarshalFunc allows customization of interface marshaling. - // Default: "encoding/json.Marshal" - InterfaceMarshalFunc = json.Marshal + // Default: "encoding/json.Marshal" with disabled HTML escaping + InterfaceMarshalFunc = func(v interface{}) ([]byte, error) { + var buf bytes.Buffer + encoder := json.NewEncoder(&buf) + encoder.SetEscapeHTML(false) + err := encoder.Encode(v) + if err != nil { + return nil, err + } + b := buf.Bytes() + if len(b) > 0 { + // Remove trailing \n which is added by Encode. + return b[:len(b)-1], nil + } + return b, nil + } // TimeFieldFormat defines the time format of the Time field type. If set to // TimeFormatUnix, TimeFormatUnixMs, TimeFormatUnixMicro or TimeFormatUnixNano, the time is formatted as a UNIX diff --git a/log_test.go b/log_test.go index 4d0d93b1..e51eb8fb 100644 --- a/log_test.go +++ b/log_test.go @@ -1013,3 +1013,12 @@ func TestUnmarshalTextLevel(t *testing.T) { }) } } + +func TestHTMLNoEscaping(t *testing.T) { + out := &bytes.Buffer{} + log := New(out) + log.Log().Interface("head", "").Send() + if got, want := decodeIfBinaryToString(out.Bytes()), `{"head":""}`+"\n"; got != want { + t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) + } +}