Add a new time format for UNIX timestamp in milliseconds

This commit is contained in:
Olivier Poitrey 2019-04-19 15:48:31 -07:00
parent 509d727fba
commit 3e85c4b21c
4 changed files with 51 additions and 15 deletions

View File

@ -53,7 +53,7 @@ func main() {
// UNIX Time is faster and smaller than most timestamps // UNIX Time is faster and smaller than most timestamps
// If you set zerolog.TimeFieldFormat to an empty string, // If you set zerolog.TimeFieldFormat to an empty string,
// logs will write with UNIX time // logs will write with UNIX time
zerolog.TimeFieldFormat = "" zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Print("hello world") log.Print("hello world")
} }
@ -76,7 +76,7 @@ import (
) )
func main() { func main() {
zerolog.TimeFieldFormat = "" zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Debug(). log.Debug().
Str("Scale", "833 cents"). Str("Scale", "833 cents").
@ -102,7 +102,7 @@ import (
) )
func main() { func main() {
zerolog.TimeFieldFormat = "" zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Info().Msg("hello world") log.Info().Msg("hello world")
} }
@ -138,7 +138,7 @@ import (
) )
func main() { func main() {
zerolog.TimeFieldFormat = "" zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
debug := flag.Bool("debug", false, "sets log level to debug") debug := flag.Bool("debug", false, "sets log level to debug")
flag.Parse() flag.Parse()
@ -189,7 +189,7 @@ import (
) )
func main() { func main() {
zerolog.TimeFieldFormat = "" zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Log(). log.Log().
Str("foo", "bar"). Str("foo", "bar").
@ -215,7 +215,7 @@ func main() {
err := errors.New("A repo man spends his life getting into tense situations") err := errors.New("A repo man spends his life getting into tense situations")
service := "myservice" service := "myservice"
zerolog.TimeFieldFormat = "" zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Fatal(). log.Fatal().
Err(err). Err(err).
@ -474,9 +474,8 @@ Some settings can be changed and will by applied to all loggers:
* `zerolog.LevelFieldName`: Can be set to customize level field name. * `zerolog.LevelFieldName`: Can be set to customize level field name.
* `zerolog.MessageFieldName`: Can be set to customize message field name. * `zerolog.MessageFieldName`: Can be set to customize message field name.
* `zerolog.ErrorFieldName`: Can be set to customize `Err` field name. * `zerolog.ErrorFieldName`: Can be set to customize `Err` field name.
* `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with an empty string, times are formated as UNIX timestamp. * `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with `zerolog.TimeFormatUnix` or `zerolog.TimeFormatUnixMs`, times are formated as UNIX timestamp.
// DurationFieldUnit defines the unit for time.Duration type fields added * DurationFieldUnit defines the unit for time.Duration type fields added using the Dur method.
// using the Dur method.
* `DurationFieldUnit`: Sets the unit of the fields added by `Dur` (default: `time.Millisecond`). * `DurationFieldUnit`: Sets the unit of the fields added by `Dur` (default: `time.Millisecond`).
* `DurationFieldInteger`: If set to true, `Dur` fields are formatted as integers instead of floats. * `DurationFieldInteger`: If set to true, `Dur` fields are formatted as integers instead of floats.
* `ErrorHandler`: Called whenever zerolog fails to write an event on its output. If not set, an error is printed on the stderr. This handler must be thread safe and non-blocking. * `ErrorHandler`: Called whenever zerolog fails to write an event on its output. If not set, an error is printed on the stderr. This handler must be thread safe and non-blocking.

View File

@ -234,7 +234,7 @@ func BenchmarkLogFieldType(b *testing.B) {
func BenchmarkContextFieldType(b *testing.B) { func BenchmarkContextFieldType(b *testing.B) {
oldFormat := TimeFieldFormat oldFormat := TimeFieldFormat
TimeFieldFormat = "" TimeFieldFormat = TimeFormatUnix
defer func() { TimeFieldFormat = oldFormat }() defer func() { TimeFieldFormat = oldFormat }()
bools := []bool{true, false, true, false, true, false, true, false, true, false} bools := []bool{true, false, true, false, true, false, true, false, true, false}
ints := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ints := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

View File

@ -6,6 +6,16 @@ import (
) )
import "sync/atomic" import "sync/atomic"
const (
// TimeFormatUnix defines a time format that makes time fields to be
// serialized as Unix timestamp integers.
TimeFormatUnix = ""
// TimeFormatUnix defines a time format that makes time fields to be
// serialized as Unix timestamp integers in milliseconds.
TimeFormatUnixMs = "UNIXMS"
)
var ( var (
// TimestampFieldName is the field name used for the timestamp field. // TimestampFieldName is the field name used for the timestamp field.
TimestampFieldName = "time" TimestampFieldName = "time"
@ -46,9 +56,9 @@ var (
return err return err
} }
// TimeFieldFormat defines the time format of the Time field type. // TimeFieldFormat defines the time format of the Time field type. If set to
// If set to an empty string, the time is formatted as an UNIX timestamp // TimeFormatUnix or TimeFormatUnixMs, the time is formatted as an UNIX
// as integer. // timestamp as integer.
TimeFieldFormat = time.RFC3339 TimeFieldFormat = time.RFC3339
// TimestampFunc defines the function called to generate a timestamp. // TimestampFunc defines the function called to generate a timestamp.

View File

@ -5,11 +5,20 @@ import (
"time" "time"
) )
const (
// Import from zerolog/global.go
timeFormatUnix = ""
timeFormatUnixMs = "UNIXMS"
)
// AppendTime formats the input time with the given format // AppendTime formats the input time with the given format
// and appends the encoded string to the input byte slice. // and appends the encoded string to the input byte slice.
func (e Encoder) AppendTime(dst []byte, t time.Time, format string) []byte { func (e Encoder) AppendTime(dst []byte, t time.Time, format string) []byte {
if format == "" { switch format {
case timeFormatUnix:
return e.AppendInt64(dst, t.Unix()) return e.AppendInt64(dst, t.Unix())
case timeFormatUnixMs:
return e.AppendInt64(dst, t.UnixNano()/1000000)
} }
return append(t.AppendFormat(append(dst, '"'), format), '"') return append(t.AppendFormat(append(dst, '"'), format), '"')
} }
@ -17,8 +26,11 @@ func (e Encoder) AppendTime(dst []byte, t time.Time, format string) []byte {
// AppendTimes converts the input times with the given format // AppendTimes converts the input times with the given format
// and appends the encoded string list to the input byte slice. // and appends the encoded string list to the input byte slice.
func (Encoder) AppendTimes(dst []byte, vals []time.Time, format string) []byte { func (Encoder) AppendTimes(dst []byte, vals []time.Time, format string) []byte {
if format == "" { switch format {
case timeFormatUnix:
return appendUnixTimes(dst, vals) return appendUnixTimes(dst, vals)
case timeFormatUnixMs:
return appendUnixMsTimes(dst, vals)
} }
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -49,6 +61,21 @@ func appendUnixTimes(dst []byte, vals []time.Time) []byte {
return dst return dst
} }
func appendUnixMsTimes(dst []byte, vals []time.Time) []byte {
if len(vals) == 0 {
return append(dst, '[', ']')
}
dst = append(dst, '[')
dst = strconv.AppendInt(dst, vals[0].UnixNano()/1000000, 10)
if len(vals) > 1 {
for _, t := range vals[1:] {
dst = strconv.AppendInt(append(dst, ','), t.UnixNano()/1000000, 10)
}
}
dst = append(dst, ']')
return dst
}
// AppendDuration formats the input duration with the given unit & format // AppendDuration formats the input duration with the given unit & format
// and appends the encoded string to the input byte slice. // and appends the encoded string to the input byte slice.
func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte { func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {