Before Python and NETCONF, before Ansible and Terraform, Cisco routers already had a way to automate themselves: the Embedded Event Manager. EEM runs entirely on the device, watches for events, and takes actions when they occur, no external server, no controller, no network dependency. It is the automation that keeps working when the automation server is exactly what went down, and it remains one of the most practical tools in the CCNP toolbox.
This article builds three EEM applets and fires all of them for real. It opens the Network Automation cluster guide.
First: This Runs On the Box
The thing that makes EEM different from every other automation tool is where it lives. Ansible, NETCONF, and REST APIs all drive the device from outside. EEM runs inside the device, in IOS itself. That has two consequences worth internalising:
The canonical use case is diagnostic capture: something breaks at 3am, and by the time an engineer looks, the transient state that would have explained it is gone. EEM catches it in the instant it happens.
The Anatomy of an Applet
An EEM applet is an event plus a set of actions. The event says "watch for this"; the actions say "do these things when it happens." The applet form (there is also a more powerful Tcl-scripted form) is readable enough to write on the fly:
event manager applet NAME
event <detector> <parameters>
action 1.0 <action>
action 2.0 <action>The action numbers (1.0, 2.0) set the execution order, and leaving gaps lets you insert steps later without renumbering. EEM offers many event detectors; the ones you will actually use:
Applet 1: Capture Diagnostics When a Link Fails
The classic. When Ethernet0/1 goes down, grab the state that will help diagnose it, before the box reconverges and hides what happened:
R1(config)# event manager applet LINK-DOWN-CAPTURE
R1(config-applet)# event syslog pattern "Interface Ethernet0/1, changed state to down"
R1(config-applet)# action 1.0 syslog msg "EEM: Et0/1 went down - collecting diagnostics"
R1(config-applet)# action 2.0 cli command "enable"
R1(config-applet)# action 3.0 cli command "show ip interface brief | append flash:eem-linkdown.txt"
R1(config-applet)# action 4.0 cli command "show ip ospf neighbor | append flash:eem-linkdown.txt"
R1(config-applet)# action 5.0 syslog msg "EEM: diagnostics saved to flash:eem-linkdown.txt"Two details matter. action 2.0 cli command "enable" is required because cli command actions start in user mode; you must elevate before running privileged commands. And | append writes each show output to a growing file, so you accumulate a timestamped record rather than overwriting.
(A platform note: the IOL-XE lab device uses a unix: filesystem rather than flash:, so more flash:eem-linkdown.txt fails there. On real hardware use flash: or bootflash:. The applet logic and the syslog evidence below are identical.)
Applet 2: Log Every Configuration Change
A lightweight audit trail. Whenever anyone leaves configuration mode (which logs a CONFIG_I message), record it:
R1(config)# event manager applet CONFIG-CHANGE-LOG
R1(config-applet)# event syslog pattern "CONFIG_I"
R1(config-applet)# action 1.0 syslog msg "EEM: a configuration change was made on R1"Paired with archive config logging, this is a poor engineer's change-tracking system that needs no external tooling.
Applet 3: Scheduled Heartbeat
A timer applet that fires every 60 seconds, standing in for any periodic task (scheduled data collection, a keepalive, a housekeeping job):
R1(config)# event manager applet HELLO-SCHEDULED
R1(config-applet)# event timer watchdog time 60
R1(config-applet)# action 1.0 syslog msg "EEM: scheduled watchdog fired - heartbeat"Firing All Three, For Real
Shut the interface and watch every applet respond. Here is the actual syslog from the box:
R1#show logging | include EEM
%HA_EM-6-LOG: CONFIG-CHANGE-LOG: EEM: a configuration change was made on R1
%HA_EM-6-LOG: LINK-DOWN-CAPTURE: EEM: Et0/1 went down - collecting diagnostics
%HA_EM-6-LOG: LINK-DOWN-CAPTURE: EEM: diagnostics saved to flash:eem-linkdown.txt
%HA_EM-6-LOG: CONFIG-CHANGE-LOG: EEM: a configuration change was made on R1Read the sequence. Entering config mode to type shutdown fired CONFIG-CHANGE-LOG. The interface going down fired LINK-DOWN-CAPTURE, which logged its start, ran the show commands, and logged completion. Every applet did exactly what it was told, driven by real events on the box.
EEM keeps its own event history, the authoritative record of what fired and whether it succeeded:
R1#show event manager history events
No. Job Id Proc Status Time of Event Event Type Name
1 1 Actv success Sun Jul12 02:33:57 2026 syslog applet: CONFIG-CHANGE-LOG
2 2 Actv success Sun Jul12 02:34:09 2026 syslog applet: CONFIG-CHANGE-LOG
3 3 Actv success Sun Jul12 02:34:10 2026 syslog applet: CONFIG-CHANGE-LOG
4 4 Actv success Sun Jul12 02:34:13 2026 syslog applet: LINK-DOWN-CAPTURE
5 5 Actv success Sun Jul12 02:34:21 2026 syslog applet: CONFIG-CHANGE-LOGEvery event success. When you are debugging an applet that is not behaving, this history (and debug event manager action cli) is where you look first: it tells you whether the event even fired, which is usually the problem.
Where EEM Bites
- Regex is literal. The
event syslog patternis a regex against the exact log string. If your pattern does not match the real message character for character (including interface naming), the applet silently never fires. Test with the actual log line. - You must
enablebefore privileged commands. Acli commandaction starts in user EXEC. Forgettingaction X cli command "enable"means your show commands fail silently. - Applets can loop. An applet whose action triggers its own event can fire itself repeatedly. Use
maxrunand think about self-triggering. - Rate limits exist for a reason. A syslog applet on a very common message can fire constantly and load the CPU. Match specifically.
- It is device-local automation, not orchestration. EEM is superb for reactive, on-box tasks. It is not a substitute for centralised config management across a fleet, which is where NETCONF and controllers come in.
Where EEM Fits in the Toolbox
EEM and the model-driven tools (NETCONF, RESTCONF) are complementary, not competing. EEM is reactive and local: it responds to events on the box in real time and keeps working in isolation. NETCONF and RESTCONF are proactive and remote: they let a central system push and read configuration at scale. A mature automation practice uses both. The rest of this cluster covers the remote, model-driven side: NETCONF, RESTCONF, and the YANG models underneath them.
FAQ
Why does my applet never fire?
Almost always a pattern mismatch. The event syslog pattern regex must match the real log message exactly. Trigger the event manually, copy the exact log line, and build your pattern from it. Check show event manager history events to confirm whether it fired at all.
Do I need to enable before running show commands?
Yes. cli command actions begin in user EXEC mode. Add action X cli command "enable" before any privileged command.
Applet or Tcl script?
Applets for straightforward event-action logic (most cases). Tcl scripts when you need loops, complex logic, or data manipulation the applet syntax cannot express. Start with applets.
Can EEM make configuration changes?
Yes, via cli command actions in config mode, which is how self-healing applets work. Be careful about loops and test thoroughly.
Does EEM work when the device is isolated?
Yes, and that is its signature strength. EEM runs entirely on the device, so it keeps reacting even when the box is cut off from every external system.
Key Takeaways
- EEM is on-box automation: it watches for events and acts, with no external server, so it keeps working when the box is isolated, exactly when you need it.
- An applet is an event (syslog, timer, snmp, cli) plus numbered actions. Its most common job is capturing transient diagnostic state the instant something breaks.
- The lab fired all three applets live: LINK-DOWN-CAPTURE on the interface event, CONFIG-CHANGE-LOG on every change, and a scheduled timer, all confirmed
successin the event history. - Two constant gotchas: the syslog regex must match exactly, and you must
enablebefore privilegedcli commandactions. - EEM is reactive and local; NETCONF/RESTCONF are proactive and remote. Use both.
Next: NETCONF hands-on, or the Network Automation cluster guide.