Advanced Search
HomeTechnical DocumentsTipsTivoliEnterprise Console › TEC Rule Writing - how to use Assertion Lists

TEC Rule Writing - how to use Assertion Lists

Sometimes the customers require the events to be hidden until a threshold is met. This can be done in various ways in TEC, but this tip will look at how to make use of the assertion list in rule writing to solve this problem.

The Problem:

A number of ports from a server can be up or down. The server sends events with the name of the server and the port number with its state 'UP' or 'DOWN'. TEC should only generate an event on the console if there are more than three ports down at the same time. One port can be down for months without any action being necessary.

Assumption: Each port name is unique.

The following diagram illustrates the event:

The Solution:

The events are stored in an assertion list within the rule engine. Normally if the Event Server is stopped the events in the assertion list are lost. However in this solution each time an a port is added to the assertion list it is 'exported' to an external file (tec_r.server_ports). The next time the Event Server starts this file is checked and if it exists it is loaded back into the rule base. The incoming event is added to the list of ports that are down, counted and compared with the threshold. If the threshold is met an event is generated with the status 'CRITICAL'.

Reception action to read the external file into the assertion list

Open in New Window
        reception_actionread_config_file:
        (
                
exists('/Tivoli/custom/server/tec_r.server_ports'),
                
compile('/Tivoli/custom/server/tec_r.server_ports'),
                
consult('/Tivoli/custom/server/server_ports')
        ),
?>

The reception_action read_config_filechecks the existents of the file, compiles it and then reads it in with the consult function.

NOTE: compile does not work on NT. The file has to read in line-by-line and added to the assertion list.

Reception action to count the ports being down


Open in New Window
        reception_actionport_counter:
        (
                
assert((port_count(_port) :-

                
server_ports(_port_host),
                
ports_down(_host_prev_count),

                
_new_count is _prev_count 1,
                
retract(ports_down(_host_prev_count)),
                
assert(ports_down(_host_new_count)), cut;

                
true
                
))
        ),
?>

The reception_action port_counter finds out the previous number of ports down and adds one to the assertion list ports_down. The iteration will stop at the cut, the true means the action will never fail.

Rule for the incoming events with the classServerPortStatus with port_status slot value 'DOWN'

Open in New Window
ruleserver_port_down:
(
        
event_event of_class 'ServerPortStatus'
                
where [
                        
hostname_hostname,
                        
port_port,
                        
port_statusequals 'DOWN'
                
],

        
reception_actioncheck_known_ports:
        (
                
server_ports_port_hst),
                
drop_received_event,
                
commit_set
        
),

        
reception_actionadd_port_down:
        (
                
assert(server_ports_port_hostname )),

                
tell('/Tivoli/custom/server/tec_r.server_ports'),
                
listing(server_ports),
                
told

        
),

        
reception_actionreset_port_counter:
        (
                
retract(ports_down(_hostname_ports))
        ),

        
reception_actionrecount_ports_down:
        (
                
assert(ports_down(_hostname0)),
                
server_ports(_prt_hostname),
                
port_count(_prt)
        ),


        
reception_actionif_critical:
        (
                
ports_down(_hostname_port_counter),
                
_port_counter >= 3,

                
sprintf(_msg'%d Ports down'_port_counter),
                
generate_event('Server_Ports',
                        [
                                
source 'EVENT',
                                
hostname _hostname,
                                
severity 'CRITICAL',
                                
msg _msg
                        
]
                )

        ),

        
reception_actionalways_drop_this_event:
        (
                
drop_received_event,
                
commit_set
        
)

).
?>

The following table will explain what each action does:


Action

Description

check_known_ports

If this port is known as down the event is dropped and the rule finishes

add_port_down

If this port is not known it is added to the assertion list server_ports of ports down. The whole list is written out to the file tec_r.server_ports.

reset_port_counter

The number of ports is reset to zero. Observe that the old counter value has to be removed within an action. This is because the action will fail if the assertion list does not exist and move on to the next action.

recount_ports_down

The next action is to set the counter to zero and then all the ports are recounted.

if_critical

Then if the number of ports is larger or equal to three a message is sent to TEC.

always_drop_this_event

The incoming event is always dropped.

Rule for the incoming events with the class ServerPortStatus with the port_status slot value 'UP':

Open in New Window
ruleserver_port_up:
(
        
event_event of_class 'ServerPortStatus'
                
where [
                        
hostname_hostname,
                        
port_port,
                        
port_statusequals 'UP'
                
],

        
reception_actioncheck_server_ports:
        (
                
not(server_ports_port_hostname)),
                
drop_received_event,
                
commit_set
        
),

        
reception_actionupdate_ports_down:
        (
                
retract(server_ports_port_hostname)),

                
tell('/Tivoli/custom/server/tec_r.server_ports'),
                
listing(server_ports),
                
told

        
),

        
reception_actionreset_counter:
        (
                
retract(ports_down_hostname_counter))
        ),

        
reception_actioncount_ports_down:
        (
                
assert(ports_down(_hostname0)),
                
server_ports(_prt_hostname),
                
port_count(_prt)
        ),

        
reception_actioncheck_server:
        (
                
ports_down(_hostname_port_counter),
                
_port_counter >= 3,

                
sprintf(_msg'%d Ports down'_port_counter),
                
generate_event('Server_Ports',
                        [
                                
source 'EVENT',
                                
hostname _hostname,
                                
severity 'CRITICAL',
                                
msg _msg
                        
]
                ),

                
drop_received_event,
                
commit_set
        
),

        
reception_actionserver_is_healthy:
        (
                
first_instance(
                        
event_matched_event of_class 'Server_Ports'
                                
where [
                                        
statusoutside 'CLOSED' ],
                                        
hostnameequals _hostname
                                
]),

                
change_event_status(_matched_event'CLOSED'),
                
re_mark_as_modified(_matched_event,_)
        ),

        
reception_actionalways_drop_this_event:
        (
                
drop_received_event,
                
commit_set
        
)

).
?>

Following table explains what each action does.

Action

Description

check_server_ports_down

Check the assertion list for server ports down. If yes processed to the next action. If no drop this event and commit this rule set.

update_ports_down

The port is removed from the the assertion list server_ports, and the file tec_r.server_ports is updated.

reset_counter

The number of ports is reset to zero. See previous explanation.

re_count_ports_down

The next action is to set the counter to zero and then all the ports are recounted.

check_server

If the number of ports down still is more than three a Server_Ports event is sent with the new number of ports down to the Event Server

if_server_healthy

If the number of ports is less than three and the Server_Ports event is found it is closed

always_drop_this_event

The incoming event is always dropped

The rule set used in this example is ServerPortDown.rls.

These are the classes that need to be added for this exercise



Open in New Window
TEC_CLASS :
    
Server_Ports ISA EVENT
    DEFINES 
{
            
Severity: default = 'CRITICAL';
    };
END

TEC_CLASS 
:
        
ServerPortStatus ISA EVENT
        DEFINES
        
{
                
port:           STRING;
                
port_status:    STRING;
        };
END?>