forked from rs/zerolog
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
439 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package zerolog | ||
|
||
// Hook defines an interface to a log hook. | ||
type Hook interface { | ||
// Run runs the hook with the event. | ||
Run(e *Event, level Level, message string) | ||
} | ||
|
||
// LevelHook applies a different hook for each level. | ||
type LevelHook struct { | ||
NoLevelHook, DebugHook, InfoHook, WarnHook, ErrorHook, FatalHook, PanicHook Hook | ||
} | ||
|
||
// Run implements the Hook interface. | ||
func (h LevelHook) Run(e *Event, level Level, message string) { | ||
switch level { | ||
case DebugLevel: | ||
if h.DebugHook != nil { | ||
h.DebugHook.Run(e, level, message) | ||
} | ||
case InfoLevel: | ||
if h.InfoHook != nil { | ||
h.InfoHook.Run(e, level, message) | ||
} | ||
case WarnLevel: | ||
if h.WarnHook != nil { | ||
h.WarnHook.Run(e, level, message) | ||
} | ||
case ErrorLevel: | ||
if h.ErrorHook != nil { | ||
h.ErrorHook.Run(e, level, message) | ||
} | ||
case FatalLevel: | ||
if h.FatalHook != nil { | ||
h.FatalHook.Run(e, level, message) | ||
} | ||
case PanicLevel: | ||
if h.PanicHook != nil { | ||
h.PanicHook.Run(e, level, message) | ||
} | ||
case NoLevel: | ||
if h.NoLevelHook != nil { | ||
h.NoLevelHook.Run(e, level, message) | ||
} | ||
} | ||
} | ||
|
||
// NewLevelHook returns a new LevelHook. | ||
func NewLevelHook() LevelHook { | ||
return LevelHook{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
package zerolog | ||
|
||
import ( | ||
"testing" | ||
"bytes" | ||
"io/ioutil" | ||
) | ||
|
||
type LevelNameHook struct{} | ||
|
||
func (h LevelNameHook) Run(e *Event, level Level, msg string) { | ||
levelName := level.String() | ||
if level == NoLevel { | ||
levelName = "nolevel" | ||
} | ||
e.Str("level_name", levelName) | ||
} | ||
|
||
type SimpleHook struct{} | ||
|
||
func (h SimpleHook) Run(e *Event, level Level, msg string) { | ||
e.Bool("has_level", level != NoLevel) | ||
e.Str("test", "logged") | ||
} | ||
|
||
type CopyHook struct{} | ||
|
||
func (h CopyHook) Run(e *Event, level Level, msg string) { | ||
hasLevel := level != NoLevel | ||
e.Bool("copy_has_level", hasLevel) | ||
if hasLevel { | ||
e.Str("copy_level", level.String()) | ||
} | ||
e.Str("copy_msg", msg) | ||
} | ||
|
||
type NopHook struct{} | ||
|
||
func (h NopHook) Run(e *Event, level Level, msg string) { | ||
} | ||
|
||
var ( | ||
levelNameHook LevelNameHook | ||
simpleHook SimpleHook | ||
copyHook CopyHook | ||
nopHook NopHook | ||
) | ||
|
||
func TestHook(t *testing.T) { | ||
t.Run("Message", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(levelNameHook) | ||
log.Log().Msg("test message") | ||
if got, want := out.String(), `{"level_name":"nolevel","message":"test message"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("NoLevel", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(levelNameHook) | ||
log.Log().Msg("") | ||
if got, want := out.String(), `{"level_name":"nolevel"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Print", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(levelNameHook) | ||
log.Print("") | ||
if got, want := out.String(), `{"level":"debug","level_name":"debug"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Error", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(levelNameHook) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","level_name":"error"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Copy/1", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(copyHook) | ||
log.Log().Msg("") | ||
if got, want := out.String(), `{"copy_has_level":false,"copy_msg":""}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Copy/2", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(copyHook) | ||
log.Info().Msg("a message") | ||
if got, want := out.String(), `{"level":"info","copy_has_level":true,"copy_level":"info","copy_msg":"a message","message":"a message"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Multi", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(levelNameHook).Hook(simpleHook) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","level_name":"error","has_level":true,"test":"logged"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Multi/Message", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(levelNameHook).Hook(simpleHook) | ||
log.Error().Msg("a message") | ||
if got, want := out.String(), `{"level":"error","level_name":"error","has_level":true,"test":"logged","message":"a message"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Output/single/pre", func(t *testing.T) { | ||
ignored := &bytes.Buffer{} | ||
out := &bytes.Buffer{} | ||
log := New(ignored).Hook(levelNameHook).Output(out) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","level_name":"error"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Output/single/post", func(t *testing.T) { | ||
ignored := &bytes.Buffer{} | ||
out := &bytes.Buffer{} | ||
log := New(ignored).Output(out).Hook(levelNameHook) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","level_name":"error"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Output/multi/pre", func(t *testing.T) { | ||
ignored := &bytes.Buffer{} | ||
out := &bytes.Buffer{} | ||
log := New(ignored).Hook(levelNameHook).Hook(simpleHook).Output(out) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","level_name":"error","has_level":true,"test":"logged"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Output/multi/post", func(t *testing.T) { | ||
ignored := &bytes.Buffer{} | ||
out := &bytes.Buffer{} | ||
log := New(ignored).Output(out).Hook(levelNameHook).Hook(simpleHook) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","level_name":"error","has_level":true,"test":"logged"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("Output/mixed", func(t *testing.T) { | ||
ignored := &bytes.Buffer{} | ||
out := &bytes.Buffer{} | ||
log := New(ignored).Hook(levelNameHook).Output(out).Hook(simpleHook) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","level_name":"error","has_level":true,"test":"logged"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("With/single/pre", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(levelNameHook).With().Str("with", "pre").Logger() | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","with":"pre","level_name":"error"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("With/single/post", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).With().Str("with", "post").Logger().Hook(levelNameHook) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","with":"post","level_name":"error"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("With/multi/pre", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(levelNameHook).Hook(simpleHook).With().Str("with", "pre").Logger() | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","with":"pre","level_name":"error","has_level":true,"test":"logged"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("With/multi/post", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).With().Str("with", "post").Logger().Hook(levelNameHook).Hook(simpleHook) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","with":"post","level_name":"error","has_level":true,"test":"logged"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("With/mixed", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out).Hook(levelNameHook).With().Str("with", "mixed").Logger().Hook(simpleHook) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error","with":"mixed","level_name":"error","has_level":true,"test":"logged"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
t.Run("None", func(t *testing.T) { | ||
out := &bytes.Buffer{} | ||
log := New(out) | ||
log.Error().Msg("") | ||
if got, want := out.String(), `{"level":"error"}`+"\n"; got != want { | ||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) | ||
} | ||
}) | ||
} | ||
|
||
func BenchmarkHooks(b *testing.B) { | ||
logger := New(ioutil.Discard) | ||
b.ResetTimer() | ||
b.Run("Nop/Single", func(b *testing.B) { | ||
log := logger.Hook(nopHook) | ||
b.RunParallel(func(pb *testing.PB) { | ||
for pb.Next() { | ||
log.Log().Msg("") | ||
} | ||
}) | ||
}) | ||
b.Run("Nop/Multi", func(b *testing.B) { | ||
log := logger.Hook(nopHook).Hook(nopHook) | ||
b.RunParallel(func(pb *testing.PB) { | ||
for pb.Next() { | ||
log.Log().Msg("") | ||
} | ||
}) | ||
}) | ||
b.Run("Simple", func(b *testing.B) { | ||
log := logger.Hook(simpleHook) | ||
b.RunParallel(func(pb *testing.PB) { | ||
for pb.Next() { | ||
log.Log().Msg("") | ||
} | ||
}) | ||
}) | ||
} |
Oops, something went wrong.