Detecting the Absence of Status Events
Each self-service terminal publishes a
Status event every 1 minute. The
Status event indicates the terminal is alive and online. The absence of
Status events may indicate that a terminal went offline for some reason and that needs to be investigated.
Status events arrive in regular intervals of 60 seconds, we can make use of temporal pattern matching using timer to find events that didn't arrive. We can use the
every operator and
timer:interval() to repeat an action every 60 seconds. Then we combine this with a not operator to check for absence of
Status events. A 65-second interval during which we look for
Status events allows 5 seconds to account for a possible delay in transmission or processing:
select 'terminal 1 is offline' from pattern [ every timer:interval(60 sec) -> (timer:interval(65 sec) and not Status(term.id = 'T1'))] output first every 5 minutes
Since we way not want to see an alert for the same terminal every 1 minute, we added an
output first clause to indicate that we only want to be alerted the first time this happens, and then not be alerted for 5 minutes, and then be alerted again if it happens again.
Figure 2. The output first clause can suppress output events
Note that we hardcoded the terminal ID to
'T1' in this query for simplicity. As we are looking for an absent event, it would require to use a subquery to detect all terminal failures with one query.
As you read through those examples you probably already realize that Esper ESP/CEP query language expressiveness enables us to do declarative programming in a very loosely-coupled way thanks to the underlying Event Driven Architecture. Most of the detection logic mirroring our business specifications are directly written in statements and not in custom code.
Activity Summary Data
By presenting statistical information about terminal activity to our staff in real-time we enable them to monitor the system and quickly spot problems. To begin with, the real-time console should show a count of the number of check-in processes started, in progress, cancelled, and completed within the last 10 minutes.
This first query counts the number of
Checkin considering only the last 10 minutes of event data:
select count(*) from Checkin.win:time(10 minutes)
Note the use of the
win:time syntax. This tells the engine to consider a time window consisting of only the last 10 minutes of the
Checkin event stream.
We can improve this query and get a count per event type considering all types of events (
LowPaper) by using
BaseTerminalEvent. Again we want to look at only the last 10 minutes of events so we will use a
win:time view. We further want to get notified every 1 minute and not at each change, hence we will use an
output all clause:
select type, count(*) from BaseTerminalEvent.win:time(10 minutes) group by type output all every 1 minutes
Running the Application
The source code is provided in the download that accompanies the article.
- Sample code for this article
- Esper at CodeHaus.org
- CEP portal site with further information about Complex Event Processing
- ESP resource site for more information on Event Stream Processing
- Wikipedia on Event Stream Processing
Thomas Bernhardt is founder and project lead of the Esper open-source project. During the day, Thomas works as an architect at a major financial institution, implementing event-driven software systems.
Alexandre Vasseur works on Event-Driven Architectures and Java middleware and co-leads the Esper open source ESP/CEP project.
Return to ONJava.com.