Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to customize internal json marshaler #318

Merged
merged 1 commit into from May 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions encoder_cbor.go
Expand Up @@ -14,6 +14,13 @@ var (
enc = cbor.Encoder{}
)

func init() {
// using closure to reflect the changes at runtime.
cbor.JSONMarshalFunc = func(v interface{}) ([]byte, error) {
return InterfaceMarshalFunc(v)
}
}

func appendJSON(dst []byte, j []byte) []byte {
return cbor.AppendEmbeddedJSON(dst, j)
}
Expand Down
7 changes: 7 additions & 0 deletions encoder_json.go
Expand Up @@ -15,6 +15,13 @@ var (
enc = json.Encoder{}
)

func init() {
// using closure to reflect the changes at runtime.
json.JSONMarshalFunc = func(v interface{}) ([]byte, error) {
return InterfaceMarshalFunc(v)
}
}

func appendJSON(dst []byte, j []byte) []byte {
return append(dst, j...)
}
Expand Down
5 changes: 5 additions & 0 deletions globals.go
@@ -1,6 +1,7 @@
package zerolog

import (
"encoding/json"
"strconv"
"sync/atomic"
"time"
Expand Down Expand Up @@ -75,6 +76,10 @@ var (
return err
}

// InterfaceMarshalFunc allows customization of interface marshaling.
// Default: "encoding/json.Marshal"
InterfaceMarshalFunc = json.Marshal

// TimeFieldFormat defines the time format of the Time field type. If set to
// TimeFormatUnix, TimeFormatUnixMs or TimeFormatUnixMicro, the time is formatted as an UNIX
// timestamp as integer.
Expand Down
10 changes: 9 additions & 1 deletion internal/cbor/base.go
@@ -1,5 +1,13 @@
package cbor

// JSONMarshalFunc is used to marshal interface to JSON encoded byte slice.
// Making it package level instead of embedded in Encoder brings
// some extra efforts at importing, but avoids value copy when the functions
// of Encoder being invoked.
// DO REMEMBER to set this variable at importing, or
// you might get a nil pointer dereference panic at runtime.
var JSONMarshalFunc func(v interface{}) ([]byte, error)

type Encoder struct{}

// AppendKey adds a key (string) to the binary encoded log message
Expand All @@ -8,4 +16,4 @@ func (e Encoder) AppendKey(dst []byte, key string) []byte {
dst = e.AppendBeginMarker(dst)
}
return e.AppendString(dst, key)
}
}
3 changes: 1 addition & 2 deletions internal/cbor/types.go
@@ -1,7 +1,6 @@
package cbor

import (
"encoding/json"
"fmt"
"math"
"net"
Expand Down Expand Up @@ -432,7 +431,7 @@ func (e Encoder) AppendFloats64(dst []byte, vals []float64) []byte {

// AppendInterface takes an arbitrary object and converts it to JSON and embeds it dst.
func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
marshaled, err := json.Marshal(i)
marshaled, err := JSONMarshalFunc(i)
if err != nil {
return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
}
Expand Down
8 changes: 8 additions & 0 deletions internal/json/base.go
@@ -1,5 +1,13 @@
package json

// JSONMarshalFunc is used to marshal interface to JSON encoded byte slice.
// Making it package level instead of embedded in Encoder brings
// some extra efforts at importing, but avoids value copy when the functions
// of Encoder being invoked.
// DO REMEMBER to set this variable at importing, or
// you might get a nil pointer dereference panic at runtime.
var JSONMarshalFunc func(v interface{}) ([]byte, error)

type Encoder struct{}

// AppendKey appends a new key to the output JSON.
Expand Down
3 changes: 1 addition & 2 deletions internal/json/types.go
@@ -1,7 +1,6 @@
package json

import (
"encoding/json"
"fmt"
"math"
"net"
Expand Down Expand Up @@ -363,7 +362,7 @@ func (Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
// AppendInterface marshals the input interface to a string and
// appends the encoded string to the input byte slice.
func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
marshaled, err := json.Marshal(i)
marshaled, err := JSONMarshalFunc(i)
if err != nil {
return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
}
Expand Down