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.

Since 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:

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 (Checkin, Completed, Cancelled, Status, OutOfOrder, 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.

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.