Add support for custom object marshaling
This commit is contained in:
parent
f220d89e1f
commit
fdbdb09630
|
@ -72,12 +72,19 @@ func BenchmarkLogFields(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
type obj struct {
|
||||
Pub string
|
||||
Tag string `json:"tag"`
|
||||
priv int
|
||||
}
|
||||
|
||||
func (o obj) MarshalZerologObject(e *Event) {
|
||||
e.Str("Pub", o.Pub).
|
||||
Str("Tag", o.Tag).
|
||||
Int("priv", o.priv)
|
||||
}
|
||||
|
||||
func BenchmarkLogFieldType(b *testing.B) {
|
||||
type obj struct {
|
||||
Pub string
|
||||
Tag string `json:"tag"`
|
||||
priv int
|
||||
}
|
||||
bools := []bool{true, false, true, false, true, false, true, false, true, false}
|
||||
ints := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
floats := []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
|
@ -143,6 +150,9 @@ func BenchmarkLogFieldType(b *testing.B) {
|
|||
"Interface": func(e *Event) *Event {
|
||||
return e.Interface("k", o)
|
||||
},
|
||||
"Object": func(e *Event) *Event {
|
||||
return e.Object("k", o)
|
||||
},
|
||||
}
|
||||
logger := New(ioutil.Discard)
|
||||
b.ResetTimer()
|
||||
|
|
15
context.go
15
context.go
|
@ -1,6 +1,9 @@
|
|||
package zerolog
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Context configures a new sub-logger with contextual fields.
|
||||
type Context struct {
|
||||
|
@ -26,6 +29,16 @@ func (c Context) Dict(key string, dict *Event) Context {
|
|||
return c
|
||||
}
|
||||
|
||||
// Object marshals an object that implement the LogObjectMarshaler interface.
|
||||
func (c Context) Object(key string, obj LogObjectMarshaler) Context {
|
||||
e := newEvent(levelWriterAdapter{ioutil.Discard}, 0, true)
|
||||
e.Object(key, obj)
|
||||
e.buf[0] = ',' // A new event starts as an object, we want to embed it.
|
||||
c.l.context = append(c.l.context, e.buf...)
|
||||
eventPool.Put(e)
|
||||
return c
|
||||
}
|
||||
|
||||
// Str adds the field key with val as a string to the logger context.
|
||||
func (c Context) Str(key, val string) Context {
|
||||
c.l.context = appendString(c.l.context, key, val)
|
||||
|
|
21
event.go
21
event.go
|
@ -26,6 +26,10 @@ type Event struct {
|
|||
done func(msg string)
|
||||
}
|
||||
|
||||
type LogObjectMarshaler interface {
|
||||
MarshalZerologObject(e *Event)
|
||||
}
|
||||
|
||||
func newEvent(w LevelWriter, level Level, enabled bool) *Event {
|
||||
if !enabled {
|
||||
return &Event{}
|
||||
|
@ -121,6 +125,23 @@ func Dict() *Event {
|
|||
return newEvent(levelWriterAdapter{ioutil.Discard}, 0, true)
|
||||
}
|
||||
|
||||
// Object marshals an object that implement the LogObjectMarshaler interface.
|
||||
func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
|
||||
e.buf = appendKey(e.buf, key)
|
||||
pos := len(e.buf)
|
||||
obj.MarshalZerologObject(e)
|
||||
if pos < len(e.buf) {
|
||||
// As MarshalZerologObject will use event API, the first field will be
|
||||
// preceded by a coma. If at least one field has been added (buf grew),
|
||||
// we replace this coma by the opening bracket.
|
||||
e.buf[pos] = '{'
|
||||
} else {
|
||||
e.buf = append(e.buf, '{')
|
||||
}
|
||||
e.buf = append(e.buf, '}')
|
||||
return e
|
||||
}
|
||||
|
||||
// Str adds the field key with val as a string to the *Event context.
|
||||
func (e *Event) Str(key, val string) *Event {
|
||||
if !e.enabled {
|
||||
|
|
|
@ -138,6 +138,31 @@ func ExampleEvent_Dict() {
|
|||
// Output: {"foo":"bar","dict":{"bar":"baz","n":1},"message":"hello world"}
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Name string
|
||||
Age int
|
||||
Created time.Time
|
||||
}
|
||||
|
||||
func (u User) MarshalZerologObject(e *zerolog.Event) {
|
||||
e.Str("name", u.Name).
|
||||
Int("age", u.Age).
|
||||
Time("created", u.Created)
|
||||
}
|
||||
|
||||
func ExampleEvent_Object() {
|
||||
log := zerolog.New(os.Stdout)
|
||||
|
||||
u := User{"John", 35, time.Time{}}
|
||||
|
||||
log.Log().
|
||||
Str("foo", "bar").
|
||||
Object("user", u).
|
||||
Msg("hello world")
|
||||
|
||||
// Output: {"foo":"bar","user":{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},"message":"hello world"}
|
||||
}
|
||||
|
||||
func ExampleEvent_Interface() {
|
||||
log := zerolog.New(os.Stdout)
|
||||
|
||||
|
@ -197,6 +222,19 @@ func ExampleContext_Dict() {
|
|||
// Output: {"foo":"bar","dict":{"bar":"baz","n":1},"message":"hello world"}
|
||||
}
|
||||
|
||||
func ExampleContext_Object() {
|
||||
u := User{"John", 35, time.Time{}}
|
||||
|
||||
log := zerolog.New(os.Stdout).With().
|
||||
Str("foo", "bar").
|
||||
Object("user", u).
|
||||
Logger()
|
||||
|
||||
log.Log().Msg("hello world")
|
||||
|
||||
// Output: {"foo":"bar","user":{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},"message":"hello world"}
|
||||
}
|
||||
|
||||
func ExampleContext_Interface() {
|
||||
obj := struct {
|
||||
Name string `json:"name"`
|
||||
|
|
Loading…
Reference in New Issue