Refactor JSON encoding code
This commit is contained in:
parent
fdbdb09630
commit
6cdd9977c4
|
@ -102,7 +102,34 @@ func BenchmarkLogFieldType(b *testing.B) {
|
||||||
time.Unix(8, 0),
|
time.Unix(8, 0),
|
||||||
time.Unix(9, 0),
|
time.Unix(9, 0),
|
||||||
}
|
}
|
||||||
o := obj{"a", "a", 0}
|
interfaces := []struct {
|
||||||
|
Pub string
|
||||||
|
Tag string `json:"tag"`
|
||||||
|
priv int
|
||||||
|
}{
|
||||||
|
{"a", "a", 0},
|
||||||
|
{"a", "a", 0},
|
||||||
|
{"a", "a", 0},
|
||||||
|
{"a", "a", 0},
|
||||||
|
{"a", "a", 0},
|
||||||
|
{"a", "a", 0},
|
||||||
|
{"a", "a", 0},
|
||||||
|
{"a", "a", 0},
|
||||||
|
{"a", "a", 0},
|
||||||
|
{"a", "a", 0},
|
||||||
|
}
|
||||||
|
objects := []obj{
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
obj{"a", "a", 0},
|
||||||
|
}
|
||||||
errs := []error{errors.New("a"), errors.New("b"), errors.New("c"), errors.New("d"), errors.New("e")}
|
errs := []error{errors.New("a"), errors.New("b"), errors.New("c"), errors.New("d"), errors.New("e")}
|
||||||
types := map[string]func(e *Event) *Event{
|
types := map[string]func(e *Event) *Event{
|
||||||
"Bool": func(e *Event) *Event {
|
"Bool": func(e *Event) *Event {
|
||||||
|
@ -148,10 +175,19 @@ func BenchmarkLogFieldType(b *testing.B) {
|
||||||
return e.Durs("k", durations)
|
return e.Durs("k", durations)
|
||||||
},
|
},
|
||||||
"Interface": func(e *Event) *Event {
|
"Interface": func(e *Event) *Event {
|
||||||
return e.Interface("k", o)
|
return e.Interface("k", interfaces[0])
|
||||||
|
},
|
||||||
|
"Interfaces": func(e *Event) *Event {
|
||||||
|
return e.Interface("k", interfaces)
|
||||||
|
},
|
||||||
|
"Interface(Object)": func(e *Event) *Event {
|
||||||
|
return e.Interface("k", objects[0])
|
||||||
|
},
|
||||||
|
"Interface(Objects)": func(e *Event) *Event {
|
||||||
|
return e.Interface("k", objects)
|
||||||
},
|
},
|
||||||
"Object": func(e *Event) *Event {
|
"Object": func(e *Event) *Event {
|
||||||
return e.Object("k", o)
|
return e.Object("k", objects[0])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
logger := New(ioutil.Discard)
|
logger := New(ioutil.Discard)
|
||||||
|
|
82
context.go
82
context.go
|
@ -3,6 +3,8 @@ package zerolog
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/internal/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Context configures a new sub-logger with contextual fields.
|
// Context configures a new sub-logger with contextual fields.
|
||||||
|
@ -24,7 +26,7 @@ func (c Context) Fields(fields map[string]interface{}) Context {
|
||||||
// Dict adds the field key with the dict to the logger context.
|
// Dict adds the field key with the dict to the logger context.
|
||||||
func (c Context) Dict(key string, dict *Event) Context {
|
func (c Context) Dict(key string, dict *Event) Context {
|
||||||
dict.buf = append(dict.buf, '}')
|
dict.buf = append(dict.buf, '}')
|
||||||
c.l.context = append(appendKey(c.l.context, key), dict.buf...)
|
c.l.context = append(json.AppendKey(c.l.context, key), dict.buf...)
|
||||||
eventPool.Put(dict)
|
eventPool.Put(dict)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
@ -41,194 +43,198 @@ func (c Context) Object(key string, obj LogObjectMarshaler) Context {
|
||||||
|
|
||||||
// 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 = json.AppendString(json.AppendKey(c.l.context, key), val)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strs adds the field key with val as a string to the logger context.
|
// Strs adds the field key with val as a string to the logger context.
|
||||||
func (c Context) Strs(key string, vals []string) Context {
|
func (c Context) Strs(key string, vals []string) Context {
|
||||||
c.l.context = appendStrings(c.l.context, key, vals)
|
c.l.context = json.AppendStrings(json.AppendKey(c.l.context, key), vals)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes adds the field key with val as a []byte to the logger context.
|
// Bytes adds the field key with val as a []byte to the logger context.
|
||||||
func (c Context) Bytes(key string, val []byte) Context {
|
func (c Context) Bytes(key string, val []byte) Context {
|
||||||
c.l.context = appendBytes(c.l.context, key, val)
|
c.l.context = json.AppendBytes(json.AppendKey(c.l.context, key), val)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnErr adds the field key with err as a string to the logger context.
|
// AnErr adds the field key with err as a string to the logger context.
|
||||||
func (c Context) AnErr(key string, err error) Context {
|
func (c Context) AnErr(key string, err error) Context {
|
||||||
c.l.context = appendErrorKey(c.l.context, key, err)
|
if err != nil {
|
||||||
|
c.l.context = json.AppendError(json.AppendKey(c.l.context, key), err)
|
||||||
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errs adds the field key with errs as an array of strings to the logger context.
|
// Errs adds the field key with errs as an array of strings to the logger context.
|
||||||
func (c Context) Errs(key string, errs []error) Context {
|
func (c Context) Errs(key string, errs []error) Context {
|
||||||
c.l.context = appendErrorsKey(c.l.context, key, errs)
|
c.l.context = json.AppendErrors(json.AppendKey(c.l.context, key), errs)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Err adds the field "error" with err as a string to the logger context.
|
// Err adds the field "error" with err as a string to the logger context.
|
||||||
// To customize the key name, change zerolog.ErrorFieldName.
|
// To customize the key name, change zerolog.ErrorFieldName.
|
||||||
func (c Context) Err(err error) Context {
|
func (c Context) Err(err error) Context {
|
||||||
c.l.context = appendError(c.l.context, err)
|
if err != nil {
|
||||||
|
c.l.context = json.AppendError(json.AppendKey(c.l.context, ErrorFieldName), err)
|
||||||
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool adds the field key with val as a bool to the logger context.
|
// Bool adds the field key with val as a bool to the logger context.
|
||||||
func (c Context) Bool(key string, b bool) Context {
|
func (c Context) Bool(key string, b bool) Context {
|
||||||
c.l.context = appendBool(c.l.context, key, b)
|
c.l.context = json.AppendBool(json.AppendKey(c.l.context, key), b)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bools adds the field key with val as a []bool to the logger context.
|
// Bools adds the field key with val as a []bool to the logger context.
|
||||||
func (c Context) Bools(key string, b []bool) Context {
|
func (c Context) Bools(key string, b []bool) Context {
|
||||||
c.l.context = appendBools(c.l.context, key, b)
|
c.l.context = json.AppendBools(json.AppendKey(c.l.context, key), b)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int adds the field key with i as a int to the logger context.
|
// Int adds the field key with i as a int to the logger context.
|
||||||
func (c Context) Int(key string, i int) Context {
|
func (c Context) Int(key string, i int) Context {
|
||||||
c.l.context = appendInt(c.l.context, key, i)
|
c.l.context = json.AppendInt(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ints adds the field key with i as a []int to the logger context.
|
// Ints adds the field key with i as a []int to the logger context.
|
||||||
func (c Context) Ints(key string, i []int) Context {
|
func (c Context) Ints(key string, i []int) Context {
|
||||||
c.l.context = appendInts(c.l.context, key, i)
|
c.l.context = json.AppendInts(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int8 adds the field key with i as a int8 to the logger context.
|
// Int8 adds the field key with i as a int8 to the logger context.
|
||||||
func (c Context) Int8(key string, i int8) Context {
|
func (c Context) Int8(key string, i int8) Context {
|
||||||
c.l.context = appendInt8(c.l.context, key, i)
|
c.l.context = json.AppendInt8(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ints8 adds the field key with i as a []int8 to the logger context.
|
// Ints8 adds the field key with i as a []int8 to the logger context.
|
||||||
func (c Context) Ints8(key string, i []int8) Context {
|
func (c Context) Ints8(key string, i []int8) Context {
|
||||||
c.l.context = appendInts8(c.l.context, key, i)
|
c.l.context = json.AppendInts8(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int16 adds the field key with i as a int16 to the logger context.
|
// Int16 adds the field key with i as a int16 to the logger context.
|
||||||
func (c Context) Int16(key string, i int16) Context {
|
func (c Context) Int16(key string, i int16) Context {
|
||||||
c.l.context = appendInt16(c.l.context, key, i)
|
c.l.context = json.AppendInt16(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ints16 adds the field key with i as a []int16 to the logger context.
|
// Ints16 adds the field key with i as a []int16 to the logger context.
|
||||||
func (c Context) Ints16(key string, i []int16) Context {
|
func (c Context) Ints16(key string, i []int16) Context {
|
||||||
c.l.context = appendInts16(c.l.context, key, i)
|
c.l.context = json.AppendInts16(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int32 adds the field key with i as a int32 to the logger context.
|
// Int32 adds the field key with i as a int32 to the logger context.
|
||||||
func (c Context) Int32(key string, i int32) Context {
|
func (c Context) Int32(key string, i int32) Context {
|
||||||
c.l.context = appendInt32(c.l.context, key, i)
|
c.l.context = json.AppendInt32(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ints32 adds the field key with i as a []int32 to the logger context.
|
// Ints32 adds the field key with i as a []int32 to the logger context.
|
||||||
func (c Context) Ints32(key string, i []int32) Context {
|
func (c Context) Ints32(key string, i []int32) Context {
|
||||||
c.l.context = appendInts32(c.l.context, key, i)
|
c.l.context = json.AppendInts32(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int64 adds the field key with i as a int64 to the logger context.
|
// Int64 adds the field key with i as a int64 to the logger context.
|
||||||
func (c Context) Int64(key string, i int64) Context {
|
func (c Context) Int64(key string, i int64) Context {
|
||||||
c.l.context = appendInt64(c.l.context, key, i)
|
c.l.context = json.AppendInt64(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ints64 adds the field key with i as a []int64 to the logger context.
|
// Ints64 adds the field key with i as a []int64 to the logger context.
|
||||||
func (c Context) Ints64(key string, i []int64) Context {
|
func (c Context) Ints64(key string, i []int64) Context {
|
||||||
c.l.context = appendInts64(c.l.context, key, i)
|
c.l.context = json.AppendInts64(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint adds the field key with i as a uint to the logger context.
|
// Uint adds the field key with i as a uint to the logger context.
|
||||||
func (c Context) Uint(key string, i uint) Context {
|
func (c Context) Uint(key string, i uint) Context {
|
||||||
c.l.context = appendUint(c.l.context, key, i)
|
c.l.context = json.AppendUint(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uints adds the field key with i as a []uint to the logger context.
|
// Uints adds the field key with i as a []uint to the logger context.
|
||||||
func (c Context) Uints(key string, i []uint) Context {
|
func (c Context) Uints(key string, i []uint) Context {
|
||||||
c.l.context = appendUints(c.l.context, key, i)
|
c.l.context = json.AppendUints(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint8 adds the field key with i as a uint8 to the logger context.
|
// Uint8 adds the field key with i as a uint8 to the logger context.
|
||||||
func (c Context) Uint8(key string, i uint8) Context {
|
func (c Context) Uint8(key string, i uint8) Context {
|
||||||
c.l.context = appendUint8(c.l.context, key, i)
|
c.l.context = json.AppendUint8(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uints8 adds the field key with i as a []uint8 to the logger context.
|
// Uints8 adds the field key with i as a []uint8 to the logger context.
|
||||||
func (c Context) Uints8(key string, i []uint8) Context {
|
func (c Context) Uints8(key string, i []uint8) Context {
|
||||||
c.l.context = appendUints8(c.l.context, key, i)
|
c.l.context = json.AppendUints8(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint16 adds the field key with i as a uint16 to the logger context.
|
// Uint16 adds the field key with i as a uint16 to the logger context.
|
||||||
func (c Context) Uint16(key string, i uint16) Context {
|
func (c Context) Uint16(key string, i uint16) Context {
|
||||||
c.l.context = appendUint16(c.l.context, key, i)
|
c.l.context = json.AppendUint16(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uints16 adds the field key with i as a []uint16 to the logger context.
|
// Uints16 adds the field key with i as a []uint16 to the logger context.
|
||||||
func (c Context) Uints16(key string, i []uint16) Context {
|
func (c Context) Uints16(key string, i []uint16) Context {
|
||||||
c.l.context = appendUints16(c.l.context, key, i)
|
c.l.context = json.AppendUints16(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint32 adds the field key with i as a uint32 to the logger context.
|
// Uint32 adds the field key with i as a uint32 to the logger context.
|
||||||
func (c Context) Uint32(key string, i uint32) Context {
|
func (c Context) Uint32(key string, i uint32) Context {
|
||||||
c.l.context = appendUint32(c.l.context, key, i)
|
c.l.context = json.AppendUint32(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uints32 adds the field key with i as a []uint32 to the logger context.
|
// Uints32 adds the field key with i as a []uint32 to the logger context.
|
||||||
func (c Context) Uints32(key string, i []uint32) Context {
|
func (c Context) Uints32(key string, i []uint32) Context {
|
||||||
c.l.context = appendUints32(c.l.context, key, i)
|
c.l.context = json.AppendUints32(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64 adds the field key with i as a uint64 to the logger context.
|
// Uint64 adds the field key with i as a uint64 to the logger context.
|
||||||
func (c Context) Uint64(key string, i uint64) Context {
|
func (c Context) Uint64(key string, i uint64) Context {
|
||||||
c.l.context = appendUint64(c.l.context, key, i)
|
c.l.context = json.AppendUint64(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uints64 adds the field key with i as a []uint64 to the logger context.
|
// Uints64 adds the field key with i as a []uint64 to the logger context.
|
||||||
func (c Context) Uints64(key string, i []uint64) Context {
|
func (c Context) Uints64(key string, i []uint64) Context {
|
||||||
c.l.context = appendUints64(c.l.context, key, i)
|
c.l.context = json.AppendUints64(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Float32 adds the field key with f as a float32 to the logger context.
|
// Float32 adds the field key with f as a float32 to the logger context.
|
||||||
func (c Context) Float32(key string, f float32) Context {
|
func (c Context) Float32(key string, f float32) Context {
|
||||||
c.l.context = appendFloat32(c.l.context, key, f)
|
c.l.context = json.AppendFloat32(json.AppendKey(c.l.context, key), f)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Floats32 adds the field key with f as a []float32 to the logger context.
|
// Floats32 adds the field key with f as a []float32 to the logger context.
|
||||||
func (c Context) Floats32(key string, f []float32) Context {
|
func (c Context) Floats32(key string, f []float32) Context {
|
||||||
c.l.context = appendFloats32(c.l.context, key, f)
|
c.l.context = json.AppendFloats32(json.AppendKey(c.l.context, key), f)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Float64 adds the field key with f as a float64 to the logger context.
|
// Float64 adds the field key with f as a float64 to the logger context.
|
||||||
func (c Context) Float64(key string, f float64) Context {
|
func (c Context) Float64(key string, f float64) Context {
|
||||||
c.l.context = appendFloat64(c.l.context, key, f)
|
c.l.context = json.AppendFloat64(json.AppendKey(c.l.context, key), f)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Floats64 adds the field key with f as a []float64 to the logger context.
|
// Floats64 adds the field key with f as a []float64 to the logger context.
|
||||||
func (c Context) Floats64(key string, f []float64) Context {
|
func (c Context) Floats64(key string, f []float64) Context {
|
||||||
c.l.context = appendFloats64(c.l.context, key, f)
|
c.l.context = json.AppendFloats64(json.AppendKey(c.l.context, key), f)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,30 +251,30 @@ func (c Context) Timestamp() Context {
|
||||||
|
|
||||||
// Time adds the field key with t formated as string using zerolog.TimeFieldFormat.
|
// Time adds the field key with t formated as string using zerolog.TimeFieldFormat.
|
||||||
func (c Context) Time(key string, t time.Time) Context {
|
func (c Context) Time(key string, t time.Time) Context {
|
||||||
c.l.context = appendTime(c.l.context, key, t)
|
c.l.context = json.AppendTime(json.AppendKey(c.l.context, key), t, TimeFieldFormat)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Times adds the field key with t formated as string using zerolog.TimeFieldFormat.
|
// Times adds the field key with t formated as string using zerolog.TimeFieldFormat.
|
||||||
func (c Context) Times(key string, t []time.Time) Context {
|
func (c Context) Times(key string, t []time.Time) Context {
|
||||||
c.l.context = appendTimes(c.l.context, key, t)
|
c.l.context = json.AppendTimes(json.AppendKey(c.l.context, key), t, TimeFieldFormat)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dur adds the fields key with d divided by unit and stored as a float.
|
// Dur adds the fields key with d divided by unit and stored as a float.
|
||||||
func (c Context) Dur(key string, d time.Duration) Context {
|
func (c Context) Dur(key string, d time.Duration) Context {
|
||||||
c.l.context = appendDuration(c.l.context, key, d)
|
c.l.context = json.AppendDuration(json.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Durs adds the fields key with d divided by unit and stored as a float.
|
// Durs adds the fields key with d divided by unit and stored as a float.
|
||||||
func (c Context) Durs(key string, d []time.Duration) Context {
|
func (c Context) Durs(key string, d []time.Duration) Context {
|
||||||
c.l.context = appendDurations(c.l.context, key, d)
|
c.l.context = json.AppendDurations(json.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface adds the field key with obj marshaled using reflection.
|
// Interface adds the field key with obj marshaled using reflection.
|
||||||
func (c Context) Interface(key string, i interface{}) Context {
|
func (c Context) Interface(key string, i interface{}) Context {
|
||||||
c.l.context = appendInterface(c.l.context, key, i)
|
c.l.context = json.AppendInterface(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
103
event.go
103
event.go
|
@ -6,6 +6,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/internal/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
var eventPool = &sync.Pool{
|
var eventPool = &sync.Pool{
|
||||||
|
@ -68,7 +70,7 @@ func (e *Event) Msg(msg string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
e.buf = appendString(e.buf, MessageFieldName, msg)
|
e.buf = json.AppendString(json.AppendKey(e.buf, MessageFieldName), msg)
|
||||||
}
|
}
|
||||||
if e.done != nil {
|
if e.done != nil {
|
||||||
defer e.done(msg)
|
defer e.done(msg)
|
||||||
|
@ -88,7 +90,7 @@ func (e *Event) Msgf(format string, v ...interface{}) {
|
||||||
}
|
}
|
||||||
msg := fmt.Sprintf(format, v...)
|
msg := fmt.Sprintf(format, v...)
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
e.buf = appendString(e.buf, MessageFieldName, msg)
|
e.buf = json.AppendString(json.AppendKey(e.buf, MessageFieldName), msg)
|
||||||
}
|
}
|
||||||
if e.done != nil {
|
if e.done != nil {
|
||||||
defer e.done(msg)
|
defer e.done(msg)
|
||||||
|
@ -113,7 +115,7 @@ func (e *Event) Dict(key string, dict *Event) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = append(append(appendKey(e.buf, key), dict.buf...), '}')
|
e.buf = append(append(json.AppendKey(e.buf, key), dict.buf...), '}')
|
||||||
eventPool.Put(dict)
|
eventPool.Put(dict)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -125,9 +127,7 @@ 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) appendObject(obj LogObjectMarshaler) {
|
||||||
func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
|
|
||||||
e.buf = appendKey(e.buf, key)
|
|
||||||
pos := len(e.buf)
|
pos := len(e.buf)
|
||||||
obj.MarshalZerologObject(e)
|
obj.MarshalZerologObject(e)
|
||||||
if pos < len(e.buf) {
|
if pos < len(e.buf) {
|
||||||
|
@ -139,6 +139,12 @@ func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
|
||||||
e.buf = append(e.buf, '{')
|
e.buf = append(e.buf, '{')
|
||||||
}
|
}
|
||||||
e.buf = append(e.buf, '}')
|
e.buf = append(e.buf, '}')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object marshals an object that implement the LogObjectMarshaler interface.
|
||||||
|
func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
|
||||||
|
e.buf = json.AppendKey(e.buf, key)
|
||||||
|
e.appendObject(obj)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +153,7 @@ func (e *Event) Str(key, val string) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendString(e.buf, key, val)
|
e.buf = json.AppendString(json.AppendKey(e.buf, key), val)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +162,7 @@ func (e *Event) Strs(key string, vals []string) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendStrings(e.buf, key, vals)
|
e.buf = json.AppendStrings(json.AppendKey(e.buf, key), vals)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +171,7 @@ func (e *Event) Bytes(key string, val []byte) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendBytes(e.buf, key, val)
|
e.buf = json.AppendBytes(json.AppendKey(e.buf, key), val)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +181,9 @@ func (e *Event) AnErr(key string, err error) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendErrorKey(e.buf, key, err)
|
if err != nil {
|
||||||
|
e.buf = json.AppendError(json.AppendKey(e.buf, key), err)
|
||||||
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +193,7 @@ func (e *Event) Errs(key string, errs []error) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendErrorsKey(e.buf, key, errs)
|
e.buf = json.AppendErrors(json.AppendKey(e.buf, key), errs)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +204,9 @@ func (e *Event) Err(err error) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendError(e.buf, err)
|
if err != nil {
|
||||||
|
e.buf = json.AppendError(json.AppendKey(e.buf, ErrorFieldName), err)
|
||||||
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +215,7 @@ func (e *Event) Bool(key string, b bool) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendBool(e.buf, key, b)
|
e.buf = json.AppendBool(json.AppendKey(e.buf, key), b)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +224,7 @@ func (e *Event) Bools(key string, b []bool) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendBools(e.buf, key, b)
|
e.buf = json.AppendBools(json.AppendKey(e.buf, key), b)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +233,7 @@ func (e *Event) Int(key string, i int) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInt(e.buf, key, i)
|
e.buf = json.AppendInt(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +242,7 @@ func (e *Event) Ints(key string, i []int) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInts(e.buf, key, i)
|
e.buf = json.AppendInts(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +251,7 @@ func (e *Event) Int8(key string, i int8) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInt8(e.buf, key, i)
|
e.buf = json.AppendInt8(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +260,7 @@ func (e *Event) Ints8(key string, i []int8) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInts8(e.buf, key, i)
|
e.buf = json.AppendInts8(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +269,7 @@ func (e *Event) Int16(key string, i int16) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInt16(e.buf, key, i)
|
e.buf = json.AppendInt16(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +278,7 @@ func (e *Event) Ints16(key string, i []int16) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInts16(e.buf, key, i)
|
e.buf = json.AppendInts16(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +287,7 @@ func (e *Event) Int32(key string, i int32) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInt32(e.buf, key, i)
|
e.buf = json.AppendInt32(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +296,7 @@ func (e *Event) Ints32(key string, i []int32) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInts32(e.buf, key, i)
|
e.buf = json.AppendInts32(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +305,7 @@ func (e *Event) Int64(key string, i int64) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInt64(e.buf, key, i)
|
e.buf = json.AppendInt64(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +314,7 @@ func (e *Event) Ints64(key string, i []int64) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInts64(e.buf, key, i)
|
e.buf = json.AppendInts64(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +323,7 @@ func (e *Event) Uint(key string, i uint) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUint(e.buf, key, i)
|
e.buf = json.AppendUint(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +332,7 @@ func (e *Event) Uints(key string, i []uint) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUints(e.buf, key, i)
|
e.buf = json.AppendUints(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +341,7 @@ func (e *Event) Uint8(key string, i uint8) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUint8(e.buf, key, i)
|
e.buf = json.AppendUint8(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +350,7 @@ func (e *Event) Uints8(key string, i []uint8) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUints8(e.buf, key, i)
|
e.buf = json.AppendUints8(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +359,7 @@ func (e *Event) Uint16(key string, i uint16) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUint16(e.buf, key, i)
|
e.buf = json.AppendUint16(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +368,7 @@ func (e *Event) Uints16(key string, i []uint16) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUints16(e.buf, key, i)
|
e.buf = json.AppendUints16(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +377,7 @@ func (e *Event) Uint32(key string, i uint32) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUint32(e.buf, key, i)
|
e.buf = json.AppendUint32(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +386,7 @@ func (e *Event) Uints32(key string, i []uint32) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUints32(e.buf, key, i)
|
e.buf = json.AppendUints32(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +395,7 @@ func (e *Event) Uint64(key string, i uint64) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUint64(e.buf, key, i)
|
e.buf = json.AppendUint64(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +404,7 @@ func (e *Event) Uints64(key string, i []uint64) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendUints64(e.buf, key, i)
|
e.buf = json.AppendUints64(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +413,7 @@ func (e *Event) Float32(key string, f float32) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendFloat32(e.buf, key, f)
|
e.buf = json.AppendFloat32(json.AppendKey(e.buf, key), f)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,7 +422,7 @@ func (e *Event) Floats32(key string, f []float32) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendFloats32(e.buf, key, f)
|
e.buf = json.AppendFloats32(json.AppendKey(e.buf, key), f)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +431,7 @@ func (e *Event) Float64(key string, f float64) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendFloat64(e.buf, key, f)
|
e.buf = json.AppendFloat64(json.AppendKey(e.buf, key), f)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +440,7 @@ func (e *Event) Floats64(key string, f []float64) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendFloats64(e.buf, key, f)
|
e.buf = json.AppendFloats64(json.AppendKey(e.buf, key), f)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,7 +450,7 @@ func (e *Event) Timestamp() *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendTimestamp(e.buf)
|
e.buf = json.AppendTime(json.AppendKey(e.buf, TimestampFieldName), TimestampFunc(), TimeFieldFormat)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,7 +459,7 @@ func (e *Event) Time(key string, t time.Time) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendTime(e.buf, key, t)
|
e.buf = json.AppendTime(json.AppendKey(e.buf, key), t, TimeFieldFormat)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,7 +468,7 @@ func (e *Event) Times(key string, t []time.Time) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendTimes(e.buf, key, t)
|
e.buf = json.AppendTimes(json.AppendKey(e.buf, key), t, TimeFieldFormat)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,7 +479,7 @@ func (e *Event) Dur(key string, d time.Duration) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendDuration(e.buf, key, d)
|
e.buf = json.AppendDuration(json.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +490,7 @@ func (e *Event) Durs(key string, d []time.Duration) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendDurations(e.buf, key, d)
|
e.buf = json.AppendDurations(json.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,7 +505,7 @@ func (e *Event) TimeDiff(key string, t time.Time, start time.Time) *Event {
|
||||||
if t.After(start) {
|
if t.After(start) {
|
||||||
d = t.Sub(start)
|
d = t.Sub(start)
|
||||||
}
|
}
|
||||||
e.buf = appendDuration(e.buf, key, d)
|
e.buf = json.AppendDuration(json.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,6 +514,9 @@ func (e *Event) Interface(key string, i interface{}) *Event {
|
||||||
if !e.enabled {
|
if !e.enabled {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = appendInterface(e.buf, key, i)
|
if obj, ok := i.(LogObjectMarshaler); ok {
|
||||||
|
return e.Object(key, obj)
|
||||||
|
}
|
||||||
|
e.buf = json.AppendInterface(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
519
field.go
519
field.go
|
@ -1,519 +0,0 @@
|
||||||
package zerolog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"math"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func appendFields(dst []byte, fields map[string]interface{}) []byte {
|
|
||||||
keys := make([]string, 0, len(fields))
|
|
||||||
for key, _ := range fields {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
sort.Strings(keys)
|
|
||||||
for _, key := range keys {
|
|
||||||
switch val := fields[key].(type) {
|
|
||||||
case string:
|
|
||||||
dst = appendString(dst, key, val)
|
|
||||||
case []byte:
|
|
||||||
dst = appendBytes(dst, key, val)
|
|
||||||
case error:
|
|
||||||
dst = appendErrorKey(dst, key, val)
|
|
||||||
case []error:
|
|
||||||
dst = appendErrorsKey(dst, key, val)
|
|
||||||
case bool:
|
|
||||||
dst = appendBool(dst, key, val)
|
|
||||||
case int:
|
|
||||||
dst = appendInt(dst, key, val)
|
|
||||||
case int8:
|
|
||||||
dst = appendInt8(dst, key, val)
|
|
||||||
case int16:
|
|
||||||
dst = appendInt16(dst, key, val)
|
|
||||||
case int32:
|
|
||||||
dst = appendInt32(dst, key, val)
|
|
||||||
case int64:
|
|
||||||
dst = appendInt64(dst, key, val)
|
|
||||||
case uint:
|
|
||||||
dst = appendUint(dst, key, val)
|
|
||||||
case uint8:
|
|
||||||
dst = appendUint8(dst, key, val)
|
|
||||||
case uint16:
|
|
||||||
dst = appendUint16(dst, key, val)
|
|
||||||
case uint32:
|
|
||||||
dst = appendUint32(dst, key, val)
|
|
||||||
case uint64:
|
|
||||||
dst = appendUint64(dst, key, val)
|
|
||||||
case float32:
|
|
||||||
dst = appendFloat32(dst, key, val)
|
|
||||||
case float64:
|
|
||||||
dst = appendFloat64(dst, key, val)
|
|
||||||
case time.Time:
|
|
||||||
dst = appendTime(dst, key, val)
|
|
||||||
case time.Duration:
|
|
||||||
dst = appendDuration(dst, key, val)
|
|
||||||
case []string:
|
|
||||||
dst = appendStrings(dst, key, val)
|
|
||||||
case []bool:
|
|
||||||
dst = appendBools(dst, key, val)
|
|
||||||
case []int:
|
|
||||||
dst = appendInts(dst, key, val)
|
|
||||||
case []int8:
|
|
||||||
dst = appendInts8(dst, key, val)
|
|
||||||
case []int16:
|
|
||||||
dst = appendInts16(dst, key, val)
|
|
||||||
case []int32:
|
|
||||||
dst = appendInts32(dst, key, val)
|
|
||||||
case []int64:
|
|
||||||
dst = appendInts64(dst, key, val)
|
|
||||||
case []uint:
|
|
||||||
dst = appendUints(dst, key, val)
|
|
||||||
// case []uint8:
|
|
||||||
// dst = appendUints8(dst, key, val)
|
|
||||||
case []uint16:
|
|
||||||
dst = appendUints16(dst, key, val)
|
|
||||||
case []uint32:
|
|
||||||
dst = appendUints32(dst, key, val)
|
|
||||||
case []uint64:
|
|
||||||
dst = appendUints64(dst, key, val)
|
|
||||||
case []float32:
|
|
||||||
dst = appendFloats32(dst, key, val)
|
|
||||||
case []float64:
|
|
||||||
dst = appendFloats64(dst, key, val)
|
|
||||||
case []time.Time:
|
|
||||||
dst = appendTimes(dst, key, val)
|
|
||||||
case []time.Duration:
|
|
||||||
dst = appendDurations(dst, key, val)
|
|
||||||
case nil:
|
|
||||||
dst = append(appendKey(dst, key), "null"...)
|
|
||||||
default:
|
|
||||||
dst = appendInterface(dst, key, val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendKey(dst []byte, key string) []byte {
|
|
||||||
if len(dst) > 1 {
|
|
||||||
dst = append(dst, ',')
|
|
||||||
}
|
|
||||||
dst = appendJSONString(dst, key)
|
|
||||||
return append(dst, ':')
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendString(dst []byte, key, val string) []byte {
|
|
||||||
return appendJSONString(appendKey(dst, key), val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendStrings(dst []byte, key string, vals []string) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = appendJSONString(dst, vals[0])
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = appendJSONString(append(dst, ','), val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendBytes(dst []byte, key string, val []byte) []byte {
|
|
||||||
return appendJSONBytes(appendKey(dst, key), val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendErrorKey(dst []byte, key string, err error) []byte {
|
|
||||||
if err == nil {
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
return appendJSONString(appendKey(dst, key), err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendErrorsKey(dst []byte, key string, errs []error) []byte {
|
|
||||||
if len(errs) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
if errs[0] != nil {
|
|
||||||
dst = appendJSONString(dst, errs[0].Error())
|
|
||||||
} else {
|
|
||||||
dst = append(dst, "null"...)
|
|
||||||
}
|
|
||||||
if len(errs) > 1 {
|
|
||||||
for _, err := range errs[1:] {
|
|
||||||
if err == nil {
|
|
||||||
dst = append(dst, ",null"...)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
dst = appendJSONString(append(dst, ','), err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendError(dst []byte, err error) []byte {
|
|
||||||
if err == nil {
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
return appendErrorKey(dst, ErrorFieldName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendBool(dst []byte, key string, val bool) []byte {
|
|
||||||
return strconv.AppendBool(appendKey(dst, key), val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendBools(dst []byte, key string, vals []bool) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendBool(dst, vals[0])
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendBool(append(dst, ','), val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInt(dst []byte, key string, val int) []byte {
|
|
||||||
return strconv.AppendInt(appendKey(dst, key), int64(val), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInts(dst []byte, key string, vals []int) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInt8(dst []byte, key string, val int8) []byte {
|
|
||||||
return strconv.AppendInt(appendKey(dst, key), int64(val), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInts8(dst []byte, key string, vals []int8) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInt16(dst []byte, key string, val int16) []byte {
|
|
||||||
return strconv.AppendInt(appendKey(dst, key), int64(val), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInts16(dst []byte, key string, vals []int16) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInt32(dst []byte, key string, val int32) []byte {
|
|
||||||
return strconv.AppendInt(appendKey(dst, key), int64(val), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInts32(dst []byte, key string, vals []int32) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInt64(dst []byte, key string, val int64) []byte {
|
|
||||||
return strconv.AppendInt(appendKey(dst, key), val, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInts64(dst []byte, key string, vals []int64) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendInt(dst, vals[0], 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendInt(append(dst, ','), val, 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUint(dst []byte, key string, val uint) []byte {
|
|
||||||
return strconv.AppendUint(appendKey(dst, key), uint64(val), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUints(dst []byte, key string, vals []uint) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUint8(dst []byte, key string, val uint8) []byte {
|
|
||||||
return strconv.AppendUint(appendKey(dst, key), uint64(val), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUints8(dst []byte, key string, vals []uint8) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUint16(dst []byte, key string, val uint16) []byte {
|
|
||||||
return strconv.AppendUint(appendKey(dst, key), uint64(val), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUints16(dst []byte, key string, vals []uint16) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUint32(dst []byte, key string, val uint32) []byte {
|
|
||||||
return strconv.AppendUint(appendKey(dst, key), uint64(val), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUints32(dst []byte, key string, vals []uint32) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUint64(dst []byte, key string, val uint64) []byte {
|
|
||||||
return strconv.AppendUint(appendKey(dst, key), uint64(val), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUints64(dst []byte, key string, vals []uint64) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendUint(dst, vals[0], 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = strconv.AppendUint(append(dst, ','), val, 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendFloat(dst []byte, val float64, bitSize int) []byte {
|
|
||||||
// JSON does not permit NaN or Infinity. A typical JSON encoder would fail
|
|
||||||
// with an error, but a logging library wants the data to get thru so we
|
|
||||||
// make a tradeoff and store those types as string.
|
|
||||||
switch {
|
|
||||||
case math.IsNaN(val):
|
|
||||||
return append(dst, `"NaN"`...)
|
|
||||||
case math.IsInf(val, 1):
|
|
||||||
return append(dst, `"+Inf"`...)
|
|
||||||
case math.IsInf(val, -1):
|
|
||||||
return append(dst, `"-Inf"`...)
|
|
||||||
}
|
|
||||||
return strconv.AppendFloat(dst, val, 'f', -1, bitSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendFloat32(dst []byte, key string, val float32) []byte {
|
|
||||||
return appendFloat(appendKey(dst, key), float64(val), 32)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendFloats32(dst []byte, key string, vals []float32) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = appendFloat(dst, float64(vals[0]), 32)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = appendFloat(append(dst, ','), float64(val), 32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendFloat64(dst []byte, key string, val float64) []byte {
|
|
||||||
return appendFloat(appendKey(dst, key), val, 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendFloats64(dst []byte, key string, vals []float64) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = appendFloat(dst, vals[0], 32)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, val := range vals[1:] {
|
|
||||||
dst = appendFloat(append(dst, ','), val, 64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendTime(dst []byte, key string, t time.Time) []byte {
|
|
||||||
if TimeFieldFormat == "" {
|
|
||||||
return appendInt64(dst, key, t.Unix())
|
|
||||||
}
|
|
||||||
return append(t.AppendFormat(append(appendKey(dst, key), '"'), TimeFieldFormat), '"')
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendTimes(dst []byte, key string, vals []time.Time) []byte {
|
|
||||||
if TimeFieldFormat == "" {
|
|
||||||
return appendUnixTimes(dst, key, vals)
|
|
||||||
}
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = append(vals[0].AppendFormat(append(dst, '"'), TimeFieldFormat), '"')
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, t := range vals[1:] {
|
|
||||||
dst = append(t.AppendFormat(append(dst, ',', '"'), TimeFieldFormat), '"')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendUnixTimes(dst []byte, key string, vals []time.Time) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendInt(dst, vals[0].Unix(), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, t := range vals[1:] {
|
|
||||||
dst = strconv.AppendInt(dst, t.Unix(), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendTimestamp(dst []byte) []byte {
|
|
||||||
return appendTime(dst, TimestampFieldName, TimestampFunc())
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendDuration(dst []byte, key string, d time.Duration) []byte {
|
|
||||||
if DurationFieldInteger {
|
|
||||||
return appendInt64(dst, key, int64(d/DurationFieldUnit))
|
|
||||||
}
|
|
||||||
return appendFloat64(dst, key, float64(d)/float64(DurationFieldUnit))
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendDurations(dst []byte, key string, vals []time.Duration) []byte {
|
|
||||||
if DurationFieldInteger {
|
|
||||||
return appendIntDurations(dst, key, vals)
|
|
||||||
}
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendFloat(dst, float64(vals[0])/float64(DurationFieldUnit), 'f', -1, 32)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, d := range vals[1:] {
|
|
||||||
dst = strconv.AppendFloat(append(dst, ','), float64(d)/float64(DurationFieldUnit), 'f', -1, 32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendIntDurations(dst []byte, key string, vals []time.Duration) []byte {
|
|
||||||
if len(vals) == 0 {
|
|
||||||
return append(appendKey(dst, key), '[', ']')
|
|
||||||
}
|
|
||||||
dst = append(appendKey(dst, key), '[')
|
|
||||||
dst = strconv.AppendInt(dst, int64(vals[0]/DurationFieldUnit), 10)
|
|
||||||
if len(vals) > 1 {
|
|
||||||
for _, d := range vals[1:] {
|
|
||||||
dst = strconv.AppendInt(append(dst, ','), int64(d/DurationFieldUnit), 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst = append(dst, ']')
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendInterface(dst []byte, key string, i interface{}) []byte {
|
|
||||||
marshaled, err := json.Marshal(i)
|
|
||||||
if err != nil {
|
|
||||||
return appendString(dst, key, fmt.Sprintf("marshaling error: %v", err))
|
|
||||||
}
|
|
||||||
return append(appendKey(dst, key), marshaled...)
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package zerolog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_appendFloat64(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
input float64
|
|
||||||
want []byte
|
|
||||||
}{
|
|
||||||
{"-Inf", math.Inf(-1), []byte(`"foo":"-Inf"`)},
|
|
||||||
{"+Inf", math.Inf(1), []byte(`"foo":"+Inf"`)},
|
|
||||||
{"NaN", math.NaN(), []byte(`"foo":"NaN"`)},
|
|
||||||
{"0", 0, []byte(`"foo":0`)},
|
|
||||||
{"-1.1", -1.1, []byte(`"foo":-1.1`)},
|
|
||||||
{"1e20", 1e20, []byte(`"foo":100000000000000000000`)},
|
|
||||||
{"1e21", 1e21, []byte(`"foo":1000000000000000000000`)},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := appendFloat32([]byte{}, "foo", float32(tt.input)); !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("appendFloat32() = %s, want %s", got, tt.want)
|
|
||||||
}
|
|
||||||
if got := appendFloat64([]byte{}, "foo", tt.input); !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("appendFloat32() = %s, want %s", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/internal/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
func appendFields(dst []byte, fields map[string]interface{}) []byte {
|
||||||
|
keys := make([]string, 0, len(fields))
|
||||||
|
for key := range fields {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
for _, key := range keys {
|
||||||
|
dst = json.AppendKey(dst, key)
|
||||||
|
switch val := fields[key].(type) {
|
||||||
|
case string:
|
||||||
|
dst = json.AppendString(dst, val)
|
||||||
|
case []byte:
|
||||||
|
dst = json.AppendBytes(dst, val)
|
||||||
|
case error:
|
||||||
|
dst = json.AppendError(dst, val)
|
||||||
|
case []error:
|
||||||
|
dst = json.AppendErrors(dst, val)
|
||||||
|
case bool:
|
||||||
|
dst = json.AppendBool(dst, val)
|
||||||
|
case int:
|
||||||
|
dst = json.AppendInt(dst, val)
|
||||||
|
case int8:
|
||||||
|
dst = json.AppendInt8(dst, val)
|
||||||
|
case int16:
|
||||||
|
dst = json.AppendInt16(dst, val)
|
||||||
|
case int32:
|
||||||
|
dst = json.AppendInt32(dst, val)
|
||||||
|
case int64:
|
||||||
|
dst = json.AppendInt64(dst, val)
|
||||||
|
case uint:
|
||||||
|
dst = json.AppendUint(dst, val)
|
||||||
|
case uint8:
|
||||||
|
dst = json.AppendUint8(dst, val)
|
||||||
|
case uint16:
|
||||||
|
dst = json.AppendUint16(dst, val)
|
||||||
|
case uint32:
|
||||||
|
dst = json.AppendUint32(dst, val)
|
||||||
|
case uint64:
|
||||||
|
dst = json.AppendUint64(dst, val)
|
||||||
|
case float32:
|
||||||
|
dst = json.AppendFloat32(dst, val)
|
||||||
|
case float64:
|
||||||
|
dst = json.AppendFloat64(dst, val)
|
||||||
|
case time.Time:
|
||||||
|
dst = json.AppendTime(dst, val, TimeFieldFormat)
|
||||||
|
case time.Duration:
|
||||||
|
dst = json.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
case []string:
|
||||||
|
dst = json.AppendStrings(dst, val)
|
||||||
|
case []bool:
|
||||||
|
dst = json.AppendBools(dst, val)
|
||||||
|
case []int:
|
||||||
|
dst = json.AppendInts(dst, val)
|
||||||
|
case []int8:
|
||||||
|
dst = json.AppendInts8(dst, val)
|
||||||
|
case []int16:
|
||||||
|
dst = json.AppendInts16(dst, val)
|
||||||
|
case []int32:
|
||||||
|
dst = json.AppendInts32(dst, val)
|
||||||
|
case []int64:
|
||||||
|
dst = json.AppendInts64(dst, val)
|
||||||
|
case []uint:
|
||||||
|
dst = json.AppendUints(dst, val)
|
||||||
|
// case []uint8:
|
||||||
|
// dst = appendUints8(dst, val)
|
||||||
|
case []uint16:
|
||||||
|
dst = json.AppendUints16(dst, val)
|
||||||
|
case []uint32:
|
||||||
|
dst = json.AppendUints32(dst, val)
|
||||||
|
case []uint64:
|
||||||
|
dst = json.AppendUints64(dst, val)
|
||||||
|
case []float32:
|
||||||
|
dst = json.AppendFloats32(dst, val)
|
||||||
|
case []float64:
|
||||||
|
dst = json.AppendFloats64(dst, val)
|
||||||
|
case []time.Time:
|
||||||
|
dst = json.AppendTimes(dst, val, TimeFieldFormat)
|
||||||
|
case []time.Duration:
|
||||||
|
dst = json.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
case nil:
|
||||||
|
dst = append(dst, "null"...)
|
||||||
|
default:
|
||||||
|
dst = json.AppendInterface(dst, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
func AppendKey(dst []byte, key string) []byte {
|
||||||
|
if len(dst) > 1 {
|
||||||
|
dst = append(dst, ',')
|
||||||
|
}
|
||||||
|
dst = AppendString(dst, key)
|
||||||
|
return append(dst, ':')
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendError(dst []byte, err error) []byte {
|
||||||
|
if err == nil {
|
||||||
|
return append(dst, `null`...)
|
||||||
|
}
|
||||||
|
return AppendString(dst, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendErrors(dst []byte, errs []error) []byte {
|
||||||
|
if len(errs) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
if errs[0] != nil {
|
||||||
|
dst = AppendString(dst, errs[0].Error())
|
||||||
|
} else {
|
||||||
|
dst = append(dst, "null"...)
|
||||||
|
}
|
||||||
|
if len(errs) > 1 {
|
||||||
|
for _, err := range errs[1:] {
|
||||||
|
if err == nil {
|
||||||
|
dst = append(dst, ",null"...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dst = AppendString(append(dst, ','), err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
|
@ -1,10 +1,25 @@
|
||||||
package zerolog
|
package json
|
||||||
|
|
||||||
import "unicode/utf8"
|
import "unicode/utf8"
|
||||||
|
|
||||||
const hex = "0123456789abcdef"
|
const hex = "0123456789abcdef"
|
||||||
|
|
||||||
// appendJSONString encodes the input string to json and appends
|
func AppendStrings(dst []byte, vals []string) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = AppendString(dst, vals[0])
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = AppendString(append(dst, ','), val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendString encodes the input string to json and appends
|
||||||
// the encoded string to the input byte slice.
|
// the encoded string to the input byte slice.
|
||||||
//
|
//
|
||||||
// The operation loops though each byte in the string looking
|
// The operation loops though each byte in the string looking
|
||||||
|
@ -13,7 +28,7 @@ const hex = "0123456789abcdef"
|
||||||
// entirety to the byte slice.
|
// entirety to the byte slice.
|
||||||
// If we encounter a byte that does need encoding, switch up
|
// If we encounter a byte that does need encoding, switch up
|
||||||
// the operation and perform a byte-by-byte read-encode-append.
|
// the operation and perform a byte-by-byte read-encode-append.
|
||||||
func appendJSONString(dst []byte, s string) []byte {
|
func AppendString(dst []byte, s string) []byte {
|
||||||
// Start with a double quote.
|
// Start with a double quote.
|
||||||
dst = append(dst, '"')
|
dst = append(dst, '"')
|
||||||
// Loop through each character in the string.
|
// Loop through each character in the string.
|
||||||
|
@ -24,7 +39,7 @@ func appendJSONString(dst []byte, s string) []byte {
|
||||||
if s[i] < 0x20 || s[i] > 0x7e || s[i] == '\\' || s[i] == '"' {
|
if s[i] < 0x20 || s[i] > 0x7e || s[i] == '\\' || s[i] == '"' {
|
||||||
// We encountered a character that needs to be encoded. Switch
|
// We encountered a character that needs to be encoded. Switch
|
||||||
// to complex version of the algorithm.
|
// to complex version of the algorithm.
|
||||||
dst = appendJSONStringComplex(dst, s, i)
|
dst = appendStringComplex(dst, s, i)
|
||||||
return append(dst, '"')
|
return append(dst, '"')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,10 +50,10 @@ func appendJSONString(dst []byte, s string) []byte {
|
||||||
return append(dst, '"')
|
return append(dst, '"')
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendJSONStringComplex is used by appendJSONString to take over an in
|
// appendStringComplex is used by appendString to take over an in
|
||||||
// progress JSON string encoding that encountered a character that needs
|
// progress JSON string encoding that encountered a character that needs
|
||||||
// to be encoded.
|
// to be encoded.
|
||||||
func appendJSONStringComplex(dst []byte, s string, i int) []byte {
|
func appendStringComplex(dst []byte, s string, i int) []byte {
|
||||||
start := 0
|
start := 0
|
||||||
for i < len(s) {
|
for i < len(s) {
|
||||||
b := s[i]
|
b := s[i]
|
||||||
|
@ -95,12 +110,12 @@ func appendJSONStringComplex(dst []byte, s string, i int) []byte {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendJSONBytes is a mirror of appendJSONString with []byte arg
|
// AppendBytes is a mirror of appendString with []byte arg
|
||||||
func appendJSONBytes(dst, s []byte) []byte {
|
func AppendBytes(dst, s []byte) []byte {
|
||||||
dst = append(dst, '"')
|
dst = append(dst, '"')
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
if s[i] < 0x20 || s[i] > 0x7e || s[i] == '\\' || s[i] == '"' {
|
if s[i] < 0x20 || s[i] > 0x7e || s[i] == '\\' || s[i] == '"' {
|
||||||
dst = appendJSONBytesComplex(dst, s, i)
|
dst = appendBytesComplex(dst, s, i)
|
||||||
return append(dst, '"')
|
return append(dst, '"')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,9 +123,9 @@ func appendJSONBytes(dst, s []byte) []byte {
|
||||||
return append(dst, '"')
|
return append(dst, '"')
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendJSONBytesComplex is a mirror of the appendJSONStringComplex
|
// appendBytesComplex is a mirror of the appendStringComplex
|
||||||
// with []byte arg
|
// with []byte arg
|
||||||
func appendJSONBytesComplex(dst, s []byte, i int) []byte {
|
func appendBytesComplex(dst, s []byte, i int) []byte {
|
||||||
start := 0
|
start := 0
|
||||||
for i < len(s) {
|
for i < len(s) {
|
||||||
b := s[i]
|
b := s[i]
|
|
@ -1,4 +1,4 @@
|
||||||
package zerolog
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -53,20 +53,20 @@ var encodeStringTests = []struct {
|
||||||
{"emoji \u2764\ufe0f!", `"emoji ❤️!"`},
|
{"emoji \u2764\ufe0f!", `"emoji ❤️!"`},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAppendJSONString(t *testing.T) {
|
func TestappendString(t *testing.T) {
|
||||||
for _, tt := range encodeStringTests {
|
for _, tt := range encodeStringTests {
|
||||||
b := appendJSONString([]byte{}, tt.in)
|
b := AppendString([]byte{}, tt.in)
|
||||||
if got, want := string(b), tt.out; got != want {
|
if got, want := string(b), tt.out; got != want {
|
||||||
t.Errorf("appendJSONString(%q) = %#q, want %#q", tt.in, got, want)
|
t.Errorf("appendString(%q) = %#q, want %#q", tt.in, got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAppendJSONBytes(t *testing.T) {
|
func TestappendBytes(t *testing.T) {
|
||||||
for _, tt := range encodeStringTests {
|
for _, tt := range encodeStringTests {
|
||||||
b := appendJSONBytes([]byte{}, []byte(tt.in))
|
b := AppendBytes([]byte{}, []byte(tt.in))
|
||||||
if got, want := string(b), tt.out; got != want {
|
if got, want := string(b), tt.out; got != want {
|
||||||
t.Errorf("appendJSONBytes(%q) = %#q, want %#q", tt.in, got, want)
|
t.Errorf("appendBytes(%q) = %#q, want %#q", tt.in, got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ func TestStringBytes(t *testing.T) {
|
||||||
}
|
}
|
||||||
s := string(r) + "\xff\xff\xffhello" // some invalid UTF-8 too
|
s := string(r) + "\xff\xff\xffhello" // some invalid UTF-8 too
|
||||||
|
|
||||||
enc := string(appendJSONString([]byte{}, s))
|
enc := string(AppendString([]byte{}, s))
|
||||||
encBytes := string(appendJSONBytes([]byte{}, []byte(s)))
|
encBytes := string(AppendBytes([]byte{}, []byte(s)))
|
||||||
|
|
||||||
if enc != encBytes {
|
if enc != encBytes {
|
||||||
i := 0
|
i := 0
|
||||||
|
@ -108,7 +108,7 @@ func TestStringBytes(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkAppendJSONString(b *testing.B) {
|
func BenchmarkappendString(b *testing.B) {
|
||||||
tests := map[string]string{
|
tests := map[string]string{
|
||||||
"NoEncoding": `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
|
"NoEncoding": `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
|
||||||
"EncodingFirst": `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
|
"EncodingFirst": `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
|
||||||
|
@ -122,13 +122,13 @@ func BenchmarkAppendJSONString(b *testing.B) {
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
buf := make([]byte, 0, 100)
|
buf := make([]byte, 0, 100)
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_ = appendJSONString(buf, str)
|
_ = AppendString(buf, str)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkAppendJSONBytes(b *testing.B) {
|
func BenchmarkappendBytes(b *testing.B) {
|
||||||
tests := map[string]string{
|
tests := map[string]string{
|
||||||
"NoEncoding": `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
|
"NoEncoding": `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
|
||||||
"EncodingFirst": `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
|
"EncodingFirst": `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
|
||||||
|
@ -143,7 +143,7 @@ func BenchmarkAppendJSONBytes(b *testing.B) {
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
buf := make([]byte, 0, 100)
|
buf := make([]byte, 0, 100)
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_ = appendJSONBytes(buf, byt)
|
_ = AppendBytes(buf, byt)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AppendTime(dst []byte, t time.Time, format string) []byte {
|
||||||
|
if format == "" {
|
||||||
|
return AppendInt64(dst, t.Unix())
|
||||||
|
}
|
||||||
|
return append(t.AppendFormat(append(dst, '"'), format), '"')
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendTimes(dst []byte, vals []time.Time, format string) []byte {
|
||||||
|
if format == "" {
|
||||||
|
return appendUnixTimes(dst, vals)
|
||||||
|
}
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = append(vals[0].AppendFormat(append(dst, '"'), format), '"')
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, t := range vals[1:] {
|
||||||
|
dst = append(t.AppendFormat(append(dst, ',', '"'), format), '"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendUnixTimes(dst []byte, vals []time.Time) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, vals[0].Unix(), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, t := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(dst, t.Unix(), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {
|
||||||
|
if useInt {
|
||||||
|
return strconv.AppendInt(dst, int64(d/unit), 10)
|
||||||
|
}
|
||||||
|
return AppendFloat64(dst, float64(d)/float64(unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = AppendDuration(dst, vals[0], unit, useInt)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, d := range vals[1:] {
|
||||||
|
dst = AppendDuration(append(dst, ','), d, unit, useInt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
|
@ -0,0 +1,278 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AppendBool(dst []byte, val bool) []byte {
|
||||||
|
return strconv.AppendBool(dst, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendBools(dst []byte, vals []bool) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendBool(dst, vals[0])
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendBool(append(dst, ','), val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInt(dst []byte, val int) []byte {
|
||||||
|
return strconv.AppendInt(dst, int64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInts(dst []byte, vals []int) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInt8(dst []byte, val int8) []byte {
|
||||||
|
return strconv.AppendInt(dst, int64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInts8(dst []byte, vals []int8) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInt16(dst []byte, val int16) []byte {
|
||||||
|
return strconv.AppendInt(dst, int64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInts16(dst []byte, vals []int16) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInt32(dst []byte, val int32) []byte {
|
||||||
|
return strconv.AppendInt(dst, int64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInts32(dst []byte, vals []int32) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInt64(dst []byte, val int64) []byte {
|
||||||
|
return strconv.AppendInt(dst, val, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInts64(dst []byte, vals []int64) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, vals[0], 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), val, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUint(dst []byte, val uint) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUints(dst []byte, vals []uint) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUint8(dst []byte, val uint8) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUints8(dst []byte, vals []uint8) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUint16(dst []byte, val uint16) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUints16(dst []byte, vals []uint16) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUint32(dst []byte, val uint32) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUints32(dst []byte, vals []uint32) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUint64(dst []byte, val uint64) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendUints64(dst []byte, vals []uint64) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, vals[0], 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), val, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendFloat(dst []byte, val float64, bitSize int) []byte {
|
||||||
|
// JSON does not permit NaN or Infinity. A typical JSON encoder would fail
|
||||||
|
// with an error, but a logging library wants the data to get thru so we
|
||||||
|
// make a tradeoff and store those types as string.
|
||||||
|
switch {
|
||||||
|
case math.IsNaN(val):
|
||||||
|
return append(dst, `"NaN"`...)
|
||||||
|
case math.IsInf(val, 1):
|
||||||
|
return append(dst, `"+Inf"`...)
|
||||||
|
case math.IsInf(val, -1):
|
||||||
|
return append(dst, `"-Inf"`...)
|
||||||
|
}
|
||||||
|
return strconv.AppendFloat(dst, val, 'f', -1, bitSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendFloat32(dst []byte, val float32) []byte {
|
||||||
|
return AppendFloat(dst, float64(val), 32)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendFloats32(dst []byte, vals []float32) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = AppendFloat(dst, float64(vals[0]), 32)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = AppendFloat(append(dst, ','), float64(val), 32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendFloat64(dst []byte, val float64) []byte {
|
||||||
|
return AppendFloat(dst, val, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendFloats64(dst []byte, vals []float64) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = AppendFloat(dst, vals[0], 32)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = AppendFloat(append(dst, ','), val, 64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendInterface(dst []byte, i interface{}) []byte {
|
||||||
|
marshaled, err := json.Marshal(i)
|
||||||
|
if err != nil {
|
||||||
|
return AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
|
||||||
|
}
|
||||||
|
return append(dst, marshaled...)
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_appendFloat64(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input float64
|
||||||
|
want []byte
|
||||||
|
}{
|
||||||
|
{"-Inf", math.Inf(-1), []byte(`"-Inf"`)},
|
||||||
|
{"+Inf", math.Inf(1), []byte(`"+Inf"`)},
|
||||||
|
{"NaN", math.NaN(), []byte(`"NaN"`)},
|
||||||
|
{"0", 0, []byte(`0`)},
|
||||||
|
{"-1.1", -1.1, []byte(`-1.1`)},
|
||||||
|
{"1e20", 1e20, []byte(`100000000000000000000`)},
|
||||||
|
{"1e21", 1e21, []byte(`1000000000000000000000`)},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := AppendFloat32([]byte{}, float32(tt.input)); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("appendFloat32() = %s, want %s", got, tt.want)
|
||||||
|
}
|
||||||
|
if got := AppendFloat64([]byte{}, tt.input); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("appendFloat32() = %s, want %s", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
4
log.go
4
log.go
|
@ -73,6 +73,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/internal/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Level defines log levels.
|
// Level defines log levels.
|
||||||
|
@ -306,7 +308,7 @@ func (l Logger) newEvent(level Level, addLevelField bool, done func(string)) *Ev
|
||||||
e.done = done
|
e.done = done
|
||||||
if l.context != nil && len(l.context) > 0 && l.context[0] > 0 {
|
if l.context != nil && len(l.context) > 0 && l.context[0] > 0 {
|
||||||
// first byte of context is ts flag
|
// first byte of context is ts flag
|
||||||
e.buf = appendTimestamp(e.buf)
|
e.buf = json.AppendTime(json.AppendKey(e.buf, TimestampFieldName), TimestampFunc(), TimeFieldFormat)
|
||||||
}
|
}
|
||||||
if addLevelField {
|
if addLevelField {
|
||||||
e.Str(LevelFieldName, level.String())
|
e.Str(LevelFieldName, level.String())
|
||||||
|
|
Loading…
Reference in New Issue