EmbedObject() API and knob to change caller frames (#66)

* Fix for a bug in cbor decodeFloat
* Add EmbedObject() method
* knob to change the depth of caller frames to skip
* removed EmbedObj() for array - since it is same as Object()
This commit is contained in:
Ravi Raju 2018-05-16 18:42:33 -07:00 committed by Olivier Poitrey
parent b5207c012d
commit a025d45231
6 changed files with 116 additions and 2 deletions

View File

@ -283,6 +283,21 @@ func ExampleEvent_Object() {
// Output: {"foo":"bar","user":{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},"message":"hello world"} // Output: {"foo":"bar","user":{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},"message":"hello world"}
} }
func ExampleEvent_EmbedObject() {
price := Price{val: 6449, prec: 2, unit: "$"}
dst := bytes.Buffer{}
log := New(&dst)
log.Log().
Str("foo", "bar").
EmbedObject(price).
Msg("hello world")
fmt.Println(decodeIfBinaryToString(dst.Bytes()))
// Output: {"foo":"bar","price":"$64.49","message":"hello world"}
}
func ExampleEvent_Interface() { func ExampleEvent_Interface() {
dst := bytes.Buffer{} dst := bytes.Buffer{}
log := New(&dst) log := New(&dst)
@ -384,6 +399,36 @@ func ExampleContext_Array_object() {
// Output: {"foo":"bar","users":[{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},{"name":"Bob","age":55,"created":"0001-01-01T00:00:00Z"}],"message":"hello world"} // Output: {"foo":"bar","users":[{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},{"name":"Bob","age":55,"created":"0001-01-01T00:00:00Z"}],"message":"hello world"}
} }
type Price struct {
val uint64
prec int
unit string
}
func (p Price) MarshalZerologObject(e *Event) {
denom := uint64(1)
for i := 0; i < p.prec; i++ {
denom *= 10
}
result := []byte(p.unit)
result = append(result, fmt.Sprintf("%d.%d", p.val/denom, p.val%denom)...)
e.Str("price", string(result))
}
func ExampleContext_EmbedObject() {
price := Price{val: 6449, prec: 2, unit: "$"}
dst := bytes.Buffer{}
log := New(&dst).With().
Str("foo", "bar").
EmbedObject(price).
Logger()
log.Log().Msg("hello world")
fmt.Println(decodeIfBinaryToString(dst.Bytes()))
// Output: {"foo":"bar","price":"$64.49","message":"hello world"}
}
func ExampleContext_Object() { func ExampleContext_Object() {
// User implements LogObjectMarshaler // User implements LogObjectMarshaler
u := User{"John", 35, time.Time{}} u := User{"John", 35, time.Time{}}

View File

@ -59,6 +59,15 @@ func (c Context) Object(key string, obj LogObjectMarshaler) Context {
return c return c
} }
// EmbedObject marshals and Embeds an object that implement the LogObjectMarshaler interface.
func (c Context) EmbedObject(obj LogObjectMarshaler) Context {
e := newEvent(levelWriterAdapter{ioutil.Discard}, 0)
e.EmbedObject(obj)
c.l.context = enc.AppendObjectData(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 = enc.AppendString(enc.AppendKey(c.l.context, key), val) c.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val)
@ -321,7 +330,8 @@ func (c Context) Interface(key string, i interface{}) Context {
type callerHook struct{} type callerHook struct{}
func (ch callerHook) Run(e *Event, level Level, msg string) { func (ch callerHook) Run(e *Event, level Level, msg string) {
e.caller(4) //Two extra frames to skip (added by hook infra).
e.caller(CallerSkipFrameCount+2)
} }
var ch = callerHook{} var ch = callerHook{}

View File

@ -179,6 +179,15 @@ func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
return e return e
} }
// Object marshals an object that implement the LogObjectMarshaler interface.
func (e *Event) EmbedObject(obj LogObjectMarshaler) *Event {
if e == nil {
return e
}
obj.MarshalZerologObject(e)
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 == nil { if e == nil {
@ -581,7 +590,7 @@ func (e *Event) Interface(key string, i interface{}) *Event {
// Caller adds the file:line of the caller with the zerolog.CallerFieldName key. // Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
func (e *Event) Caller() *Event { func (e *Event) Caller() *Event {
return e.caller(2) return e.caller(CallerSkipFrameCount)
} }
func (e *Event) caller(skip int) *Event { func (e *Event) caller(skip int) *Event {

View File

@ -19,6 +19,9 @@ var (
// CallerFieldName is the field name used for caller field. // CallerFieldName is the field name used for caller field.
CallerFieldName = "caller" CallerFieldName = "caller"
// CallerSkipFrameCount is the number of stack frames to skip to find the caller.
CallerSkipFrameCount = 2
// TimeFieldFormat defines the time format of the Time field type. // TimeFieldFormat defines the time format of the Time field type.
// If set to an empty string, the time is formatted as an UNIX timestamp // If set to an empty string, the time is formatted as an UNIX timestamp
// as integer. // as integer.

View File

@ -1,5 +1,8 @@
// +build !windows // +build !windows
// Package journald provides a io.Writer to send the logs
// to journalD component of systemd.
package journald package journald
// This file provides a zerolog writer so that logs printed // This file provides a zerolog writer so that logs printed

View File

@ -4,6 +4,7 @@ package zerolog_test
import ( import (
"errors" "errors"
"fmt"
stdlog "log" stdlog "log"
"net" "net"
"os" "os"
@ -195,6 +196,22 @@ func (u User) MarshalZerologObject(e *zerolog.Event) {
Time("created", u.Created) Time("created", u.Created)
} }
type Price struct {
val uint64
prec int
unit string
}
func (p Price) MarshalZerologObject(e *zerolog.Event) {
denom := uint64(1)
for i := 0; i < p.prec; i++ {
denom *= 10
}
result := []byte(p.unit)
result = append(result, fmt.Sprintf("%d.%d", p.val/denom, p.val%denom)...)
e.Str("price", string(result))
}
type Users []User type Users []User
func (uu Users) MarshalZerologArray(a *zerolog.Array) { func (uu Users) MarshalZerologArray(a *zerolog.Array) {
@ -248,6 +265,19 @@ func ExampleEvent_Object() {
// Output: {"foo":"bar","user":{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},"message":"hello world"} // Output: {"foo":"bar","user":{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},"message":"hello world"}
} }
func ExampleEvent_EmbedObject() {
log := zerolog.New(os.Stdout)
price := Price{val: 6449, prec: 2, unit: "$"}
log.Log().
Str("foo", "bar").
EmbedObject(price).
Msg("hello world")
// Output: {"foo":"bar","price":"$64.49","message":"hello world"}
}
func ExampleEvent_Interface() { func ExampleEvent_Interface() {
log := zerolog.New(os.Stdout) log := zerolog.New(os.Stdout)
@ -351,6 +381,20 @@ func ExampleContext_Object() {
// Output: {"foo":"bar","user":{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},"message":"hello world"} // Output: {"foo":"bar","user":{"name":"John","age":35,"created":"0001-01-01T00:00:00Z"},"message":"hello world"}
} }
func ExampleContext_EmbedObject() {
price := Price{val: 6449, prec: 2, unit: "$"}
log := zerolog.New(os.Stdout).With().
Str("foo", "bar").
EmbedObject(price).
Logger()
log.Log().Msg("hello world")
// Output: {"foo":"bar","price":"$64.49","message":"hello world"}
}
func ExampleContext_Interface() { func ExampleContext_Interface() {
obj := struct { obj := struct {
Name string `json:"name"` Name string `json:"name"`