10-17-2011 08:59 AM
Hi there,
I'm trying to create a script that will email me when an interface goes down, and include the interface description in the email. I've found a script that successfully emails me when the status changes, and I found another script that will parse for the interface description, but I can't seem to get them to work together. I've mashed them up together into the below script:
#------------------------------------------------------------------
# EEM policy that will monitor SYSLOG for Interface status changes.
# If UPDOWN message is detected, send an email with interface information.
#
#------------------------------------------------------------------
### The following EEM environment variables are used:
###
### _email_server
### - A Simple Mail Transfer Protocol (SMTP)
### mail server used to send e-mail.
### Example: _email_server mailserver.example.com
# Register for a Syslog event. Event Detector: Syslog
# Match pattern for Interface Status change
::cisco::eem::event_register_syslog pattern "%LINK-3-UPDOWN"
# NAMESPACE IMPORT
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
# Set array for event_reqinfo
# Array is populated with additional event information
array set Syslog_info [event_reqinfo]
set msg $Syslog_info(msg)
# Set routername variable for use later
set routername [info hostname]
# Parse output for interface name
if { ! [regexp {: ([^:]+)$} $msg -> info] } {
action_syslog msg "Failed to parse syslog message"
}
regexp {Line protocol on Interface ([a-zA-Z0-9]+)} $info -> interface
# ------------------- cli open -------------------
#
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli $result
}
# Go into Enable mode
if [catch {cli_exec $cli(fd) "enable"} result] {
error $result $errorInfo
}
#Find interface description
if [catch {cli_exec $cli(fd) "show interface $interface | inc Description" } description] {
error $description $errorInfo
}
#
#--------------------- cli close ------------------------
#
cli_close $cli(fd) $cli(tty_id)
set time_now [clock seconds]
set time_now [clock format $time_now -format "%T %Z %a %b %d %Y"]
#
# EMAIL MESSAGE
# This manually creates a text message with specific format to be used by the
# smtp_send_email command later to send an email alert.
#
# Ensure the following are configured:
# ip domain-name <domain.com>
#
# If a hostname is used for mailservername, ensure the following are configured:
# ip name-server <dns-server>
# ip domain-lookup
#
# NOTE: Change environment variable _email_server to your SMTP server
#
# The email below references the following variables:
#
# $routername: hostname of device
# $time_now: time when specific Syslog message was detected
# $msg: Syslog message received
#
#
#
set email_message "Mailservername: $_email_server
From: eem-$routername@mycompany.com
To: $_email_to
Cc:
Subject: EEM: Critical interface status change on $routername
This email is generated by EEM.
$time_now
$msg
$description
"
# Send email message
if {[catch {smtp_send_email $email_message} result]} {
set result "Email send failed"
} else {
set result "Email Sent"
}
# Debug message to check email transmission status
action_syslog msg "$result"
----------------------------------------------------
When I trigger an interface UPDOWN message, I'm getting the following error on the command line:
Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: can't read "interface": no such variable
Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: while executing
Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "cli_exec $cli(fd) "show interface $interface | inc Description" "
Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: invoked from within
Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "$slave eval $Contents"
Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: (procedure "eval_script" line 7)
Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: invoked from within
Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "eval_script slave $scriptname"
Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: invoked from within
Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "if {$security_level == 1} { #untrusted script
Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: interp create -safe slave
Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: interp share {} stdin slave
Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: interp share {} stdout slave
Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: ..."
Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: (file "tmpsys:/lib/tcl/base.tcl" line 50)
Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: Tcl policy execute failed: can't read "interface": no such variable
Can anyone help me figure out where I'm going wrong?
Thanks in advance,
Brandon
Solved! Go to Solution.
10-18-2011 07:59 AM
I got the same errors with your file. Made some changes and I no longer get the interface error with the attached file.
10-17-2011 04:28 PM
Can you remove this line:
::cisco::eem::event_register_syslog pattern "%LINK-3-UPDOWN"
and replace it with:
::cisco::eem::event_register_syslog pattern "LINEPROTO-5-UPDOWN.*"
Also replace:
regexp {Line protocol on Interface ([a-zA-Z0-9]+)} $info -> interface
with
regexp {Line protocol on Interface ([\/a-zA-Z0-9]+)} $info -> interface
I believe this will get the interface variable populated correctly.
Dan
10-18-2011 06:56 AM
Hi Dan,
Thanks for the reply. I've made the changes you suggested but I'm still getting the error:
Oct 18 21:41:50.446 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: can't read "interface": no such variable
Oct 18 21:41:50.446 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: while executing
Oct 18 21:41:50.446 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "cli_exec $cli(fd) "show int $interface | inc Description""
Is there any additional debugging I could place in my script? Normally I would try and print the variables after each line to see what's being populated, but I'm not sure how I can test that from within EEM.
--Brandon
10-18-2011 07:07 AM
Brandon,
Could you upload your script file to this site and I will take a look.
Thanks,
Dan
10-18-2011 07:25 AM
10-18-2011 07:59 AM
10-18-2011 08:21 AM
That definitely did the trick -- any insight as to what was wrong with my original version?
10-18-2011 09:49 AM
I had a fat finger in the orginal one I sent you.
Originally it had this:
regexp {Line protocol on Interface ([\/a-zA-Z0-9]+)} $info -> interface]
This would make a variable named interface] . Later in the script it called variable "$interface" (without the left bracket) and this generated the error.
Here is the correct syntax.
regexp {Line protocol on Interface ([\/a-zA-Z0-9]+)} $info -> interface
I did change some variable names in the current policy which made it easier for me to troubleshoot. If you wanted to change the variable and array names back to what you had the policy should still work.
Dan
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide