Alerting when problems persist
Visit the pattern-matching-cep recipe on GitHub.Use case: Alert when a sensor remains hot for too long
In this recipe we are working with this data model for a SensorReading
class:
We are going to focus on detecting when a temperature sensor continuously reports a temperature that is above some threshold for some pre-determined period of time.
But the same pattern matching logic can be applied to other use cases where streaming analytics are used to trigger alerts. For example, you might want to count login attempts per minute, and raise an alert when that value exceeds some threshold for 3 minutes in a row. Or you might want an alert whenever a geo-fenced asset has reported itself outside the region where it is authorized to be for more than one minute.
Quick intro to Apache Flink's CEP library
Flink includes a Complex Event Processing library (called CEP, for short) that has extensive documentation .
The basic idea is that you define a pattern and apply that pattern to a stream. Every time CEP succeeds in matching that pattern to the stream, CEP calls a callback you've registered for processing the matches.
In this recipe, we want to define a pattern that matches as soon as a sensor has been continuously hot for some period of time.
Here's an initial attempt to define such a pattern:
What you are seeing above is a pattern sequence composed of two singleton patterns (each
matching only one event) combined into a sequence with followedBy
.
The first singleton pattern is named first-hot-reading, and it matches any
sensor
reading
satisfying
the condition reading.sensorIsHot()
.
The second singleton pattern (still-hot-later) is more complex. It uses
an IterativeCondition
to
match sensor readings that are hot and at least limitOfHeatTolerance
seconds after the
first-hot-reading:
This being an IterativeCondition
is what allows us
to look back at the sensor reading that matched the first-hot-reading part of the pattern sequence
and use it
to measure the time elapsed between that initial sensor reading and the one being currently
considered as a possible match for the still-hot-later condition.
The preliminary solution shown above isn't good enough. While it does successfully find situation where there are two hot sensor readings far enough apart, it doesn't correctly handle cases where the sensor has cooled off in-between those two readings.
Doing a better job
The pattern defined by MatcherV2
overcomes the problem described above
by inserting an additional condition that requires that the sensor not become
cool
in-between the first-hot-reading and the still-hot-later reading.
However, if your objective is to generate an alert when the pattern matches, you might be
dissatisfied
with MatcherV2
because it won't just match once, but will match again and again until the
temperature drops below the threshold:
Doing an even better job
If you only want to generate one alert from each hot streak, then the solution shown above isn't good enough. It could be addressed by extending the still-hot-later part of the pattern to continue matching until the temperature is no longer hot — but then the single alert would not be emitted until after the hot streak was over — and that's unacceptable (assuming you want real-time alerting).
MatcherV3
overcomes these problems, and also illustrates a somewhat different approach:
With this solution we have
- prevented a continuously hot sensor from matching more than once by requiring that each match begin when the sensor is cool
- used a looping pattern (rather than a singleton pattern in combination
with
notFollowedBy
) to capture the sequence of continuously hot readings - used
next
rather thanfollowedBy
to connect the individual patterns
The difference between next
and followedBy
is that next
only matches if there are no events
in-between the two simple patterns being connected, whereas followedBy
can skip over events that
aren't matched by either of those patterns.
This is the behavior of MatcherV3
:
The full recipe
This recipe is self contained. You can run the ProductionJobTests
to see the full recipe
in action with any of these matchers. Those tests use an embedded Apache Kafka and
Apache
Flink setup, so you can run them directly via
Maven or in your favorite editor such as IntelliJ IDEA or Visual Studio Code.
See the code and tests included in the Github repo for more details.