Skip to content
Snippets Groups Projects
check_snmp_synology 8.00 KiB
#!/bin/bash
# check_snmp_synology for nagios version 1.1
# 30.04.2013  Nicolas Ordonez, Switzerland
# 08.08.2020  Axel Hahn: add update, community string
#---------------------------------------------------
# this plugin check the health of your Synology NAS
# - System status (Power, Fans)
# - Disks status 
# - RAID status
# - available updates
#
# Tested with DSM 6.2
#---------------------------------------------------
# see docs:
# https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_MIB_Guide.pdf
#---------------------------------------------------

. `dirname $0`/inc_pluginfunctions

# --- basic vars
SNMPCOMMUNITY="public"
SNMPVERSION="2c"
SNMPWALK=$(which snmpwalk)
SNMPGET=$(which snmpget)

HOSTNAME=""
option_found=0
healthString=""
verbose="no"
out=""

# --- OID declarations
OID_syno="1.3.6.1.4.1.6574"
OID_model="${OID_syno}.1.5.1.0"
OID_serialNumber="${OID_syno}.1.5.2.0"
OID_DSMVersion="${OID_syno}.1.5.3.0"
OID_DSMUpdateAvailable="${OID_syno}.1.5.4.0"
OID_systemStatus="${OID_syno}.1.1.0"
OID_powerStatus="${OID_syno}.1.3.0"
OID_systemFanStatus="${OID_syno}.1.4.1.0"
OID_CPUFanStatus="${OID_syno}.1.4.2.0"
OID_temp="${OID_syno}.1.2.0"

OID_disk=""
OID_diskID="${OID_syno}.2.1.1.2"
OID_diskModel="${OID_syno}.2.1.1.3"
OID_diskStatus="${OID_syno}.2.1.1.5"
OID_diskTemp="${OID_syno}.2.1.1.6"

OID_RAID=""
OID_RAIDName="${OID_syno}.3.1.1.2"
OID_RAIDStatus="${OID_syno}.3.1.1.3"

OID_RAIDFree="${OID_syno}.3.1.1.4"
OID_RAIDSize="${OID_syno}.3.1.1.5"


# --- status arrays to show results
#                0     1          2             3               4                      5
aStatusDual=(    "???" Normal     Failed)
aStatusUpgrade=( "???" Yes        "Up to date"  Connecting      Disconnected           Others)
aStatusDisk=(    "???" Normal     Initialized   NotInitialized  SystemPartitionFailed  Crashed)
aStatusRaid=(    "???" Normal     Repairing     Migrating       Expanding              Deleting Creating RaidSyncing RaidParityChecking RaidAssembling Canceling Degrade Crashed DataScrubbing RaidDeploying RaidUnDeploying RaidMountCache RaidExpandingUnfinishedSHR RaidConvertSHRToPool RaidMigrateSHR1ToSHR2 RaidUnknownStatus)

aStatusSystem=$aStatusDual
aStatusPower=$aStatusDual
aStatusFan=$aStatusDual


#---------------------------------------------------
# FUNCTIONS
#---------------------------------------------------

# --- write verbose text
_wd()
{
    if [ "$verbose" = "yes" ] ; then 
        out="${out}$*
" ; fi
}

# --- get a value from SNMP output data
# param  string  mib string
_get(){
    echo "$syno" | grep "${1} " | cut -d "=" -f2 | cut -f 2- -d " "
}

# --- show usage
usage()
{
        ph.abort "usage: ./check_snmp_synology -h hostname [-C communitystring] [-v verbose]"
}

#---------------------------------------------------
# MAIN
#---------------------------------------------------

while getopts h:v OPTNAME; do
        case "$OPTNAME" in

        h)
                HOSTNAME="$OPTARG"
                option_found=1
                ;;
		C)
			    SNMPCOMMUNITY="$OPTARG"
			    ;;
        v)
                verbose="yes"
                ;;
        *)
                usage
                ;;
        esac
done

if [ "$option_found" = "0" ] || [ "$HOSTNAME" = "" ] ; then
    usage
    # remark: script aborts ...
fi


# --- read raid and disks to get its single OIDs
nbDisk=`$SNMPWALK -OQne -t 10 -v $SNMPVERSION -c $SNMPCOMMUNITY $HOSTNAME $OID_diskID   2> /dev/null | wc -l `
nbRAID=`$SNMPWALK -OQne -t 10 -v $SNMPVERSION -c $SNMPCOMMUNITY $HOSTNAME $OID_RAIDName 2> /dev/null | wc -l`

for i in `seq 1 $nbDisk`;
do
    OID_disk="$OID_disk $OID_diskID.$(($i-1)) $OID_diskModel.$(($i-1)) $OID_diskStatus.$(($i-1)) $OID_diskTemp.$(($i-1)) " 
done
for i in `seq 1 $nbRAID`;
do
    OID_RAID="$OID_RAID $OID_RAIDName.$(($i-1)) $OID_RAIDStatus.$(($i-1)) $OID_RAIDSize.$(($i-1)) $OID_RAIDFree.$(($i-1))" 
done

# --- SNPGET to all wanted oids
syno=`$SNMPGET -OQne -t 10 -v $SNMPVERSION -c $SNMPCOMMUNITY $HOSTNAME $OID_model $OID_serialNumber $OID_DSMVersion $OID_DSMUpdateAvailable $OID_systemStatus $OID_powerStatus $OID_systemFanStatus $OID_CPUFanStatus $OID_temp $OID_disk $OID_RAID 2> /dev/null | sed 's/^[ \t]*//;s/[ \t]*$//'`

