Skip to content

Commit

Permalink
Expose zaptest.observer.(*ObservedLogs).Filter
Browse files Browse the repository at this point in the history
Export method  `observer.(*ObservedLogs).Filter` to allow consumers to
filter logs by arbitrary functions for testing.

Currently consumers can call `(*ObservedLogs).All` and proceed to filter
using `[]LoggedEntry` directly, but the result is then incompatible with
existing methods such as `FilterMessage` because there is now way to
re-construct an `*ObservedLogs` object.
  • Loading branch information
jkanywhere committed May 23, 2021
1 parent 3748251 commit aefe3c4
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
14 changes: 8 additions & 6 deletions zaptest/observer/observer.go
Expand Up @@ -80,21 +80,21 @@ func (o *ObservedLogs) AllUntimed() []LoggedEntry {

// FilterMessage filters entries to those that have the specified message.
func (o *ObservedLogs) FilterMessage(msg string) *ObservedLogs {
return o.filter(func(e LoggedEntry) bool {
return o.Filter(func(e LoggedEntry) bool {
return e.Message == msg
})
}

// FilterMessageSnippet filters entries to those that have a message containing the specified snippet.
func (o *ObservedLogs) FilterMessageSnippet(snippet string) *ObservedLogs {
return o.filter(func(e LoggedEntry) bool {
return o.Filter(func(e LoggedEntry) bool {
return strings.Contains(e.Message, snippet)
})
}

// FilterField filters entries to those that have the specified field.
func (o *ObservedLogs) FilterField(field zapcore.Field) *ObservedLogs {
return o.filter(func(e LoggedEntry) bool {
return o.Filter(func(e LoggedEntry) bool {
for _, ctxField := range e.Context {
if ctxField.Equals(field) {
return true
Expand All @@ -106,7 +106,7 @@ func (o *ObservedLogs) FilterField(field zapcore.Field) *ObservedLogs {

// FilterFieldKey filters entries to those that have the specified key.
func (o *ObservedLogs) FilterFieldKey(key string) *ObservedLogs {
return o.filter(func(e LoggedEntry) bool {
return o.Filter(func(e LoggedEntry) bool {
for _, ctxField := range e.Context {
if ctxField.Key == key {
return true
Expand All @@ -116,13 +116,15 @@ func (o *ObservedLogs) FilterFieldKey(key string) *ObservedLogs {
})
}

func (o *ObservedLogs) filter(match func(LoggedEntry) bool) *ObservedLogs {
// Filter returns a copy of this ObservedLogs containing only those entries
// for which the provided function returns true.
func (o *ObservedLogs) Filter(keep func(LoggedEntry) bool) *ObservedLogs {
o.mu.RLock()
defer o.mu.RUnlock()

var filtered []LoggedEntry
for _, entry := range o.logs {
if match(entry) {
if keep(entry) {
filtered = append(filtered, entry)
}
}
Expand Down
15 changes: 14 additions & 1 deletion zaptest/observer/observer_test.go
Expand Up @@ -55,7 +55,7 @@ func TestObserver(t *testing.T) {
assert.Equal(t, want, logs.AllUntimed(), "Unexpected contents from AllUntimed.")

all := logs.All()
require.Equal(t, 1, len(all), "Unexpected numbed of LoggedEntries returned from All.")
require.Equal(t, 1, len(all), "Unexpected number of LoggedEntries returned from All.")
assert.NotEqual(t, time.Time{}, all[0].Time, "Expected non-zero time on LoggedEntry.")

// copy & zero time for stable assertions
Expand Down Expand Up @@ -219,6 +219,19 @@ func TestFilters(t *testing.T) {
filtered: sink.FilterFieldKey("filterMe"),
want: logs[7:9],
},
{
msg: "filter by arbitrary function",
filtered: sink.Filter(func(e LoggedEntry) bool {
return len(e.Context) > 1
}),
want: func() []LoggedEntry {
// Do not modify logs slice.
w := []LoggedEntry{}
w = append(w, logs[0:5]...)
w = append(w, logs[7])
return w
}(),
},
}

for _, tt := range tests {
Expand Down

0 comments on commit aefe3c4

Please sign in to comment.