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 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. // 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. // To customize the key name, change zerolog.TimestampFieldName.
func (c Context) Timestamp() Context { func (c Context) Timestamp() Context {
if len(c.l.context) > 0 { c.l = c.l.Hook(th)
c.l.context[0] = 1
} else {
c.l.context = append(c.l.context, 1)
}
return c return c
} }

View File

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

View File

@ -67,5 +67,5 @@ func Example_handler() {
h.ServeHTTP(httptest.NewRecorder(), &http.Request{}) 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" "io/ioutil"
"os" "os"
"strconv" "strconv"
"github.com/rs/zerolog/internal/json"
) )
// Level defines log levels. // Level defines log levels.
@ -193,9 +191,6 @@ func (l Logger) With() Context {
l.context = make([]byte, 0, 500) l.context = make([]byte, 0, 500)
if context != nil { if context != nil {
l.context = append(l.context, context...) 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} return Context{l}
} }
@ -208,7 +203,7 @@ func (l *Logger) UpdateContext(update func(c Context) Context) {
return return
} }
if cap(l.context) == 0 { 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}) c := update(Context{*l})
l.context = c.l.context 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 := newEvent(l.w, level, true)
e.done = done e.done = done
if l.context != nil && len(l.context) > 0 && l.context[0] > 0 { e.ch = l.hooks
// first byte of context is ts flag
e.buf = json.AppendTime(json.AppendKey(e.buf, TimestampFieldName), TimestampFunc(), TimeFieldFormat)
}
if level != NoLevel { if level != NoLevel {
e.Str(LevelFieldName, level.String()) e.Str(LevelFieldName, level.String())
} }
if l.context != nil && len(l.context) > 1 { if len(l.context) > 0 {
if len(e.buf) > 1 { if len(e.buf) > 1 {
e.buf = append(e.buf, ',') e.buf = append(e.buf, ',')
} }
e.buf = append(e.buf, l.context[1:]...) e.buf = append(e.buf, l.context...)
}
if len(l.hooks) > 0 {
e.h = append(e.h, l.hooks...)
} }
return e return e
} }

View File

@ -426,7 +426,7 @@ func TestContextTimestamp(t *testing.T) {
log := New(out).With().Timestamp().Str("foo", "bar").Logger() log := New(out).With().Timestamp().Str("foo", "bar").Logger()
log.Log().Msg("hello world") 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) 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 := New(ignoredOut).Output(out).With().Timestamp().Str("foo", "bar").Logger()
log.Log().Msg("hello world") 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) t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
} }
} }