if [ "$?" != "0" ] ; then
    ph.abort "Problem with SNMP request"
fi

_wd ""

# --- check fetched data
model=$(_get $OID_model)
_wd "Synology model:    $model"

serialNumber=$(_get $OID_serialNumber)
_wd "Synology s/n:      $serialNumber"

DSMVersion=$(_get $OID_DSMVersion)
_wd "DSM Version:       $DSMVersion"

healthString="Synology $model (s/n:$serialNumber, $DSMVersion)"

RAIDName=$(_get $OID_RAIDName)
RAIDStatus=$(_get $OID_RAIDStatus)


# --- check update
typeset -i DSMupdate=$(_get $OID_DSMUpdateAvailable)
_wd "Update available:  ${aStatusUpgrade[$DSMupdate]} ($DSMupdate)"
if [ $DSMupdate -eq 1 ] ; then
    ph.setStatus "warning"
    healthString="$healthString, Update available"
fi
_wd ""


# --- Check system status
systemStatus=$(_get $OID_systemStatus)

if [ $systemStatus != "1" ] ; then
    if [ "$systemStatus" = "2" ] ; then      systemStatus="Failed";          fi
    ph.setStatus "critical"
    healthString="$healthString, System status: $systemStatus "
else
    systemStatus="Normal"
fi
_wd "System Status:     $systemStatus"


# --- Check power status
powerStatus=$(_get $OID_powerStatus)

if [ $powerStatus != "1" ] ; then
    if [ "$powerStatus" = "2" ] ; then       powerStatus="Failed";           fi
    ph.setStatus "critical"
    healthString="$healthString, Power status: $powerStatus "
else
    powerStatus="Normal"
fi
_wd "Power Status:      $powerStatus"


# --- Check system fan status
systemFanStatus=$(_get $OID_systemFanStatus)
if [ $systemFanStatus != "1" ] ; then
    if [ "$systemFanStatus" = "2" ] ; then   systemFanStatus="Failed";               fi
    ph.setStatus "critical"
    healthString="$healthString, System fan status: $systemFanStatus "
else
    systemFanStatus="Normal"
fi
_wd "System Fan Status: $systemFanStatus"


# --- Check CPU fan status
CPUFanStatus=$(_get $OID_CPUFanStatus)
if [ $CPUFanStatus != "1" ] ; then
    if [ "$CPUFanStatus" = "2" ] ; then      CPUFanStatus="Failed";          fi
    ph.setStatus "critical"
    healthString="$healthString, CPU fan status: $CPUFanStatus "
else
    CPUFanStatus="Normal"
fi
_wd "CPU Fan Status:    $CPUFanStatus"


# --- Show temperature
DeviceTemperature=$(_get $OID_temp)
# if [ $DeviceTemperature ...  ] ; then
#     ph.setStatus "critical"
#     healthString="$healthString, CPU fan status: $CPUFanStatus °C"
# else
#     CPUFanStatus="Normal"
# fi
_wd "NAS temperature:   $DeviceTemperature °C"


# --- Check all disk status
_wd ""
_wd "Number of disks:   $nbDisk"
for i in `seq 1 $nbDisk`;
do
    diskID[$i]=$(_get $OID_diskID.$(($i-1)))
    diskModel[$i]=$(_get $OID_diskModel.$(($i-1)))
    diskTemp[$i]=$(_get $OID_diskTemp.$(($i-1)))
    idiskStatus=$(_get $OID_diskStatus.$(($i-1)))

    diskStatus[$i]=${aStatusDisk[$idiskStatus]}
   
    if [ ${idiskStatus} != "1" ] ; then
        ph.setStatus "critical"
        healthString="$healthString, problem with ${diskID[$i]} (model:${diskModel[$i]}) status:${diskStatus[$i]} temperature:${diskTemp[$i]} °C"
    fi

    _wd "${diskID[$i]} (model:${diskModel[$i]}) status: ${diskStatus[$i]} ($idiskStatus) temperature: ${diskTemp[$i]} °C"
done


# --- Check all RAID volume status
_wd ""
_wd "Number of RAID volume: $nbRAID"
for i in `seq 1 $nbRAID`;
do
    RAIDName[$i]=$(_get $OID_RAIDName.$(($i-1)))
    iRAIDStatus=$(_get $OID_RAIDStatus.$(($i-1)))

    # size in integer GB
    iRAIDSize=$(( $(_get $OID_RAIDSize.$(($i-1))) / 1024/1024/1024 ))
    iRAIDFree=$(( $(_get $OID_RAIDFree.$(($i-1))) / 1024/1024/1024 ))
    iFree=$(( iRAIDFree*100/$iRAIDSize ))

    RAIDStatus[$i]=${aStatusRaid[${iRAIDStatus}]}

    if [ $iRAIDStatus != "1" ] ; then
        ph.setStatus "critical"
        healthString="$healthString, RAID status: ($RAIDName ): $RAIDStatus[$i] "
    fi
    _wd "${RAIDName[$i]} status: ${RAIDStatus[$i]} ($iRAIDStatus) - size $iRAIDSize GB, free $iRAIDFree GB (${iFree}%)"
done


# --- output status
ph.status "$healthString"
echo "$out"

ph.exit