Apama 10.15.0 | Developing Apama Applications | Developing Apama Applications in EPL | Defining Monitors | Example of a simple monitor
 
Example of a simple monitor
The empty monitor discussed in About monitor contents does not do anything. To write a useful monitor, add the following:
*An event type definition
*A global variable declaration
*An event expression that indicates the pattern to monitor for
*An action that operates on an event that matches the specified pattern
For example, the EPL below
*Defines the StockTick event type, which is the event type that the monitor is interested in.
*Defines the newTick global variable, which is accessible by all actions within this monitor. The newTick variable can hold a StockTick event.
*Registers an interest in all StockTick events.
*Invokes the processTick() action when it finds a StockTick event. The processTick() action uses the log statement to output the name and price of all StockTick events received by the correlator.
Lines starting with // are comments. EPL also supports the standard C++/Java /* ... */ multi-line comment syntax.
// Definition of the event type that the correlator will receive.
// These events represent stock ticks from a market data feed.
event StockTick {
   string name;
   float price;
}
 
// A simple monitor follows.
monitor SimpleShareSearch {
   // The following is a global variable for storing the latest
   // StockTick event.
   StockTick newTick;
     // The correlator executes the onload() action when you inject the
     // monitor.
     action onload() {
       on all StockTick(*,*):newTick processTick();
     }
     // The processTick() action logs the received StockTick event.
     action processTick() {
       log "StockTick event received" +
          " name = " + newTick.name +
          " Price = " + newTick.price.toString() at INFO;
    }
}
About the variable in the example
The single global variable is of the event type StockTick. A variable can be of any primitive type (boolean, decimal, float, integer, string), or any reference type (action, context, dictionary, event, listener, location, sequence or stream).
About the onload() action
In this example, the onload() action contains only one line of code:
on all StockTick(*,*):newTick processTick();
This line specifies the following:
*on all StockTick(*,*) indicates the event to look for.
The on statement begins the definition of an event listener. It means, when the following event (or a pattern of events) is received …. This event listener is looking for all StockTick events. The asterisks indicate that the values of the StockTick event fields do not matter.
*:newTick processTick(); indicates what to do when a StockTick event is found.
If the event listener finds a StockTick event, the coassignment (:) operator indicates that you want to copy the found event into the newTick global variable. The onload() action then invokes the processTick() action.
About event listeners
The on statement must be followed by an event expression. An event expression specifies the pattern you want to match. It can specify multiple events, but this simple example specifies a single event in its event expression. For details, see About event expressions and event templates.
The all keyword extends the on statement to listen for all events that match the specified pattern. Without the all keyword, the event listener would listen for only the first matching event. In this example, without the all keyword, the event listener would terminate after it finds one StockTick event.
In the sample code, the event expression is StockTick(*,*). Each event expression specifies one or more event templates. Each event template specifies one event that you want to listen for. The StockTick(*,*) event expression contains one event template.
The first part of an event template defines the type of event the event listener is looking for (in this case StockTick). The section in parentheses specifies filtering criteria for contents of events of the desired type. In this example, the event template sets both fields to wildcards (*). This declares an event listener that is interested in all StockTick events, regardless of content.
When an event listener finds a matching event, the listener can use the as operator to place the event into an implicitly declared variable only available in the scope of the listener processing block or the : assignment operator to place that event in a global or local variable. For example:
on StockTick(*,*) as newTick {
processTick(newTick);
}
This copies a StockTick event into the newTick variable which is only in scope of the processing block. This is known as implicit coassignment.
Or:
on all StockTick(*,*):newTick processTick();
This copies a StockTick event into the newTick global variable. This is known as a variable coassignment.
Finally, the on statement invokes the processTick() action. For all received StockTick events, regardless of content, the sample monitor copies the matching event into the newTick global variable, and then invokes the processTick() action. For details, see Using global variables.
About the processTick() action
The processTick() action executes the log statement to output some data on the registered logging device, which by default is standard output. This log statement is used to report some of the fields from the received event. For details, see Logging and printing.
Accessing fields in events
EPL uses the . operator to access the fields of an event. You can see that the processTick() action uses the . operator to retrieve both the name (newTick.name) and price (newTick.price) fields of each event.
The log statement requires strings as fields, so the processTick() action specifies the built-in .toString() operation on the non-string value:
newTick.price.toString()