diff --git a/context.go b/context.go index cd25687..8753929 100644 --- a/context.go +++ b/context.go @@ -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 } diff --git a/event.go b/event.go index 2557599..deae8db 100644 --- a/event.go +++ b/event.go @@ -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 { diff --git a/hlog/hlog_example_test.go b/hlog/hlog_example_test.go index 5ffcaf7..a70240e 100644 --- a/hlog/hlog_example_test.go +++ b/hlog/hlog_example_test.go @@ -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"} } diff --git a/log.go b/log.go index 8c35785..843a94b 100644 --- a/log.go +++ b/log.go @@ -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 } diff --git a/log_test.go b/log_test.go index 00b8940..b5ee231 100644 --- a/log_test.go +++ b/log_test.go @@ -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) } }