diff --git a/log/zap/filter_core.go b/log/zap/filter_core.go index 43e5e6bdf6998358efcac389920511f5915fd322..35d24fe35ce6c1f3fd9c799c2a25e63a76bc9534 100644 --- a/log/zap/filter_core.go +++ b/log/zap/filter_core.go @@ -7,8 +7,8 @@ import ( type FilterFunc func(entry zapcore.Entry, fields []zapcore.Field) bool -func FilterField(field zapcore.Field) FilterFunc { - return func(entry zapcore.Entry, fields []zapcore.Field) bool { +func HasField(field zapcore.Field) FilterFunc { + return func(_ zapcore.Entry, fields []zapcore.Field) bool { for _, f := range fields { if f.Equals(field) { return true @@ -18,25 +18,53 @@ func FilterField(field zapcore.Field) FilterFunc { } } +func Or(filters ...FilterFunc) FilterFunc { + return func(entry zapcore.Entry, fields []zapcore.Field) bool { + for _, filter := range filters { + if filter(entry, fields) { + return true + } + } + return false + } +} + +func And(filters ...FilterFunc) FilterFunc { + return func(entry zapcore.Entry, fields []zapcore.Field) bool { + for _, filter := range filters { + if !filter(entry, fields) { + return false + } + } + return true + } +} + +func Not(filter FilterFunc) FilterFunc { + return func(entry zapcore.Entry, fields []zapcore.Field) bool { + return !filter(entry, fields) + } +} + type filterCore struct { zapcore.Core - filters []FilterFunc - fields []zap.Field + filter FilterFunc + fields []zap.Field } -func RegisterFilters(core zapcore.Core, filters ...FilterFunc) zapcore.Core { +func RegisterFilters(core zapcore.Core, filter FilterFunc) zapcore.Core { return &filterCore{ - Core: core, - filters: filters, + Core: core, + filter: filter, } } func (core *filterCore) With(fields []zapcore.Field) zapcore.Core { return &filterCore{ - Core: core.Core.With(fields), - filters: core.filters, - fields: append(core.fields, fields...), + Core: core.Core.With(fields), + filter: core.filter, + fields: append(core.fields, fields...), } } @@ -48,14 +76,12 @@ func (core *filterCore) Check(entry zapcore.Entry, checkedEntry *zapcore.Checked } func (core *filterCore) Write(entry zapcore.Entry, fields []zapcore.Field) error { - if len(core.filters) > 0 { + if len(core.fields) > 0 { fields = append(core.fields, fields...) } - for _, filter := range core.filters { - if !filter(entry, fields) { - return nil - } + if !core.filter(entry, fields) { + return nil } return core.Core.Write(entry, fields) diff --git a/log/zap/filter_core_test.go b/log/zap/filter_core_test.go index 211979752a21ceb071ce748fb0ed4e6d8eb02328..82ed4fba863d1cc55db3381c22914bc468054372 100644 --- a/log/zap/filter_core_test.go +++ b/log/zap/filter_core_test.go @@ -11,7 +11,7 @@ import ( func TestFilterCore_Write(t *testing.T) { core, logs := observer.New(zapcore.InfoLevel) - core = RegisterFilters(core, FilterField(zap.Bool("check", true))) + core = RegisterFilters(core, HasField(zap.Bool("check", true))) err := core.With([]zapcore.Field{zap.Bool("check", true)}).Write(zapcore.Entry{Message: "msg"}, nil) require.NoError(t, err) @@ -24,3 +24,64 @@ func TestFilterCore_Write(t *testing.T) { require.Equal(t, 2, logs.Len()) } + +func TestAnd(t *testing.T) { + core, logs := observer.New(zapcore.InfoLevel) + core = RegisterFilters(core, And( + HasField(zap.Int("a", 1)), + HasField(zap.Int("b", 2)), + )) + + err := core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{ + zap.Int("a", 1), + zap.Int("b", 2), + }) + require.NoError(t, err) + + err = core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{ + zap.Int("a", 1), + zap.Int("b", 3), + }) + require.NoError(t, err) + + require.Equal(t, 1, logs.Len()) +} + +func TestOr(t *testing.T) { + core, logs := observer.New(zapcore.InfoLevel) + core = RegisterFilters(core, Or( + HasField(zap.Int("a", 1)), + HasField(zap.Int("b", 2)), + )) + + err := core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{ + zap.Int("a", 1), + zap.Int("b", 3), + }) + require.NoError(t, err) + + err = core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{ + zap.Int("a", 3), + zap.Int("b", 2), + }) + require.NoError(t, err) + + require.Equal(t, 2, logs.Len()) +} + +func TestNot(t *testing.T) { + core, logs := observer.New(zapcore.InfoLevel) + core = RegisterFilters(core, Not(HasField(zap.Int("a", 1)))) + + err := core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{ + zap.Int("a", 1), + }) + require.NoError(t, err) + + err = core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{ + zap.Int("a", 2), + }) + require.NoError(t, err) + + require.Equal(t, 1, logs.Len()) +}