Using TCLSH and EEM with SNMP
This evening it's topping 100 degrees in Reno, NV where our rack rental equipment is located. I'm looking at the temperature in our new data center to see how it's holding up in regards to the high exterior temperature. We have temperature sensors for each cage in our existing data center but so far only have a few installed in our new data center. I'm looking to see what the temperature is in a couple new cages in the new data center that don't have a temperature senor installed yet. So how can we get the temperature without a dedicated senor and only Cisco devices installed?
Relatively newer Cisco hardware has the ability to display the numerical temperature values by using the show environment command along with polling via SNMP. For the ISR G1's (1800, 2800, 3800) the internal-ambient, CPU, intake and backplane temperature (3845) and for the ISR G2's (1900, 2900, 3900) the intake left(bezel), intake left, exhaust right(bezel), exhaust right, CPU and power supply unit temperature can be displayed/polled. I wanted to see the temperature of the management access server (3825's) located at the top of each cage. I assumed I would just login and issue the show environment command to see the values. Good idea but I don't want to check it manually every few hours.
I could just login to SolarWinds and see the temperature but as we network engineers know, network management applications aren't that fun to use. You buy them, install them, swear they are the best thing since sliced bread, drool over the fancy graphs and then two months later you never log back into them unless something is wrong. Plus my normal thought process is to always try and do whatever possible via the IOS as it's the most fun.
To start I'll display the values via the show environment command and then poll the values using the SNMP via TCLSH and finally wrap it up with an EEM applet to log the values.
Row8Cage1AS#show environment
Redundant Power System is not present OR in standby mode.SYS PS1 is present.
Type: ACAUX(-48V) PS1 is absent.
Fan 1 OK
Fan 2 OK
Fan 3 OKFan Speed Setting: Normal
Alert settings:
Intake temperature warning: Enabled, Threshold: 55
Core temperature warning: Enabled, Threshold: 70 (CPU: 95)Board Temperature: Normal
Internal-ambient temperature = 33, Normal
CPU temperature = 50, Normal
Intake temperature = 32, NormalVoltage 1(3300) is Normal, Current voltage = 3300 mV
Voltage 2(5150) is Normal, Current voltage = 5153 mV
Voltage 3(2500) is Normal, Current voltage = 2525 mV
Voltage 4(1200) is Normal, Current voltage = 1215 mVNominal frequency
Row8Cage1AS#
Now I need to find the SNMP OID related to temperature for the platform. Note that SNMP has previous been setup on this router.
Row8Cage1AS#show snmp mib | in Temperature
ciscoEnvMonTemperatureStatusEntry.2
ciscoEnvMonTemperatureStatusEntry.3
ciscoEnvMonTemperatureStatusEntry.4
ciscoEnvMonTemperatureStatusEntry.5
ciscoEnvMonTemperatureStatusEntry.6
c3gModemTemperature
Row8Cage1AS#
I know it's one of the ciscoEnvMonTemperatureStatusEntry values but which one? One should be the name, another should be the actual values and another should be the thresholds. Seems like Google should be used here but we know the values via the show environment command so we could poll them and see which one matches. We'll learn more this way over using Google. We'll start with the first one and walk down 99.
Row8Cage1AS#tclsh
Row8Cage1AS(tcl)#snmp_getbulk
usage: snmp_getbulk community_string non_repeaters max_repetitions oid [oid2 oid3 ...]
Row8Cage1AS(tcl)#
Row8Cage1AS(tcl)#snmp_getbulk XXXXXX 0 99 ciscoEnvMonTemperatureStatusEntry.2
{<obj oid='ciscoEnvMonTemperatureStatusEntry.2.1' val='Internal-ambient'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.2.2' val='CPU'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.2.3' val='Intake'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.3.1' val='33'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.3.2' val='50'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.3.3' val='32'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.4.1' val='70'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.4.2' val='95'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.4.3' val='55'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.5.1' val='0'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.5.2' val='0'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.5.3' val='0'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.6.1' val='1'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.6.2' val='1'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.6.3' val='1'/>}
Row8Cage1AS(tcl)#
Row8Cage1AS(tcl)#snmp_getbulk XXXXXX 0 3 ciscoEnvMonTemperatureStatusEntry.3
{<obj oid='ciscoEnvMonTemperatureStatusEntry.3.1' val='33'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.3.2' val='50'/>}
{<obj oid='ciscoEnvMonTemperatureStatusEntry.3.3' val='32'/>}
Row8Cage1AS(tcl)#
That was easy. The ciscoEnvMonTemperatureStatusEntry.3 is what we are looking for and ciscoEnvMonTemperatureStatusEntry.3.1 is a good value to use as it's giving us the "internal ambient" temperature.
Row8Cage1AS(tcl)#snmp_getone
usage: snmp_getone community_string oid [oid2 oid3 ...]
Row8Cage1AS(tcl)#
Row8Cage1AS(tcl)#snmp_getone XXXXXX ciscoEnvMonTemperatureStatusEntry.3.1
{<obj oid='ciscoEnvMonTemperatureStatusEntry.3.1' val='33'/>}
Row8Cage1AS(tcl)#
Now how about having this value logged every 5 minutes so we can check back in the morning to see any changes overnight. An easy way to do this is to poll the SNMP OID using EEM and log the value returned using syslog if it's above 1 degree which we know it will always be. This way EEM will always log the value to syslog.
Row8Cage1AS(tcl)#tclquit
Row8Cage1AS#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Row8Cage1AS(config)#event manager applet EEM_TEMP_MON
Row8Cage1AS(config-applet)#event snmp oid ciscoEnvMonTemperatureStatusEntry.3.1 get-type exact entry-op gt entry-val 1 poll-interval 300
Row8Cage1AS(config-applet)#action 1.0 syslog msg "Row8Cage1AS Temperature $_snmp_oid_val"
Row8Cage1AS(config-applet)#^Z
Row8Cage1AS#
Jun 7 06:53:42.011: %SYS-5-CONFIG_I: Configured from console by bdennis on vty0
Row8Cage1AS#
Jun 7 06:54:12.012: %HA_EM-6-LOG: EEM_TEMP_MON: Row8Cage1AS Temperature: 33
We could convert the value to fahrenheit if we wanted by using this TCL expression: set temp [expr {9.0*$_snmp_oid_val/5.0+32.0}].
Of course using a network management application or script on a server would be easier but doing it via the IOS was fun. There are a few other ways to do this via the IOS and one being SNMP MIB BULKSTAT.