|
|
Rules files were introduced in "Introduction to Info Mediators."
Rules files use their own language to process raw event source data into Cisco Info Center alerts. This section is a reference to the functions, statements, operations, and techniques that can be used within rules files. It also contains examples of typical rules file segments to show how the rules file language can be applied.
This chapter contains the following sections:
"Rules File Syntax," also contains rules file related information.
All of the following comparison functions can be used within the if statement. This enables different field values to be set depending on the event acquired. The if statement is typically used to set the @Summary, @Identifier, and @Severity fields.
This function compares an element or field (the variable) with another string (the expression) and returns true when the contents of the element or field match exactly with the value of the expression. This function has the following syntax:
match(variable,expression) This function compares an element or field (the variable) with another string (the expression) and returns true when the contents of the variable, up to the length of the value of the expression, matches exactly the value of the expression. For example, nmatch(something,some) would be true, nmatch(something,somethings) would be false. This function has the following syntax:
This function compares an element, field, or the result of a string expression with a regular expression string, and returns true when the contents of the element or field match the regular expression. This function has the following syntax:
regmatch(expression,regexp)This function tests for the existence of a particular named element. When the element exists, this returns true. The exists function is used for checking available information where the range of elements generated by the event source varies. This function has the following syntax:
exists(element)The event processing functions manipulate whole events.
The stand-alone function remove, deletes the information associated with the named element so it will not be placed into the details table on the Cisco Info Server. See "The Details Statement" section for more information. This function has the following syntax:
remove(elementname) The stand-alone function discard, removes the entire event, stopping it from being forwarded to the Cisco Info Server. Discarded events can be retrieved with the recover function. This function has the following syntax:
The standalone function recover, retrieves a previously discarded event. This operation has the following syntax:
recoverThe Cisco Info Server details table (alerts.details) is used to store elements which are not added to the fields of the alert. These details can be viewed by double-clicking on an event in the Event List.
Details are added to the alerts.details table with the details statement. They are only added when an event is inserted. It is possible to define different details for different events using if statements.
To add the elements $a and $b to the alerts.details table, you include the following statement in the rules file:
details($a,$b)
To add all of the event information into the alerts.details table, you include the following statement in the rules file:
details ($*)
![]() |
Note We recommend you do not use ($*), because events forwarded to the Cisco Info Server in this way are not processed normally. When you use ($*) for long periods of time, your Cisco Info Server tables become too large and the performance of the Cisco Info Server suffers. You should only use ($*) when you are debugging or writing rules files. |
In the following example, $Summary is compared to the strings Incoming and Backup. When there is no match, $Summary is set to the string "Please see details", and all of the information for the event is added to the details table:
if (match($Summary, "Incoming"))
{
@Summary = "Received a call"
}
else if(match($Summary, "Backup"))
{
@Summary = "Attempting to back up"
}
else
{
@Summary = "Please see details"
details($*)
{
The switch/case statement is used to test for exact matches. This statement should be used wherever possible in place of if statements, as the rules contained within switch/case statements process more efficiently, and therefore, execute more quickly. This statement has the following syntax:
switch(expression)
{case "<stringliteral>":rulescase "<stringliteral>":rules...defaultrules}
The expression value can be any valid expression, for example:
switch($node)
switch(@Summary)
the stringliteral can be any value; however, it cannot be an expression. For example, the following are both valid:
case "jupiter"case "Link Down"
There is no limit on the number of rules contained within each case. The cases can contain all of the statements, expressions, and functions you would normally include in a rules file, including switch statements.
A number of case labels can share the same set of rules. For example:
case "stringliteral 1" | "stringliteral 2" | "stringliteral 3":
{
....
![]() |
Note Switch/case statements must contain a default case even when no rules associated with it. Also, there is no fall through from one case statement to the next, therefore, there is no need for a break statement. |
The SERVICE command is used in Cisco Info Center/Internet Service Monitors rules files. When you are not using Cisco Info Center/Internet Service Monitors, you can ignore this command.
The SERVICE command is used to define the status of a service before it is forwarded to the Cisco Info Server. The status changes the color of the service status event when it is displayed in the Event List and Service window.
The syntax of the SERVICE command is:
SERVICE (service_identifier, service_status)The service_identifier parameter identifies the monitored service. For example, the rules files could use $service on $host as the identifier.
The service_status parameter can be GOOD, BAD, or MARGINAL, as shown in Table 2-1.
| Service Status Level | Definition |
|---|---|
BAD | The service level agreement is not being met. |
MARGINAL | There are some problems with the service. |
GOOD | There are no problems with the service. |
No Level Defined | The status of the service is unknown. |
It may be necessary sometimes to extract extra data from an element created by the Info Mediator. For example, if the Info Mediator has created the following element from the event:
$Summary="The Port is down on Board 2 Port 1"
but the Board and Port values are not held in any other element, then these values can be extracted from the string by the following statements:
$temp1=extract($Summary,".*Port ([0-9]+).*")
$temp2=extract($Summary,".*Board ([0-9]+).*")
@AlertKey = $temp1 + "." + $temp2
The Board and Port values need to be extracted from the element and placed in the @AlertKey field. Any information contained within the parenthesis is extracted into the field values. In this example, two temporary strings are used: $temp1 and $temp2. These fields are then concatenated and placed in the AlertKey field, which is forwarded to the Cisco Info Server.
Returns the part of the string (which may be a field, element, or string expression) that matched the parenthesized section of the regular expression. This operation has the following syntax:
extract(expression,regexp) For example, where $example is "abc123def":
extract($example,"abc([0-9]+)def")
returns 123.
Messages are logged with the log function, which accepts the message and a logging level. There are five levels of messages: DEBUG, INFO, WARNING, ERROR, and FATAL. These are assigned numeric values, as shown in Table 2-2.
| Level | Value |
|---|---|
FATAL | 5 |
ERROR | 4 |
WARNING | 3 |
INFO | 2 |
DEBUG | 1 |
When a logging level is set (using the setlog function), only messages equal to or above that level are logged. For example, when the logging level is set to WARNING (3), only WARNING, ERROR, and FATAL messages are logged. When the logging level is set to ERROR (4), only ERROR and FATAL messages are logged.
Sends a message to the logging system at a set logging level. The log level may be DEBUG, INFO, WARNING, ERROR, FATAL, or a numeric value. The syntax of this function is:
log([DEBUG | INFO | WARNING | ERROR | FATAL | numexpression],"string")Sets the minimum level of messages to be logged. The logging system records the logging status before entering the rules engine and resets the logging status when the rules engine finishes with an event. By default, the setting for logging is WARNING. The syntax of this function is:
setlog([DEBUG | INFO | WARNING | ERROR | FATAL | numexpression]) setlog(WARNING)
log(DEBUG,"A debug message")
log(WARNING,"A warning message")
setlog(ERROR)
log(WARNING,"Another warning message")
log(ERROR,"An error message")
This produces a log output of:
The debug message is not logged, because the logging setting is set higher than DEBUG. The second warning message is not logged, because the setlog function has set the logging level higher than WARNING.
The message logging functions allow you to trace operation of rules processing.
The following string functions can be used to manipulate string elements within rules files.
The upper function converts a string to upper case. This function has the following syntax:
upper(string)The lower function converts a string to lower case. This function has the following syntax:
lower(string)The length function calculates the length of a string in characters. This function has the following syntax:
length(string)The rtrim function removes any white space from the right of a string. This function has the following syntax:
rtrim(string)The ltrim function removes any white space from the left of a string. This function has the following syntax:
ltrim(string) The substr function extracts a substring (substring) from a string given the start position (n) and the length (len) of the string to be extracted. This is more efficient than the extract regular expression. This function has the following syntax:
The printable function removes any special non-printable characters from a string. This function has the following syntax:
printable(string)@Upper = upper(@Node)@Lower = lower(@Node)@Length = length(@Node)@Trim = ltrim(@Node)@Trim = rtrim(@Node)@Substring = substr(@Node, 2, 10)@Print = printable(@Node)
All of the above examples show how to use the string functions. In all but the substr function, the required parameter is the field or token name. The substr function also requires the offset from the left-hand side of the string and the length of the string to extract.
The following function can be used to convert string elements into dates or times within rules files.
The DatetoTime function converts a string into a time or date. This function uses the C library function strptime(). See the strptime() man page for more information about this function and its conversion specifications. The DatetoTime function has the following syntax:
DatetoTime(string, "conversion_specifications")
The TimetoDate function converts a numeric time value into a string. This function uses the C library function strftime(). Refer to the strftime() man page for more information about this function and its conversion specifications.
This function has the following syntax:
TimetoDate(numeric, "conversion_specifications")
The GetDate function returns the current date as an integer value. It uses the UNIX time system (the number of seconds since midnight on January 1 1970).
The following utility functions allow you to obtain more information about the environment that the probe is running in.
The hostname function returns the name of the host running the probe. The function has the following syntax:
hostname()Below is an example:
$My_Hostname = hostname()
The getpid function returns the process ID of the running probe. The function has the following syntax:
getpid()Below is an example:
$My_PID = getpid()
The getenv function returns the value of a given environment variable. The function has the following syntax:
getenv(string)Below are two examples:
$My_Path = getenv("PATH")
$My_OMNIHOME = getenv("OMNIHOME")
Lookup tables provide a method for adding extra information into an event. A table is made up of a list of keys and values. It is defined by using the table keyword and accessed using the lookup keyword. A lookup table can be defined in two ways, either within a file or within the rules file itself.
The lookup keyword evaluates the expression in the keys of the named table and returns the associated value. When the key is not found, an empty string is returned. The lookup function has the following syntax:
lookup(<expression>,<tablename>)Table definitions must appear at the start of a rules file, before any processing statements. There can be multiple tables defined within each rules file. For the Info Mediator to use any changes made to a lookup table, it must be restarted.
A lookup table can be defined directly within the rules file itself using the following format:
table tablename={{"<key>","<value>"},{"<key>","<value>"}}
This can be used to create a table that matches a node name to the department the node belongs. For example:
table dept={{"node1","Technical"},{"node2","Finance"}}
This could be used in the rules file as follows:
@ExtraChar=lookup(@Node,dept)
This example uses the @Node field as the key. When the value in the event matches the key of the table, it places the second value in @ExtraChar.
Rather than defining the table within the rules file itself, it is possible to define the table within a separate file. The file must be in the following format:
<key>[TAB]<value> <key>[TAB]<value>
To define the table dept used in the previous example, create a file called dept in the following format:
node1[TAB]Technicalnode2[TAB]Finance
Within the rules file, the table is used as follows:
table dept="/opt/Omnibus/probes/solaris2/Dept"@ExtraChar=lookup(@Node,dept)
A lookup table can also have multiple columns when building the table within the rules file. For example:
table example_table =
{{"key1", "value1", "value2", "value3"},
{"key2", "val1", "val2", "val3"}}
default = {"defval1", "defval2", "defval3"}
An example of how to obtain the values from a multi-value lookup table:
[@Summary, @AlertKey, $error_code] = lookup("key1", "example_table")
![]() |
Note It is important to note that the number of values in every row of the lookup table, and the number of values obtained from the lookup command must match. If they do not, a rules parse error will be generated. |
To explain this further, the following examples are incorrect:
table example_table =
{{"key1", "value1", "value2", "value3"},
{"key2", "val1", "val2"}}
This is incorrect because the first entry has three values while the second only has two values.
table example_table =
{{"key1", "value1", "value2", "value3"},
{"key2", "val1", "val2", "val3"}} [@Summary, @AlertKey] = lookup("key1", "example_table")
This is incorrect because the lookup table holds three values, but only two variables are being set by the lookup command.
Default options can be set when an event does not match any of the key values within a table. The default statement must follow the specific table definition and is used in the rules files as follows:
table dept="/opt/Omnibus/probes/solaris2/Dept"
default="UNKNOWN"
It is possible to split rules files into many smaller sections of rules using 'include'. For example:
if(match(@Manager, "ProbeWatch"))
{
include "/opt/Omnibus/probes/solaris2/probewatch.rules"
}
else
{
....
![]() |
Note If using a relative path, the path is taken from the probe's current working directory. There is no guarantee what this is, as it depends on how the probe was started. Therefore it is recommended that full pathnames are used as the argument to all include statements. |
It is possible to carry out mathematical calculations within the rules file and to set event information using thresholds. Within an if statement, comparisons can be made using mathematical operators.
In the following example, the severity of an event which monitors disk space usage, is set depending on the level of disk space.
if (int($PercentFull) > 80 && int($PercentFull) <=85){ @Severity=2} else if (int($PercentFull) > 85 and int($PercentFull) <=90) { @Severity=3} else if (int($PercentFull > 90 && int($PercentFull) <=95){ @Severity=4}elseif (int($PercentFull) > 95){ @Severity=5}In some cases, the percentage of disk space is not always provided within the event stream. The percentage of disk space can be calculated in the rules file as follows:
if (int($total) > 0){ @DiskSpace=(100*int($diskspace))/int($total)}This can also be calculated using the real function:
if (int($total) > 0){@DiskSpace=(real($diskspace)/real($total))*100}The previous if statement can then be used.
The mathematical operators supported are: +, -, *, /, <, >, <=, =>.
The following five operators can be used within the rules file to manipulate bits:
These operators only work with integer expressions, for example:
$result1 = $number1 & number2$result2 = $number3 >> 1 Remember, the operators work on the bits of the integer expressions. For example, when the $number3 element contained 17, $result2 resolves to 8, as follows:
Note that the bits do not rotate when they are pushed off one end, instead, they are replaced on the other end by a zero.
The deduplication process is managed by the Info Server, however it can be configured in both the Info Server and the probe rules file. This allows deduplication rules to be set on a per-event basis. You can specify in each probe rules file which fields of an event are updated during deduplication by using the update command.
For example, to ensure that the field @Severity is updated on deduplication, you can add the following to the rules file:
update (@Severity)
Another example would be to update the field @Acknowledged:
update (@Acknowledged)
You can also disable the update command for a specific field. For example:
update (@Severity,0)
This function has the following syntax:
update (fieldname)
or
update (fieldname, 1 or 0)
where 1 is when the update field on deduplication is enabled and 0 is when the update field on deduplication is disabled.
The following sections show examples of typical rules file segments.
This example rule tests if the $trap-type element is "Link-Up". When it is, it populates the @Summary field with a string made up of "Link up on", the name of the node from the record being generated, "Port " and the value of the $ifIndex element:
if(match($trap-type,"Link-Up"))
{@Summary = "Link up on "+ @Node + " Port "+ $ifIndex}This example rule is similar to the previous rule except it also populates the @AlertKey and @Severity fields:
if(match($trap-type, "Link-Up"))
{@Summary = "Link up on " + @Node + " Port " + $ifIndex
@AlertKey = $ifIndex
@Severity = 4}This example rule first tests if the trap has come from an Acme manager, and then tests if it is a "Link-Up". When it is, the rule populates the @Summary field with extra information:
if(match ($enterprise,"Acme"))
{if(match($trap-type, "Link-Up"))
{@Summary= "Acme Link Up on " + @Node + " Port " + $ifIndex +
" Reason : " +$ifLocReason}}This example rule tests for a line starting with "Acme Configuration:" followed by a single digit:
if (regmatch($enterprise,"^Acme Configuration:[0-9]"))
{@Summary="Generic configuration change for "+@Node}This example rule tests for a line starting with "Acme Configuration:" followed by a single digit. Then it extracts that single digit and places it in the @Summary field:
if (regmatch($enterprise,"^Acme Configuration:[0-9]")) {@Summary="Acme error "+extract($enterprise,"^Acme Configuration:
([0-9])")+" on"+@Node}This example rule tests the numeric value of an element called $freespace by converting it to an integer and performing a numeric comparison:
if (int($freespace) < 1024)
{@Summary="Less than 1024K free on drive array"}This example rule creates an element called $tmpval. The value of $tmpval is derived from the $temperature element which is converted to an integer and then has 20 subtracted from it. The string element $tmpval contains the result of this calculation:
$tmpval=int($temperature)-20
This example rule calculates the percentage of free disk space. The if statement checks if there is a valid element $DiskSize. When there is not, $Percentage is set to 100 which assumes the worst case. When $DiskSize is not 0, the calculation is performed using $DiskUsed:
if(int($DiskSize) == 0)
{# No disk size, so assume the worst case
$Percentage=100} else
{$Percentage=100*int($DiskUsed)/int($DiskSize)}This example rule creates an element $Kilobytes by dividing $DiskSize by 1024. The result is then cast back into a string using the string function and the letter K is appended to the string:
$Kilobytes = string(int($DiskSize)/1024) + "K"
This example rule uses $Percentage element to set the @Severity field. In this example, @Severity is set to a numeric value implicitly (@Severity="4") and explicitly (@Severity=3):
if(int($percentage) >= 98)
{@Severity="4"}
else if (int($Percentage) >=95)
{@Severity=3}
else
{discard}Note that in this example an explicit cast (@Severity=3) processes more efficiently.
![]()
![]()
![]()
![]()
![]()
![]()
![]()
Posted: Tue Jun 13 17:10:58 PDT 2000
Copyright 1989 - 2000©Cisco Systems Inc.