Getting started

An EEM Tcl script has the advantage of being able to be set to run when a predefined trigger event occurs, this could be a certain counter reaching a set level, a syslog message being generated, a time of day ect.
The event manager directory where the Tcl scripts are stored needs to be setup in global configuration mode and the tcl script itself needs registering for as a policy. If a script is edited then after upload it must be de-registered and reregistered in the global configuration mode before the code change will have an effect.
Note that in some circumstances an EEM Applet may be more suitable than a EEM Tcl Policy.

event manager directory user policy [folderLocation]
event manager policy [location][filename.tcl] type user

The first none comment line of the Tcl policy script must state the event registration command,

::cisco::eem::event_register_[commandExtensions]

EEM Policies are by default given a time limit of 20 seconds to complete, if the script continues to execute beyond this maxrun timer limit it is forcibly stopped and will return an error containing the message "Process Forced Exit". This time limit can be extended by adding the maxrun [limit] command to the end of the event registration command, specified in seconds.milliseconds, so maxrun 60 sets the script execution maxrun time limit to 60 seconds.

Passing information to the EEM Policy

Tcl policies running under the Embedded Event Manager can access information regarding how, why and when they were called through the event_reqinfo variable, which also under certain triggers and on the newer EEM versions can be used to pass variables to the Tcl policy like when running scripts in the Tcl shell. See here for further information. They can also read globally configured values set with the command,

event manager environment [variable-name] [string]

EEM policy scripts can also save variables using the Tcl Context Library Command Extensions context_save and context_retrieve or via the EEM Utility Tcl Command Extensions appl_read and appl_setinfo. In both cases when the values are read they are also deleted and so if required later need to be written again after being read.

Debugging

There is comprehensive debugging available for EEM from the router, for debugging an issue with policies not being triggered correctly use;

debug event manager detector [eventDetectorType]
debug event manager policydir
debug event manager server scheduling

For debugging CLI command execution use

debug event manager action cli

and for debugging the Tcl policy use

debug event manager tcl cli
debug event manager tcl commands

Example script using the various arguments/variables available to an EEM policy

An example script which gets and or sets the event_reqinfo, event manager environment..., appl_ and context_ variables and arguments.


  1. # eemVarTest.tcl --
  2. #
  3. # Sample EEM policy to get/set;
  4. # Get 'event_reqinfo' variable information (for event type none).
  5. # Get 'event manager environment' variables.
  6. # Get and or Set appl_ variables.
  7. # Get and or Set context_ content variables.
  8. #
  9. # For the last two types the script loops three times,
  10. # Firstly it attempts to read the variables, upon first run they will not
  11. # exits, so they are written.
  12. # Secondly it again attempts to read, as it wrote them last time they are
  13. # found and read.
  14. # Thirdly it again attempts to read, however as we read them in the second
  15. # loop and did not re-write them (commented out) they are not found.
  16. #
  17. #
  18. # Prerequisites:
  19. #
  20. # Set: 'event manager directory user policy [folder]'
  21. # Upload file to [folderLocation]
  22. # register policy: 'event manager policy [folder][filename.tcl] type user'
  23. # Set: 'event manager environment owner [ownerName]'
  24. # Set: 'event manager environment location [location]'
  25. #
  26. # Call with 'event manager run [folder][filename.tcl]'
  27. # or
  28. # alias with 'alias exec [aliasName] event manager run [folder][filename.tcl]'
  29. #
  30. ::cisco::eem::event_register_none
  31. #::cisco::eem::description "This policy counts the number of configuration changes"
  32.  
  33. namespace import ::cisco::eem::*
  34. #namespace import ::cisco::lib::*
  35.  
  36. puts "Get event_reqinfo:"
  37. array set arr_reqinfo [event_reqinfo]
  38. foreach {var val} [array get arr_reqinfo] {
  39. puts "$var: $val"
  40. }
  41.  
  42. puts "\nGet from router config 'event manager environment' variables."
  43. if {![info exists owner]} {
  44. puts "No router owner set in config"
  45. puts "try setting 'event manager environment owner [ownerName]'"
  46. } else {
  47. puts "Router owner is: $owner."
  48. }
  49. if {![info exists location]} {
  50. puts "No router location set."
  51. puts "try setting 'event manager environment location [location]'"
  52. } else {
  53. puts "Router location is: $location."
  54. }
  55.  
  56.  
  57. for {set x 0} {$x<3} {incr x} {
  58. puts "\nLoop $x #########"
  59.  
  60. puts "\nGet EEM appl_ stored variables."
  61. set applEric [appl_reqinfo key eric]
  62. if {[lindex $applEric 0] == "data"} {
  63. puts "Got EEM key 'Eric': [lindex $applEric 1]"
  64. #Do not re-write, so on the next script run we will not be able to find it.
  65. #In normal operation the below should be uncommented to resave the value
  66. #appl_setinfo key eric data "is banana man"
  67. } else {
  68. puts "Could not find EEM Key 'Eric', setting it now"
  69. appl_setinfo key eric data "is banana man"
  70. }
  71. set applStig [appl_reqinfo key stig]
  72. if {[lindex $applStig 0] == "data"} {
  73. puts "Got EEM Key 'Sidekick': [lindex $applStig 1]"
  74. #Do not re-write, so on the next script run we will not be able to find it.
  75. #appl_setinfo key stig data "of the dump"
  76. } else {
  77. puts "Could not find EEM Key 'Sidekick', setting it now"
  78. appl_setinfo key stig data "Crow"
  79. }
  80.  
  81.  
  82. puts "\nGet EEM context_ stored variables."
  83. set test1 result1
  84. set test2 result2
  85.  
  86. if {![catch {context_retrieve TESTCTX "test1"} tempc]} {
  87. puts "Found context_retrieve test1: $tempc"
  88. #Do not re-write, so on the next script run we will not be able to find it.
  89. #In normal operation the below should be uncommented to resave the value
  90. #if {[catch {context_save TESTCTX "testvar*"} errmsg]} {
  91. # action_syslog msg "context_save failed: $errmsg"
  92. #} else {
  93. # action_syslog msg "context_save succeeded"
  94. # puts "context_save succeeded for test1"
  95. #}
  96. } else {
  97. puts -nonewline "Could no find context_retrieve test1, setting now. "
  98. if {[catch {context_save TESTCTX "test1"} errmsg]} {
  99. puts "Context_save failed: $errmsg"
  100. } else {
  101. puts "Context_save succeeded for test1"
  102. }
  103. }
  104. }

Example output of the above script.

Router#
Router#event manager run eemVariables.tcl
Get event_reqinfo:
event_type_string: none
event_pub_sec: 1386554295
event_id: 17
event_pub_msec: 122
event_type: 131

Get from router config 'event manager environment' variables.
Router owner is: Eric.
Router location is: 29 Acacia Road.

Loop 0 #########

Get EEM appl_ stored variables.
Could not find EEM Key 'Eric', setting it now
Could not find EEM Key 'Sidekick', setting it now

Get EEM context_ stored variables.
Could no find context_retrieve test1, setting now. Context_save succeeded for test1

Loop 1 #########

Get EEM appl_ stored variables.
Got EEM key 'Eric': is banana man
Got EEM Key 'sidekick': Crow

Get EEM context_ stored variables.
Found context_retrieve test1: result1

Loop 2 #########

Get EEM appl_ stored variables.
Could not find EEM Key 'Eric', setting it now
Could not find EEM Key 'Sidekick', setting it now

Get EEM context_ stored variables.
Could no find context_retrieve test1, setting now. Context_save succeeded for test1

Router#