Use new hook internally to handle timestamp in context

This commit is contained in:
Olivier Poitrey 2018-02-07 13:24:48 -08:00
parent cbec2377ee
commit fcbdf23e9e
5 changed files with 25 additions and 23 deletions

View File

@ -258,14 +258,18 @@ func (c Context) Floats64(key string, f []float64) Context {
return c
}
type timestampHook struct{}
func (ts timestampHook) Run(e *Event, level Level, msg string) {
e.Timestamp()
}
var th = timestampHook{}
// Timestamp adds the current local time as UNIX timestamp to the logger context with the "time" key.
// To customize the key name, change zerolog.TimestampFieldName.
func (c Context) Timestamp() Context {
if len(c.l.context) > 0 {
c.l.context[0] = 1
} else {
c.l.context = append(c.l.context, 1)
}
c.l = c.l.Hook(th)
return c
}

View File

@ -25,6 +25,7 @@ type Event struct {
w LevelWriter
level Level
done func(msg string)
ch []Hook // hooks from context
h []Hook
}
@ -77,6 +78,14 @@ func (e *Event) Msg(msg string) {
if e == nil {
return
}
if len(e.ch) > 0 {
e.ch[0].Run(e, e.level, msg)
if len(e.ch) > 1 {
for _, hook := range e.ch[1:] {
hook.Run(e, e.level, msg)
}
}
}
if len(e.h) > 0 {
e.h[0].Run(e, e.level, msg)
if len(e.h) > 1 {

View File

@ -67,5 +67,5 @@ func Example_handler() {
h.ServeHTTP(httptest.NewRecorder(), &http.Request{})
// Output: {"time":"2001-02-03T04:05:06Z","level":"info","role":"my-service","host":"local-hostname","user":"current user","status":"ok","message":"Something happend"}
// Output: {"level":"info","role":"my-service","host":"local-hostname","user":"current user","status":"ok","time":"2001-02-03T04:05:06Z","message":"Something happend"}
}

19
log.go
View File

@ -90,8 +90,6 @@ import (
"io/ioutil"
"os"
"strconv"
"github.com/rs/zerolog/internal/json"
)
// Level defines log levels.
@ -193,9 +191,6 @@ func (l Logger) With() Context {
l.context = make([]byte, 0, 500)
if context != nil {
l.context = append(l.context, context...)
} else {
// first byte of context is presence of timestamp or not
l.context = append(l.context, 0)
}
return Context{l}
}
@ -208,7 +203,7 @@ func (l *Logger) UpdateContext(update func(c Context) Context) {
return
}
if cap(l.context) == 0 {
l.context = make([]byte, 1, 500) // first byte is timestamp flag
l.context = make([]byte, 0, 500)
}
c := update(Context{*l})
l.context = c.l.context
@ -345,21 +340,15 @@ func (l *Logger) newEvent(level Level, done func(string)) *Event {
}
e := newEvent(l.w, level, true)
e.done = done
if l.context != nil && len(l.context) > 0 && l.context[0] > 0 {
// first byte of context is ts flag
e.buf = json.AppendTime(json.AppendKey(e.buf, TimestampFieldName), TimestampFunc(), TimeFieldFormat)
}
e.ch = l.hooks
if level != NoLevel {
e.Str(LevelFieldName, level.String())
}
if l.context != nil && len(l.context) > 1 {
if len(l.context) > 0 {
if len(e.buf) > 1 {
e.buf = append(e.buf, ',')
}
e.buf = append(e.buf, l.context[1:]...)
}
if len(l.hooks) > 0 {
e.h = append(e.h, l.hooks...)
e.buf = append(e.buf, l.context...)
}
return e
}

View File

@ -426,7 +426,7 @@ func TestContextTimestamp(t *testing.T) {
log := New(out).With().Timestamp().Str("foo", "bar").Logger()
log.Log().Msg("hello world")
if got, want := out.String(), `{"time":"2001-02-03T04:05:06Z","foo":"bar","message":"hello world"}`+"\n"; got != want {
if got, want := out.String(), `{"foo":"bar","time":"2001-02-03T04:05:06Z","message":"hello world"}`+"\n"; got != want {
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
}
}
@ -470,7 +470,7 @@ func TestOutputWithTimestamp(t *testing.T) {
log := New(ignoredOut).Output(out).With().Timestamp().Str("foo", "bar").Logger()
log.Log().Msg("hello world")
if got, want := out.String(), `{"time":"2001-02-03T04:05:06Z","foo":"bar","message":"hello world"}`+"\n"; got != want {
if got, want := out.String(), `{"foo":"bar","time":"2001-02-03T04:05:06Z","message":"hello world"}`+"\n"; got != want {
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
}
}