Add support for custom object marshaling
This commit is contained in:
parent
f220d89e1f
commit
fdbdb09630
|
@ -72,12 +72,19 @@ func BenchmarkLogFields(b *testing.B) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkLogFieldType(b *testing.B) {
|
type obj struct {
|
||||||
type obj struct {
|
|
||||||
Pub string
|
Pub string
|
||||||
Tag string `json:"tag"`
|
Tag string `json:"tag"`
|
||||||
priv int
|
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) {
|
||||||
bools := []bool{true, false, true, false, true, false, true, false, true, false}
|
bools := []bool{true, false, true, false, true, false, true, false, true, false}
|
||||||
ints := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
ints := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||||
floats := []float64{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 {
|
"Interface": func(e *Event) *Event {
|
||||||
return e.Interface("k", o)
|
return e.Interface("k", o)
|
||||||
},
|
},
|
||||||
|
"Object": func(e *Event) *Event {
|
||||||
|
return e.Object("k", o)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
logger := New(ioutil.Discard)
|
logger := New(ioutil.Discard)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
15
context.go
15
context.go
|
@ -1,6 +1,9 @@
|
||||||
package zerolog
|
package zerolog
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// Context configures a new sub-logger with contextual fields.
|
// Context configures a new sub-logger with contextual fields.
|
||||||
type Context struct {
|
type Context struct {
|
||||||
|
@ -26,6 +29,16 @@ func (c Context) Dict(key string, dict *Event) Context {
|
||||||
return c
|
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.
|
// Str adds the field key with val as a string to the logger context.
|
||||||
func (c Context) Str(key, val string) Context {
|
func (c Context) Str(key, val string) Context {
|
||||||
c.l.context = appendString(c.l.context, key, val)
|
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)
|
done func(msg string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LogObjectMarshaler interface {
|
||||||
|
MarshalZerologObject(e *Event)
|
||||||
|
}
|
||||||
|
|
||||||
func newEvent(w LevelWriter, level Level, enabled bool) *Event {
|
func newEvent(w LevelWriter, level Level, enabled bool) *Event {
|
||||||
if !enabled {
|
if !enabled {
|
||||||
return &Event{}
|
return &Event{}
|
||||||
|
@ -121,6 +125,23 @@ func Dict() *Event {
|
||||||
return newEvent(levelWriterAdapter{ioutil.Discard}, 0, true)
|
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.
|
// Str adds the field key with val as a string to the *Event context.
|
||||||
func (e *Event) Str(key, val string) *Event {
|
func (e *Event) Str(key, val string) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
|
|
|
@ -138,6 +138,31 @@ func ExampleEvent_Dict() {
|
||||||
// Output: {"foo":"bar","dict":{"bar":"baz","n":1},"message":"hello world"}
|
// 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() {
|
func ExampleEvent_Interface() {
|
||||||
log := zerolog.New(os.Stdout)
|
log := zerolog.New(os.Stdout)
|
||||||
|
|
||||||
|
@ -197,6 +222,19 @@ func ExampleContext_Dict() {
|
||||||
// Output: {"foo":"bar","dict":{"bar":"baz","n":1},"message":"hello world"}
|
// 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() {
|
func ExampleContext_Interface() {
|
||||||
obj := struct {
|
obj := struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
Loading…
Reference in New Issue