@@ -27,7 +27,6 @@ import (
2727 "github.com/rabbitstack/fibratus/pkg/filter/fields"
2828 "github.com/rabbitstack/fibratus/pkg/ps"
2929 "github.com/rabbitstack/fibratus/pkg/rules/action"
30- "github.com/rabbitstack/fibratus/pkg/util/hashers"
3130 log "github.com/sirupsen/logrus"
3231 "sync"
3332 "time"
5352// the collection of compiled filters that are derived
5453// from the loaded ruleset.
5554type Engine struct {
56- filters compiledFilters
55+ filters * filterset
5756 config * config.Config
5857 psnap ps.Snapshotter
5958
@@ -65,82 +64,42 @@ type Engine struct {
6564
6665 compiler * compiler
6766
68- hashCache * hashCache
69-
7067 matchFunc RuleMatchFunc
7168}
7269
7370type ruleMatch struct {
7471 ctx * config.ActionContext
7572}
7673
77- // hashCache caches the event type/category FNV hashes
78- type hashCache struct {
79- mu sync.RWMutex
80- types map [event.Type ]uint32
81- cats map [event.Category ]uint32
82- lookupCategory bool
83- }
84-
85- func newHashCache () * hashCache {
86- return & hashCache {types : make (map [event.Type ]uint32 ), cats : make (map [event.Category ]uint32 )}
87- }
88-
89- func (c * hashCache ) typeHash (e * event.Event ) uint32 {
90- c .mu .RLock ()
91- defer c .mu .RUnlock ()
92- return c .types [e .Type ]
93- }
94-
95- func (c * hashCache ) categoryHash (e * event.Event ) uint32 {
96- c .mu .RLock ()
97- defer c .mu .RUnlock ()
98- return c .cats [e .Category ]
99- }
100-
101- func (c * hashCache ) addTypeHash (e * event.Event ) uint32 {
102- c .mu .Lock ()
103- defer c .mu .Unlock ()
104- h := e .Type .Hash ()
105- c .types [e .Type ] = h
106- return h
107- }
108-
109- func (c * hashCache ) addCategoryHash (e * event.Event ) uint32 {
110- c .mu .Lock ()
111- defer c .mu .Unlock ()
112- h := e .Category .Hash ()
113- c .cats [e .Category ] = h
114- return h
115- }
116-
11774type compiledFilter struct {
11875 filter filter.Filter
11976 config * config.FilterConfig
12077 ss * sequenceState
12178}
12279
123- type compiledFilters map [uint32 ][]* compiledFilter
80+ // filterset contains compiled filters indexed by event type and category.
81+ type filterset struct {
82+ types map [event.Type ][]* compiledFilter
83+ categories map [uint8 ][]* compiledFilter
84+ }
12485
125- // collect collects all compiled filters for a
126- // particular event type or category. If no filters
127- // are found, the event is not asserted against the
128- // ruleset.
129- func (filters compiledFilters ) collect (hashCache * hashCache , e * event.Event ) []* compiledFilter {
130- h := hashCache .typeHash (e )
131- if h == 0 {
132- h = hashCache .addTypeHash (e )
86+ func newFilterset () * filterset {
87+ fs := & filterset {
88+ types : make (map [event.Type ][]* compiledFilter ),
89+ categories : make (map [uint8 ][]* compiledFilter ),
13390 }
91+ return fs
92+ }
13493
135- if ! hashCache . lookupCategory {
136- return filters [ h ]
137- }
94+ func ( f * filterset ) empty () bool {
95+ return len ( f . types ) == 0 && len ( f . categories ) == 0
96+ }
13897
139- c := hashCache . categoryHash ( e )
140- if c == 0 {
141- c = hashCache . addCategoryHash ( e )
98+ func ( f * filterset ) collect ( e * event. Event ) [] * compiledFilter {
99+ if len ( f . categories ) == 0 {
100+ return f . types [ e . Type ]
142101 }
143- return append (filters [ h ], filters [ c ]... )
102+ return append (f . types [ e . Type ], f . categories [ e . Category . Index () ]... )
144103}
145104
146105func newCompiledFilter (f filter.Filter , c * config.FilterConfig , ss * sequenceState ) * compiledFilter {
@@ -172,14 +131,13 @@ func (f *compiledFilter) run(e *event.Event) bool {
172131// NewEngine builds a fresh rules engine instance.
173132func NewEngine (psnap ps.Snapshotter , config * config.Config ) * Engine {
174133 e := & Engine {
175- filters : make ( map [ uint32 ][] * compiledFilter ),
134+ filters : newFilterset ( ),
176135 matches : make ([]* ruleMatch , 0 ),
177136 sequences : make ([]* sequenceState , 0 ),
178137 psnap : psnap ,
179138 config : config ,
180139 scavenger : time .NewTicker (sequenceGcInterval ),
181140 compiler : newCompiler (psnap , config ),
182- hashCache : newHashCache (),
183141 }
184142
185143 go e .gcSequences ()
@@ -217,6 +175,7 @@ func (e *Engine) Compile() (*config.RulesCompileResult, error) {
217175 // for more convenient tracking
218176 e .sequences = append (e .sequences , ss )
219177 }
178+
220179 if ! fltr .isScoped () {
221180 log .Warnf ("%q rule doesn't have " +
222181 "event type or event category condition! " +
@@ -227,18 +186,21 @@ func (e *Engine) Compile() (*config.RulesCompileResult, error) {
227186 c .Name )
228187 continue
229188 }
189+
230190 // traverse all event name or category fields and determine
231191 // the event type from the filter field name expression.
232- // We end up with a map of rules indexed by event name
233- // or event category hash
192+ // We end up with a map of rules indexed by event type
193+ // or event category
234194 for name , values := range f .GetStringFields () {
235195 for _ , v := range values {
236- if name == fields .EvtName || name == fields .EvtCategory {
237- if name == fields .EvtCategory {
238- e .hashCache .lookupCategory = true
196+ switch name {
197+ case fields .EvtName :
198+ for _ , typ := range event .NameToTypes (v ) {
199+ e .filters .types [typ ] = append (e .filters .types [typ ], fltr )
239200 }
240- hash := hashers .FnvUint32 ([]byte (v ))
241- e .filters [hash ] = append (e .filters [hash ], fltr )
201+ case fields .EvtCategory :
202+ category := event .Category (v )
203+ e .filters .categories [category .Index ()] = append (e .filters .categories [category .Index ()], fltr )
242204 }
243205 }
244206 }
@@ -258,10 +220,10 @@ func (*Engine) CanEnqueue() bool { return true }
258220// Filters can be simple direct-event matchers or sequence states that
259221// track an ordered series of events over a short period of time.
260222func (e * Engine ) ProcessEvent (evt * event.Event ) (bool , error ) {
261- if len ( e .filters ) == 0 {
223+ if e .filters . empty () {
262224 return true , nil
263225 }
264- var matches bool
226+
265227 if evt .IsTerminateProcess () {
266228 // expire all sequences if the
267229 // process referenced in any
@@ -270,7 +232,10 @@ func (e *Engine) ProcessEvent(evt *event.Event) (bool, error) {
270232 seq .expire (evt )
271233 }
272234 }
273- filters := e .filters .collect (e .hashCache , evt )
235+
236+ filters := e .filters .collect (evt )
237+
238+ var matches bool
274239 for _ , f := range filters {
275240 match := f .run (evt )
276241 if ! match {
@@ -293,6 +258,7 @@ func (e *Engine) ProcessEvent(evt *event.Event) (bool, error) {
293258 return true , nil
294259 }
295260 }
261+
296262 return matches , nil
297263}
298264
0 commit comments