Wednesday, July 16, 2014

Nagios: SNMP checks for a Synology Diskstation


Because Synology uses embedded linux it is difficult to get the nagios-plugins package installed to do nrpe monitoring.  I tried the ipkg method then building the nagios-plugins from source, and while that site was helpful, I kept getting compile errors, probably a missing or outdated library issue.  That is OK because nagios has SNMP checks, and going one step further, has community plugins for Synology.  We are going to be using this community plugin from the user deegan199.

First we need to enable SNMP.  In DSM 5.x open the control panel and browse to Terminal & SNMP then the SNMP tab:


And that is all for the synology, no ports to open nor restart needed.

Grab the synology snmp check from the previous link and throw it into your plugins folder.  You may need to change the permissions to executable for your nagios user, something like:
 # chmod +x check_snmp_synology  
If this is your first SNMP check for nagios, you need the snmpget and snmpwalk programs, in redhat/centos get them from the net-snmp-utils package:
 # yum install net-snmp-utils  
Next run the plugin from your nagios server to do a test, change -h for your Synology's IP address:
 # ./check_snmp_synology -h 192.168.1.30 -v  

Next we will set up our nagios configs to get this check on the nagios panel.  First we will add the synology command definition to our commands.cfg:
 ################################################################################  
 #  
 # SYNOLOGY  
 #  
 ################################################################################  
 define command{  
      command_name check_synology  
      command_line /usr/lib64/nagios/plugins/check_snmp_synology -h $HOSTADDRESS$ -v  
 }  
I am leaving the -v (verbose) switch in because its nice to have the entire output on the Nagios panel, its up to you.  Next create a config for your Synology device inside your nagios/etc/servers directory and assign this new command to it, I also added SSH, for the heck of it:
 ###############################################################################  
 ###############################################################################  
 #  
 # HOST DEFINITION  
 #  
 ###############################################################################  
 ###############################################################################  
 define host{  
     use            linux-server      ; Name of host template to use  
     host_name      synology1
     alias          synology1
     address        192.168.1.30  
     }  
 ###############################################################################  
 ###############################################################################  
 #  
 # SERVICE DEFINITIONS  
 #  
 ###############################################################################  
 ###############################################################################  
 define service{  
   use                  generic-service  
   host_name            synology1
   service_description      System Health  
   check_command        check_synology  
   }  
 define service{  
   use                  generic-service  
   host_name            synology1
   service_description      SSH  
   check_command        check_ssh  
   }  
Save and do a service nagios restart and soon you will have your checks in your Nagios panel:


Initialized Disks
If your Synology is provisioned with hot-spares then Synology reports the disks as "initialized" and this plugin will create a critical alert for these initialized disks.  This was the case for one of my Synology devices, luckily in the comments for this plugin user mtominsk provides a fix.  Change the following in the check_snmp_synology plugin:

Original:
 if [ "${diskStatus[$i]}" != "1" ] ; then  
         if [ "${diskStatus[$i]}" = "2" ] ; then    diskStatus[$i]="Initialized";            fi  
     if [ "${diskStatus[$i]}" = "3" ] ; then    diskStatus[$i]="NotInitialized";        fi  
     if [ "${diskStatus[$i]}" = "4" ] ; then    diskStatus[$i]="SystemPartitionFailed";        fi  
     if [ "${diskStatus[$i]}" = "5" ] ; then    diskStatus[$i]="Crashed";            fi  
         healthStatus=2  
         healthString="$healthString, problem with ${diskID[$i]} (model:${diskModel[$i]}) status:${diskStatus[$i]} temperature:${diskTemp[$i]} C "  
 else  
     diskStatus[$i]="Normal"  
     fi  
     if [ "$verbose" = "yes" ] ; then  echo "${diskID[$i]} (model:${diskModel[$i]}) status:${diskStatus[$i]} temperature:${diskTemp[$i]} C" ; fi  
 done  
Modified:
 if [ "${diskStatus[$i]}" != "1" ] && [ "${diskStatus[$i]}" != "2" ] ; then  
     # if [ "${diskStatus[$i]}" = "2" ] ; then diskStatus[$i]="Initialized"; fi  
     if [ "${diskStatus[$i]}" = "3" ] ; then diskStatus[$i]="NotInitialized"; fi  
     if [ "${diskStatus[$i]}" = "4" ] ; then diskStatus[$i]="SystemPartitionFailed"; fi  
     if [ "${diskStatus[$i]}" = "5" ] ; then diskStatus[$i]="Crashed"; fi  
         healthStatus=2  
         healthString="$healthString, problem with ${diskID[$i]} (model:${diskModel[$i]})   status:${diskStatus[$i]} temperature:${diskTemp[$i]} C "  
 elif [ "${diskStatus[$i]}" = "2" ] ; then diskStatus[$i]="Initialized";  
 else  
     diskStatus[$i]="Normal"  
     fi  
     if [ "$verbose" = "yes" ] ; then echo "${diskID[$i]} (model:${diskModel[$i]}) status:${diskStatus[$i]} temperature:${diskTemp[$i]} C" ; fi  
 done  
Brilliant!  Thanks deegan199 and mtominsk!