diff --git a/hooks/test/test.go b/hooks/test/test.go index 0190ba0..78d75ff 100644 --- a/hooks/test/test.go +++ b/hooks/test/test.go @@ -2,6 +2,7 @@ package test import ( "io/ioutil" + "sync" "github.com/Sirupsen/logrus" ) @@ -9,6 +10,7 @@ import ( // Hook is a hook designed for dealing with logs in test scenarios. type Hook struct { Entries []*logrus.Entry + mu sync.RWMutex } // NewGlobal installs a test hook for the global logger. @@ -42,6 +44,8 @@ func NewNullLogger() (*logrus.Logger, *Hook) { } func (t *Hook) Fire(e *logrus.Entry) error { + t.mu.Lock() + defer t.mu.Unlock() t.Entries = append(t.Entries, e) return nil } @@ -51,17 +55,35 @@ func (t *Hook) Levels() []logrus.Level { } // LastEntry returns the last entry that was logged or nil. -func (t *Hook) LastEntry() (l *logrus.Entry) { - - if i := len(t.Entries) - 1; i < 0 { +func (t *Hook) LastEntry() *logrus.Entry { + t.mu.RLock() + defer t.mu.RUnlock() + i := len(t.Entries) - 1 + if i < 0 { return nil - } else { - return t.Entries[i] } + // Make a copy, for safety + e := *t.Entries[i] + return &e +} +// AllEntries returns all entries that were logged. +func (t *Hook) AllEntries() []*logrus.Entry { + t.mu.RLock() + defer t.mu.RUnlock() + // Make a copy so the returned value won't race with future log requests + entries := make([]*logrus.Entry, len(t.Entries)) + for i, entry := range t.Entries { + // Make a copy, for safety + e := *entry + entries[i] = &e + } + return entries } // Reset removes all Entries from this test hook. func (t *Hook) Reset() { + t.mu.Lock() + defer t.mu.Unlock() t.Entries = make([]*logrus.Entry, 0) }