Add ability to customize internal json marshaler (#318)

Added a package level variable "InterfaceMarshalFunc".
It's used to marshal interface to JSON encoded byte slice,
mostly when event.Interface("key", v) is called.
This commit is contained in:
povsister 2021-05-20 20:46:36 +08:00 committed by GitHub
parent ffbd37b8d7
commit 47a03bc5eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 38 additions and 5 deletions

View File

@ -14,6 +14,13 @@ var (
enc = cbor.Encoder{} 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 { func appendJSON(dst []byte, j []byte) []byte {
return cbor.AppendEmbeddedJSON(dst, j) return cbor.AppendEmbeddedJSON(dst, j)
} }

View File

@ -15,6 +15,13 @@ var (
enc = json.Encoder{} 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 { func appendJSON(dst []byte, j []byte) []byte {
return append(dst, j...) return append(dst, j...)
} }

View File

@ -1,6 +1,7 @@
package zerolog package zerolog
import ( import (
"encoding/json"
"strconv" "strconv"
"sync/atomic" "sync/atomic"
"time" "time"
@ -75,6 +76,10 @@ var (
return err 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 // TimeFieldFormat defines the time format of the Time field type. If set to
// TimeFormatUnix, TimeFormatUnixMs or TimeFormatUnixMicro, the time is formatted as an UNIX // TimeFormatUnix, TimeFormatUnixMs or TimeFormatUnixMicro, the time is formatted as an UNIX
// timestamp as integer. // timestamp as integer.

View File

@ -1,5 +1,13 @@
package cbor 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{} type Encoder struct{}
// AppendKey adds a key (string) to the binary encoded log message // AppendKey adds a key (string) to the binary encoded log message
@ -8,4 +16,4 @@ func (e Encoder) AppendKey(dst []byte, key string) []byte {
dst = e.AppendBeginMarker(dst) dst = e.AppendBeginMarker(dst)
} }
return e.AppendString(dst, key) return e.AppendString(dst, key)
} }

View File

@ -1,7 +1,6 @@
package cbor package cbor
import ( import (
"encoding/json"
"fmt" "fmt"
"math" "math"
"net" "net"
@ -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. // AppendInterface takes an arbitrary object and converts it to JSON and embeds it dst.
func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte { func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
marshaled, err := json.Marshal(i) marshaled, err := JSONMarshalFunc(i)
if err != nil { if err != nil {
return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err)) return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
} }

View File

@ -1,5 +1,13 @@
package json 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{} type Encoder struct{}
// AppendKey appends a new key to the output JSON. // AppendKey appends a new key to the output JSON.

View File

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