Creating a Monitor to Listen for Events
In this lesson, you will write an EPL program that monitors events coming into the correlator from a simulated event feed (the SensorTest.evt file). The correlator can understand these events because you created definitions for them in the SensorMonitorEvents.mon event definition file.
Your EPL program will instruct the correlator to monitor the Temperature events for a single sensor ID (“S001”). The correlator will check the data types of the incoming events to make sure that they match the data types provided in the event type definitions. Each time it detects a matching temperature event, the correlator will send information to the console.
Creating the monitor
-
Right-click on the monitors folder and create a new file called
SensorMonitor.mon
. -
Open
SensorMonitor.mon
. The basic template of a monitor can be generated automatically by typingmonitor
and selecting the auto-complete suggestion (generated by the Apama Extension for Visual Studio Code). The generated content will be as follows:
/**
* This monitor is responsible for...
*/
monitor SensorMonitor {
action onload() {
log "Started monitor SensorMonitor.";
}
}
onload()
action. When a monitor is injected into the correlator, the correlator executes the monitor’s onload()
action.Creating your first rule
As the first rule for this monitor, you will write code that references the Temperature event type in the eventdefinitions/SensorMonitorEvents.mon file (that you defined as part of the “Defining Types of Events” lesson). Note that in the SensorTest.evt file, each Temperature and Pressure event is sent in on a specific channel. The monitor must first subscribe to that channel.
- Write the following code that uses the
monitor.subscribe("channel")
method to subscribe to the channel that the event data is sent into the correlator on:
action onload() {
// Subscribe to events.
monitor.subscribe("Factory1");
}
- Write the following code that listens for all
Temperature
events where the value of the sensor ID is “S001”:
monitor SensorMonitor {
action onload() {
// Subscribe to events.
monitor.subscribe("Factory1");
// Listen for all temperature events where ID = S001.
on all Temperature (sensorId="S001"){ }
}
}
- Save your changes.
- The
monitor.subscribe
method subscribes the context that the monitor is running in to the named channel. Without it, the correlator will not send events on that channel to the context and thus to the monitor. Subscribe to the channel on which data is sent in each monitor that listens for those events. The subscription is owned by the monitor, so when the monitor terminates, the subscription will end. Multiple subscriptions in a context are merged, so the existence of any subscription in a context will cause events to be sent to that context. This is particularly useful when using multiple contexts See Process Multiple Monitor Instances Simultaneously. Events on the default channel (which do not have a named channel in the evt file) are available to the main context and other public contexts. - In EPL, the
on
statement tells the correlator to create alistener
, a construct that watches for specified events. The correlator observes the events, analyzing each event in turn until it finds a sequence of events that match the listener’s event expression. When this happens the listener triggers, causing the correlator to execute the listeneraction
(defined in the next step). At this point, depending on the form of the event expression, the listener either terminates or continues listening for other matching event sequences. - The
all
keyword extends theon
command to listen for all events that match the specified pattern. Without theall
keyword, the listener would listen for only the first matching event. In this example, without theall
keyword, the listener would terminate after it finds one Sensor ID S001 event. - In EPL, an
action
is just a function that can be called. An action is similar to a method in other programming languages, such as Java and C++.
Making your rule do some work
- For this listener’s action, add code that prints the text “Temperature received”.
monitor SensorMonitor {
action onload() {
// Subscribe to events.
monitor.subscribe("Factory1");
// Listen for all temperature events.
on all Temperature (sensorId="S001"){
// Print the temperature.
print "Temperature received.";
}
}
}
- Save your changes.
sensorId
field that has a value of S001
, it sends the text “Temperature received”.Testing the code
-
Open a terminal window, and start the correlator using:
correlator -p 5000
. Keep this terminal window open. -
Create a new terminal window in the project folder, run
engine_inject eventdefinitions/SensorMonitorEvents.mon monitors/SensorMonitor.mon -p 5000
. This will add the defined events, and your monitor into the correlator. -
Run
engine_send events/SensorTest.evt -p 5000
. Go back to yourcorrelator
terminal window, and you should see the following text:Temperature received. Temperature received. Temperature received. Temperature received.
-
You can terminate the
correlator
by sending a signal interrupt into the terminal window: this is usually by pressing CTRL+C (Command+C for macOS users).
These commands are used to inject monitor files, and send event files into the running correlator instance. In the above examples, we have used the example port 5000
, but any valid and open port on your machine can be used.
engine_inject <MON_FILE(S)> -p <CORRELATOR_PORT>
engine_send <EVT_FILE(S)> -p <CORRELATOR_PORT>
To test any code you write in this tutorial, you should follow these steps.
Copying the event into a variable
EPL supports the ability to copy an event into a variable. This process is called coassignment. Follow these steps to coassign found Temperature events to a variable:
-
Open the
monitors/SensorMonitor.mon
file. -
Use the
as
operator to coassign each Temperature event to a variable calledtemperature
:on all Temperature (sensorId="S001") as temperature {...}
The variable is only in scope in the processing block of the listener and has no effect on clashing local or global variables.
-
Update the print statement to use this variable:
print "Temperature received: "+temperature;
-
Save your changes.
Follow the steps from “Testing the code” to run your updated monitor. You should now see output such as:
Temperature received: Temperature("S001",90) Temperature received: Temperature("S001",100) Temperature received: Temperature("S001",111) Temperature received: Temperature("S001",120)
You can import the completed solution for this lesson:
In the Apama Samples Git repository, navigate to the tutorials/EPL_Fundamentals_Completed
directory.