Add support for typed array.
This commit is contained in:
parent
6cdd9977c4
commit
614d88bbf8
|
@ -0,0 +1,169 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/internal/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
var arrayPool = &sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &Array{
|
||||||
|
buf: make([]byte, 0, 500),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
type Array struct {
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arr creates an array to be added to an Event or Context.
|
||||||
|
func Arr() *Array {
|
||||||
|
a := arrayPool.Get().(*Array)
|
||||||
|
a.buf = a.buf[:0]
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Array) MarshalZerologArray(*Array) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Array) write(dst []byte) []byte {
|
||||||
|
if len(a.buf) == 0 {
|
||||||
|
dst = append(dst, `[]`...)
|
||||||
|
} else {
|
||||||
|
a.buf[0] = '['
|
||||||
|
dst = append(append(dst, a.buf...), ']')
|
||||||
|
}
|
||||||
|
arrayPool.Put(a)
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object marshals an object that implement the LogObjectMarshaler
|
||||||
|
// interface and append it to the array.
|
||||||
|
func (a *Array) Object(obj LogObjectMarshaler) *Array {
|
||||||
|
a.buf = append(a.buf, ',')
|
||||||
|
e := Dict()
|
||||||
|
obj.MarshalZerologObject(e)
|
||||||
|
e.buf = append(e.buf, '}')
|
||||||
|
a.buf = append(a.buf, e.buf...)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Str append the val as a string to the array.
|
||||||
|
func (a *Array) Str(val string) *Array {
|
||||||
|
a.buf = json.AppendString(append(a.buf, ','), val)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes append the val as a string to the array.
|
||||||
|
func (a *Array) Bytes(val []byte) *Array {
|
||||||
|
a.buf = json.AppendBytes(append(a.buf, ','), val)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err append the err as a string to the array.
|
||||||
|
func (a *Array) Err(err error) *Array {
|
||||||
|
a.buf = json.AppendError(append(a.buf, ','), err)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool append the val as a bool to the array.
|
||||||
|
func (a *Array) Bool(b bool) *Array {
|
||||||
|
a.buf = json.AppendBool(append(a.buf, ','), b)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int append i as a int to the array.
|
||||||
|
func (a *Array) Int(i int) *Array {
|
||||||
|
a.buf = json.AppendInt(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8 append i as a int8 to the array.
|
||||||
|
func (a *Array) Int8(i int8) *Array {
|
||||||
|
a.buf = json.AppendInt8(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16 append i as a int16 to the array.
|
||||||
|
func (a *Array) Int16(i int16) *Array {
|
||||||
|
a.buf = json.AppendInt16(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32 append i as a int32 to the array.
|
||||||
|
func (a *Array) Int32(i int32) *Array {
|
||||||
|
a.buf = json.AppendInt32(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64 append i as a int64 to the array.
|
||||||
|
func (a *Array) Int64(i int64) *Array {
|
||||||
|
a.buf = json.AppendInt64(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint append i as a uint to the array.
|
||||||
|
func (a *Array) Uint(i uint) *Array {
|
||||||
|
a.buf = json.AppendUint(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint8 append i as a uint8 to the array.
|
||||||
|
func (a *Array) Uint8(i uint8) *Array {
|
||||||
|
a.buf = json.AppendUint8(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16 append i as a uint16 to the array.
|
||||||
|
func (a *Array) Uint16(i uint16) *Array {
|
||||||
|
a.buf = json.AppendUint16(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32 append i as a uint32 to the array.
|
||||||
|
func (a *Array) Uint32(i uint32) *Array {
|
||||||
|
a.buf = json.AppendUint32(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64 append i as a uint64 to the array.
|
||||||
|
func (a *Array) Uint64(i uint64) *Array {
|
||||||
|
a.buf = json.AppendUint64(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32 append f as a float32 to the array.
|
||||||
|
func (a *Array) Float32(f float32) *Array {
|
||||||
|
a.buf = json.AppendFloat32(append(a.buf, ','), f)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64 append f as a float64 to the array.
|
||||||
|
func (a *Array) Float64(f float64) *Array {
|
||||||
|
a.buf = json.AppendFloat64(append(a.buf, ','), f)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time append t formated as string using zerolog.TimeFieldFormat.
|
||||||
|
func (a *Array) Time(t time.Time) *Array {
|
||||||
|
a.buf = json.AppendTime(append(a.buf, ','), t, TimeFieldFormat)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dur append d to the array.
|
||||||
|
func (a *Array) Dur(d time.Duration) *Array {
|
||||||
|
a.buf = json.AppendDuration(append(a.buf, ','), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface append i marshaled using reflection.
|
||||||
|
func (a *Array) Interface(i interface{}) *Array {
|
||||||
|
if obj, ok := i.(LogObjectMarshaler); ok {
|
||||||
|
return a.Object(obj)
|
||||||
|
}
|
||||||
|
a.buf = json.AppendInterface(append(a.buf, ','), i)
|
||||||
|
return a
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestArray(t *testing.T) {
|
||||||
|
a := Arr().
|
||||||
|
Bool(true).
|
||||||
|
Int(1).
|
||||||
|
Int8(2).
|
||||||
|
Int16(3).
|
||||||
|
Int32(4).
|
||||||
|
Int64(5).
|
||||||
|
Uint(6).
|
||||||
|
Uint8(7).
|
||||||
|
Uint16(8).
|
||||||
|
Uint32(9).
|
||||||
|
Uint64(10).
|
||||||
|
Float32(11).
|
||||||
|
Float64(12).
|
||||||
|
Str("a").
|
||||||
|
Time(time.Time{}).
|
||||||
|
Dur(0)
|
||||||
|
want := `[true,1,2,3,4,5,6,7,8,9,10,11,12,"a","0001-01-01T00:00:00Z",0]`
|
||||||
|
if got := string(a.write([]byte{})); got != want {
|
||||||
|
t.Errorf("Array.write()\ngot: %s\nwant: %s", got, want)
|
||||||
|
}
|
||||||
|
}
|
20
context.go
20
context.go
|
@ -31,6 +31,26 @@ func (c Context) Dict(key string, dict *Event) Context {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Array adds the field key with an array to the event context.
|
||||||
|
// Use zerolog.Arr() to create the array or pass a type that
|
||||||
|
// implement the LogArrayMarshaler interface.
|
||||||
|
func (c Context) Array(key string, arr LogArrayMarshaler) Context {
|
||||||
|
c.l.context = json.AppendKey(c.l.context, key)
|
||||||
|
if arr, ok := arr.(*Array); ok {
|
||||||
|
c.l.context = arr.write(c.l.context)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
var a *Array
|
||||||
|
if aa, ok := arr.(*Array); ok {
|
||||||
|
a = aa
|
||||||
|
} else {
|
||||||
|
a = Arr()
|
||||||
|
arr.MarshalZerologArray(a)
|
||||||
|
}
|
||||||
|
c.l.context = a.write(c.l.context)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// Object marshals an object that implement the LogObjectMarshaler interface.
|
// Object marshals an object that implement the LogObjectMarshaler interface.
|
||||||
func (c Context) Object(key string, obj LogObjectMarshaler) Context {
|
func (c Context) Object(key string, obj LogObjectMarshaler) Context {
|
||||||
e := newEvent(levelWriterAdapter{ioutil.Discard}, 0, true)
|
e := newEvent(levelWriterAdapter{ioutil.Discard}, 0, true)
|
||||||
|
|
32
event.go
32
event.go
|
@ -28,10 +28,18 @@ type Event struct {
|
||||||
done func(msg string)
|
done func(msg string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogObjectMarshaler provides a strongly-typed and encoding-agnostic interface
|
||||||
|
// to be implemented by types used with Event/Context's Object methods.
|
||||||
type LogObjectMarshaler interface {
|
type LogObjectMarshaler interface {
|
||||||
MarshalZerologObject(e *Event)
|
MarshalZerologObject(e *Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogArrayMarshaler provides a strongly-typed and encoding-agnostic interface
|
||||||
|
// to be implemented by types used with Event/Context's Array methods.
|
||||||
|
type LogArrayMarshaler interface {
|
||||||
|
MarshalZerologArray(a *Array)
|
||||||
|
}
|
||||||
|
|
||||||
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{}
|
||||||
|
@ -127,6 +135,25 @@ func Dict() *Event {
|
||||||
return newEvent(levelWriterAdapter{ioutil.Discard}, 0, true)
|
return newEvent(levelWriterAdapter{ioutil.Discard}, 0, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Array adds the field key with an array to the event context.
|
||||||
|
// Use zerolog.Arr() to create the array or pass a type that
|
||||||
|
// implement the LogArrayMarshaler interface.
|
||||||
|
func (e *Event) Array(key string, arr LogArrayMarshaler) *Event {
|
||||||
|
if !e.enabled {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = json.AppendKey(e.buf, key)
|
||||||
|
var a *Array
|
||||||
|
if aa, ok := arr.(*Array); ok {
|
||||||
|
a = aa
|
||||||
|
} else {
|
||||||
|
a = Arr()
|
||||||
|
arr.MarshalZerologArray(a)
|
||||||
|
}
|
||||||
|
e.buf = a.write(e.buf)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Event) appendObject(obj LogObjectMarshaler) {
|
func (e *Event) appendObject(obj LogObjectMarshaler) {
|
||||||
pos := len(e.buf)
|
pos := len(e.buf)
|
||||||
obj.MarshalZerologObject(e)
|
obj.MarshalZerologObject(e)
|
||||||
|
@ -143,6 +170,9 @@ func (e *Event) appendObject(obj LogObjectMarshaler) {
|
||||||
|
|
||||||
// Object marshals an object that implement the LogObjectMarshaler interface.
|
// Object marshals an object that implement the LogObjectMarshaler interface.
|
||||||
func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
|
func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
|
||||||
|
if !e.enabled {
|
||||||
|
return e
|
||||||
|
}
|
||||||
e.buf = json.AppendKey(e.buf, key)
|
e.buf = json.AppendKey(e.buf, key)
|
||||||
e.appendObject(obj)
|
e.appendObject(obj)
|
||||||
return e
|
return e
|
||||||
|
@ -166,7 +196,7 @@ func (e *Event) Strs(key string, vals []string) *Event {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes adds the field key with val as a []byte to the *Event context.
|
// Bytes adds the field key with val as a string to the *Event context.
|
||||||
func (e *Event) Bytes(key string, val []byte) *Event {
|
func (e *Event) Bytes(key string, val []byte) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
|
|
|
@ -150,9 +150,49 @@ func (u User) MarshalZerologObject(e *zerolog.Event) {
|
||||||
Time("created", u.Created)
|
Time("created", u.Created)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Users []User
|
||||||
|
|
||||||
|
func (uu Users) MarshalZerologArray(a *zerolog.Array) {
|
||||||
|
for _, u := range uu {
|
||||||
|
a.Object(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEvent_Array() {
|
||||||
|
log := zerolog.New(os.Stdout)
|
||||||
|
|
||||||
|
log.Log().
|
||||||
|
Str("foo", "bar").
|
||||||
|
Array("array", zerolog.Arr().
|
||||||
|
Str("baz").
|
||||||
|
Int(1),
|
||||||
|
).
|
||||||
|
Msg("hello world")
|
||||||
|
|
||||||
|
// Output: {"foo":"bar","array":["baz",1],"message":"hello world"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleEvent_Array_object() {
|
||||||
|
log := zerolog.New(os.Stdout)
|
||||||
|
|
||||||
|
// Users implements zerolog.LogArrayMarshaler
|
||||||
|
u := Users{
|
||||||
|
User{"John", 35, time.Time{}},
|
||||||
|
User{"Bob", 55, time.Time{}},
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Log().
|
||||||
|
Str("foo", "bar").
|
||||||
|
Array("users", u).
|
||||||
|
Msg("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"}
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleEvent_Object() {
|
func ExampleEvent_Object() {
|
||||||
log := zerolog.New(os.Stdout)
|
log := zerolog.New(os.Stdout)
|
||||||
|
|
||||||
|
// User implements zerolog.LogObjectMarshaler
|
||||||
u := User{"John", 35, time.Time{}}
|
u := User{"John", 35, time.Time{}}
|
||||||
|
|
||||||
log.Log().
|
log.Log().
|
||||||
|
@ -222,7 +262,38 @@ 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_Array() {
|
||||||
|
log := zerolog.New(os.Stdout).With().
|
||||||
|
Str("foo", "bar").
|
||||||
|
Array("array", zerolog.Arr().
|
||||||
|
Str("baz").
|
||||||
|
Int(1),
|
||||||
|
).Logger()
|
||||||
|
|
||||||
|
log.Log().Msg("hello world")
|
||||||
|
|
||||||
|
// Output: {"foo":"bar","array":["baz",1],"message":"hello world"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleContext_Array_object() {
|
||||||
|
// Users implements zerolog.LogArrayMarshaler
|
||||||
|
u := Users{
|
||||||
|
User{"John", 35, time.Time{}},
|
||||||
|
User{"Bob", 55, time.Time{}},
|
||||||
|
}
|
||||||
|
|
||||||
|
log := zerolog.New(os.Stdout).With().
|
||||||
|
Str("foo", "bar").
|
||||||
|
Array("users", u).
|
||||||
|
Logger()
|
||||||
|
|
||||||
|
log.Log().Msg("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"}
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleContext_Object() {
|
func ExampleContext_Object() {
|
||||||
|
// User implements zerolog.LogObjectMarshaler
|
||||||
u := User{"John", 35, time.Time{}}
|
u := User{"John", 35, time.Time{}}
|
||||||
|
|
||||||
log := zerolog.New(os.Stdout).With().
|
log := zerolog.New(os.Stdout).With().
|
||||||
|
|
Loading…
Reference in New Issue