|Reflex - the Customizable Event Correlation System|
The language reference contains two parts: a syntactic reference, and a semantic reference. Read the syntactic section to learn exactly how to format your Policy file, and the semantic section to learn exactly how the Reflex engine processes each incoming event.
Our event specification language is expressive and flexible. The grammar in EBNF is as follows:
<pattern-name>s are simply identifiers.
Note how the event sets must be in this order: reset, always, ordered, unordered.
When the system reads in a name/value pair from the event stream, the element that is created to model the pair dynamically determines the datatype of the value. It uses this method for determining:
Even though the system uses a pattern-specification language, there are some ways to implement familiar imperative language control structures like loops and conditionals.
Many times, one will want to see some number of events pass by and then trigger an alarm when that number exceeds some limit. In C, it may look like this:
This is also possible in our language using the always event set.
In the action part of an event, one might want to perform the action only if some condition qualifies. In C,
This is possible in our language as well. Events already come in the form
( some-condition ? some-action )
Using the ( ? ) syntax, conditional actions can be created.
The system is capable of describing and detecting more complicated patterns that are composed of sub-patterns. This is because when it matches a pattern, it sends out a new event describing the alarm. The elements of the event consist of PatternName, and any stored variables that that pattern-matching procedure picked up.
When the Small pattern is found, the system sends out an event with the attribute PatternName set as the name of the pattern "Small". When the Medium pattern is found, it also sends out an event with the PatternName as "Medium", but since the pattern keeps track of the SmallCount, that name/value pair is also part of the Medium event. The Big pattern only triggers when the SmallCount in the Medium event is greater than 5.
The operators used in our language are similar to the ones used in C++. Numbers are compared like normal, strings are compared lexically, and true and false are casted to 1 and 0 respectively, then compared. The same precedence rules apply, but parentheses may be used for clarification. Operators have been listed in order of precedence.
Our first task in designing Reflex was to determine our philosophies for it, so that we could argue about how it should behave when we had more than once choice. The easiest way to understand how it works, therefore, is to start with those same philosophies in hand.
Semantics -- Following an Event
A new event is passed to a Reflex engine via the Handle() function. Here's what happens:
The event goes from one pattern to the next, in the same order that the patterns were written in the policy. For each pattern, the event may be used only once.
First, the event is compared to each partial match for the pattern, starting with the oldest. For each partial match, the event is first examined as a possible 'reset' event. If it matches, the partial match is deleted and processing moves to the next pattern!
If not, the event is examined as an 'always' event. If it matches, the event may also match this partial match only as an ordered or unordered event. (This allows descriptions that examine only stored attributes to match, completing counting patterns and such). After the always match and possible ordered or unordered match, processing moves to the next pattern.
If not, the event is examined as an 'ordered' or 'unordered' event (ordered first). If it matches, the state of the partial match changes and processing moves to the next pattern. If the partial match was completed by this event, the partial match is deleted and sent out as an Alarm.
If this event has not matched this partial match at all, it attempts to match against the next partial match for this pattern.
If there are no more partial matches, the event is checked as an 'ordered' or 'unordered' event to create a new match (only the first ordered event, of course). If it matches, a new partial match is created. (If there are too many partial matches, the oldest for this pattern is discarded!) The limit defaults to 100 matches per pattern, and can be modified by editing the correlator engine code.
At this point, processing moves to the next pattern.
What just happened here? The event can be used by by each pattern once. It is checked against partial matches before getting the opportunity to create a new match. It is checked against the oldest partial match first.
The event is evaluated as a reset event, then an always event, then an ordered event, then an unordered event. (The same order as in the Policy file). If more than one description in a pattern can match the event, the first one written will match it.
If the event matches anything, the state of the partial match changes and all other partial matches are left alone. Processing resumes on the next pattern's partial match set.
If an event matches an always description, it is also allowed to match an ordered or unordered description for the same match. This allows patterns that count or collect events to have a final ordered or unordered description which will test for a completion condition and sent out the alarm when this happens.
This is how an Event is processed by the Reflex engine. To examine the exact code, check out the implementation of the Handle() function that the compiler produces for your Policy. If the behavior seems odd, run through the steps that the engine does and you'll often find why.
Copyright © 2001