diff --git a/http/api/event.go b/http/api/event.go index 2e6c7448..52ea2205 100644 --- a/http/api/event.go +++ b/http/api/event.go @@ -51,7 +51,20 @@ func (e *Event) Marshal(le *log.Event) { } func (e *Event) Filter(ef *EventFilter) bool { - for k, r := range ef.data { + if ef.reMessage != nil { + if !ef.reMessage.MatchString(e.Message) { + return false + } + } + + if ef.reLevel != nil { + level := log.Level(e.Level).String() + if !ef.reLevel.MatchString(level) { + return false + } + } + + for k, r := range ef.reData { v, ok := e.Data[k] if !ok { continue @@ -67,8 +80,13 @@ func (e *Event) Filter(ef *EventFilter) bool { type EventFilter struct { Component string `json:"event"` + Message string `json:"message"` + Level string `json:"level"` Data map[string]string `json:"data"` - data map[string]*regexp.Regexp + + reMessage *regexp.Regexp + reLevel *regexp.Regexp + reData map[string]*regexp.Regexp } type EventFilters struct { @@ -76,15 +94,33 @@ type EventFilters struct { } func (ef *EventFilter) Compile() error { - ef.data = make(map[string]*regexp.Regexp) - - for k, v := range ef.Data { - r, err := regexp.Compile(v) + if len(ef.Message) != 0 { + r, err := regexp.Compile("(?i)" + ef.Message) if err != nil { return err } - ef.data[k] = r + ef.reMessage = r + } + + if len(ef.Level) != 0 { + r, err := regexp.Compile("(?i)" + ef.Level) + if err != nil { + return err + } + + ef.reLevel = r + } + + ef.reData = make(map[string]*regexp.Regexp) + + for k, v := range ef.Data { + r, err := regexp.Compile("(?i)" + v) + if err != nil { + return err + } + + ef.reData[k] = r } return nil diff --git a/http/api/event_test.go b/http/api/event_test.go index b5207e53..08375786 100644 --- a/http/api/event_test.go +++ b/http/api/event_test.go @@ -9,7 +9,7 @@ import ( func TestEventFilter(t *testing.T) { event := Event{ Timestamp: 1234, - Level: 0, + Level: 3, Component: "foobar", Message: "none", Data: map[string]string{ @@ -17,6 +17,42 @@ func TestEventFilter(t *testing.T) { }, } + filter := EventFilter{ + Component: "foobar", + Level: "info", + Message: "none", + } + + err := filter.Compile() + require.NoError(t, err) + + res := event.Filter(&filter) + require.True(t, res) + + filter = EventFilter{ + Component: "foobar", + Level: "warn", + Message: "none", + } + + err = filter.Compile() + require.NoError(t, err) + + res = event.Filter(&filter) + require.False(t, res) + + filter = EventFilter{ + Component: "foobar", + Level: "info", + Message: "done", + } + + err = filter.Compile() + require.NoError(t, err) + + res = event.Filter(&filter) + require.False(t, res) + foobarfilter := EventFilter{ Component: "foobar", Data: map[string]string{ @@ -24,9 +60,12 @@ func TestEventFilter(t *testing.T) { }, } - err := foobarfilter.Compile() + err = foobarfilter.Compile() require.NoError(t, err) + res = event.Filter(&foobarfilter) + require.True(t, res) + foobazfilter := EventFilter{ Component: "foobaz", Data: map[string]string{ @@ -37,9 +76,36 @@ func TestEventFilter(t *testing.T) { err = foobazfilter.Compile() require.NoError(t, err) - res := event.Filter(&foobarfilter) - require.True(t, res) - res = event.Filter(&foobazfilter) require.False(t, res) } + +func BenchmarkEventFilters(b *testing.B) { + event := Event{ + Timestamp: 1234, + Level: 3, + Component: "foobar", + Message: "none", + Data: map[string]string{ + "foo": "bar", + }, + } + + levelfilter := EventFilter{ + Component: "foobar", + Level: "info", + Data: map[string]string{ + "foo": "^b.*$", + }, + } + + err := levelfilter.Compile() + require.NoError(b, err) + + res := event.Filter(&levelfilter) + require.True(b, res) + + for i := 0; i < b.N; i++ { + event.Filter(&levelfilter) + } +} diff --git a/http/handler/api/events.go b/http/handler/api/events.go index f86d6729..d90c74b0 100644 --- a/http/handler/api/events.go +++ b/http/handler/api/events.go @@ -13,13 +13,12 @@ import ( "github.com/labstack/echo/v4" ) -// The EventsHandler type provides handler functions for retrieving details -// about the API version and build infos. +// The EventsHandler type provides handler functions for retrieving event. type EventsHandler struct { events log.ChannelWriter } -// NewEvents returns a new About type +// NewEvents returns a new EventsHandler type func NewEvents(events log.ChannelWriter) *EventsHandler { return &EventsHandler{ events: events,