This document describes Embedded Event Manager (EEM) script configuration best practices on Cisco IOS-XE devices, and provides examples of common syntax and useful scripts.
This document assumes that the reader is already familiar with the Cisco IOS/IOS-XE Embedded Event Manager (EEM) feature. If you are not already familiar with this feature, please read the EEM Feature Overview first.
The information in this document is based on these software and hardware versions:
Cisco Catalyst 9300, 9400, and 9500 switches that run Cisco IOS Software Version 16.X or 17.X
These scripts are not supported by Cisco TAC and are provided on an as-is basis for educational purposes.
The information in this document was created from the devices in a specific lab environment. All of the devices used in this document started with a cleared (default) configuration. If your network is live, make sure that you understand the potential impact of any command.
This section covers some of the most common issues observed with the design and implementation of EEM scripts. For additional information on EEM best practices, see the EEM Best Practices document referenced under the References section.
Confirm Appropriate Authentication is in Place
If your device uses AAA, you must ensure that the EEM scripts configured on the device are either configured with an AAA user able to run the commands in the script, or that authorization bypass is configured with the command authorization bypass in the script definition.
Add Constraints for EEM Runtime and Rate-limit
By default, EEM scripts can run for a maximum of 20 seconds. If you design a script that will take longer to run, or has to wait between command execution, specify a maxrun value on the applet event trigger to alter the default execution timer.
It is also important to consider how often the event that triggers your EEM script may run. If you trigger a script from a condition that occurs rapidly in a short amount of time (i.e. syslog trigger for MAC flaps), it is important to include a rate-limit condition on your EEM script to prevent an excessive number of executions in parallel and prevent exhaustion of device resources.
Avoid Out-of-order Execution
As described in the EEM documentation, the order of execution for action statements is controlled by their label (i.e. 'action 0001 cli command enable has a label of 0001). This label value is NOT a number, but rather alphanumeric. Actions are sorted in ascending alphanumeric key sequence, use the label argument as the sort key, and they are run in this sequence. This can lead to unexpected order of execution, based on how you structure your action labels.
Consider this example:
event manager applet test authorization bypass event timer watchdog time 60 maxrun 60 action 13 syslog msg "You would expect to see this message first" action 120 syslog msg "This message will print first"
Since 120 is before 13 in an alphanumeric comparison, this script will not run in the order you expect. To avoid this, it is useful to use a system of padding like this:
event manager applet test authorization bypass event timer watchdog time 60 maxrun 60 action 0010 syslog msg "This message will appear first" action 0020 syslog msg "This message will appear second" action 0120 syslog msg "This message will appear third"
Due to the padding here, the numbered statements will evaluate in the expected order. The increment of 10 between each label allows for additional statements to be inserted into the EEM script later where needed, without the need to renumber all subsequent statements.
EEM looks for the device prompt to determine when command output is complete. Commands that output more data then can be displayed on one screen (as configured by your terminal length), can prevent EEM scripts from completion (and eventually killed via the maxrun timer) as the device prompt will not be shown until all pages of the output are viewed. Configure term len 0 at the start of EEM scripts that examine large outputs.
Design Scripts for Future Maintainability
When you design an EEM script, leave gaps between action labels to make it easier to update the EEM script logic in the future. When appropriate gaps are available (i.e. two statements such as action 0010 and action 0020 leave a gap of 9 labels that can be inserted), new statements can be added as required without renumber or recheck of the action labels and ensure the actions will continue to execute in the expected order.
There are common commands that you may need to run at the beginning of your EEM scripts. This may include:
set terminal length to 0
enter enable mode
enable automatic timestamp for command output
You will see this as a common pattern in the examples shown in this document, where many of the scripts begin with the same 3 action statements to configure this.
Common EEM Logic Patterns
This section covers some common logic patterns and syntax blocks used in EEM scripts. The examples here are not complete scripts, but rather demonstrations of how specific functionality can be used to create complex EEM scripts.
Branch Code Paths with if/else
EEM variables can be used to control the execution flow of EEM scripts. Consider this EEM script:
event manager applet snmp_cpu authorization bypass event timer watchdog time 60 action 0010 info type snmp oid 220.127.116.11.18.104.22.168.22.214.171.124.1.3.1 get-type exact action 0020 if $_info_snmp_value ge "50" action 0030 syslog msg "This syslog message will be sent if CPU utilization is above 50%" action 0040 elseif $_info_snmp_value ge "30" action 0050 syslog msg "This syslog message will be sent if CPU utilization is above 30% and below 50%" action 0060 else action 0070 syslog msg "This syslog message will only be sent if CPU utilization is below 30%" action 0080 end
This script will run every minute, examine the value of the SNMP OID for CPU utilization, and then enter one of three different execution paths based on the value of the OID. Similar statements can be used on any other legal EEM variable to build complex execution flows in EEM scripts.
Loop Over Statements
Execution loops can be used to significantly shorten EEM scripts, and make them easier to reason about. Consider the this script, designed to pull the interface statistics for Te2/1/15 6 times over a 1 minute period to check for small periods of high utilization:
The EEM regexp statement can be used to extract values from command output to be used in subsequent commands, and enable dynamic command creation within the EEM script itself. Refer to this code block for an example to extract the SNMP ENGINE PID from the output of show proc cpu | i SNMP engine and print it to a syslog message. This extracted value can also be used in other commands that require a PID to run.
In this example, the MAC address b4e9.b0d3.6a41 is tracked. The script checks every 30 seconds to see if the specified MAC address has been learned in the ARP or MAC tables. If the MAC is seen, the script takes these actions:
outputs a syslog message (This is useful when you want to confirm where a MAC address is learned, or when/how often it is learned).
This script is configured to pattern match on the non-standard prompt returned by the install add file <file> activate commit command and respond to the prompts. No trigger event is configured, so the EEM script must be manually triggered by a user when the upgrade needs to occur via event manager run UPGRADE. The maxrun timer is set for 300 seconds instead of the default value of 20 seconds as the install add command takes a significant amount of time to run.
Dump diagnostic data to a file when an IP SLA tracked object goes down
This script is triggered when IP SLA object 11 goes down and takes these actions:
Collect MAC table, ARP table, syslogs, and Routing table
Write info to a file on flash: called sla_track.txt
ip sla 10
icmp-echo 10.10.10.10 source-ip 126.96.36.199
ip sla schedule 10 life forever start-time now
track 11 ip sla 10 reachability
event manager applet track-10 authorization bypass
event track 11 state down action 0001 cli command "enable" action 0002 cli command "term exec prompt timestamp" action 0003 cli command "term length 0"
action 0010 syslog msg "IP SLA object 10 has gone down"
action 0020 cli command "show mac address-table detail | append flash:sla_track.txt"
action 0030 cli command "show ip arp | append flash:sla_track.txt"
action 0040 cli command "show log | append flash:sla_track.txt"
action 0050 cli command "show ip route | append flash:sla_track.txt"
Send an Email from EEM
This script is triggered when the pattern described in the event syslog pattern statement is seen, and takes these actions:
sends an email from an internal email server (this assumes that the internal email server allows for open authentication from the device).
event manager environment email_from email@example.com
event manager environment email_server 192.168.1.1
event manager environment email_to firstname.lastname@example.org
event manager applet email_syslog
event syslog pattern "SYSLOG PATTERN HERE” maxrun 60
action 0010 info type routername
action 0020 mail server "$email_server" to "$email_to" from "$email_from" subject "SUBJECT OF EMAIL - Syslog seen on $_info_routername" body “BODY OF YOUR EMAIL GOES HERE”
Shutdown a Port on a Schedule
This script shuts down port Te2/1/15 every day at 6PM.