#!/bin/bash # check_snmp_synology for nagios version 1.2 # 30.04.2013 Nicolas Ordonez, Switzerland # 08.08.2020 Axel Hahn: add update, community string # 03.05.2023 v1.2 ah support Snmpv3 connections #--------------------------------------------------- # this plugin check the health of your Synology NAS # - System status (Power, Fans) # - Disks status # - RAID status # - available updates # # Tested with DSM 6.2 + 6.4 + 7.1 #--------------------------------------------------- # # ah = axel.hahn@unibe.ch # # 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 self_APPNAME=$( basename $0 | tr [:lower:] [:upper:] ) self_APPVERSION=1.2 SNMPCOMMUNITY="public" SNMPVERSION="2c" SNMPWALK=$(which snmpwalk) SNMPGET=$(which snmpget) SNMPCONFIG=/etc/icingaclient/snmp.cfg HOSTNAME="localhost" 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 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) _self=$( basename $0 ) USAGE=" ______________________________________________________________________ $self_APPNAME v$self_APPVERSION Based on script of Nicolas Ordonez. Institute for Medical Education - University of Bern Licence: GNU GPL 3 ______________________________________________________________________ check cpu usage and cpu wait Cpu infos are taken from output of top command. On higher cpu usage it can show processes that cause cpu waits and with most cpu consumption. SYNTAX: $_self [options] OPTIONS: -a authentication params for snmpwalk/ snmpget to connect to target; default: \"-v2c -c public\" (Snmpv2 with community string \"public\") -h host to connect as hostname or ip address -f FILE read authentication from config file default: \"/etc/icingaclient/snmp.cfg\" -v detailed output CONFIG FILE: The config file can be multiline and has the syntax [hostname]:[auth parameters] The auth parameters set the version and all needed values to connect. Snmp v2 uses a community string. Snmp v3 is highly recommended (you should disable Snmp v2) and needs a user and password. Example: server-01.example.com:-v 3 -l authnoPriv -a SHA -u snmpmonitor -A password-for-server-01 server-02.example.com:-v 3 -l authnoPriv -a SHA -u snmpmonitor -A password-for-server-02 EXAMPLE: $_self -h server-01.example.com -v Show Synology status of server-01 using connect data from /etc/icingaclient/snmp.cfg $_self -h server-01.example.com -v -f /opt/somewhere/snmp.conf Show Synology status of server-01 using connect data from custom config " #--------------------------------------------------- # 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" } read_config(){ SNMPAUTH="-v $SNMPVERSION -c $SNMPCOMMUNITY" if [ -r "$SNMPCONFIG" ]; then if grep "^${HOSTNAME}:" "$SNMPCONFIG" >/dev/null; then SNMPAUTH="$( grep "^${HOSTNAME}:" "$SNMPCONFIG" | cut -f 2- -d ':' )" else SNMPAUTH="$( grep "^DEFAULT:" "$SNMPCONFIG" | cut -f 2- -d ':' )" fi else ph.setStatus "unknown" echo "ERROR: unable to read config file [$SNMPCONFIG]." ph.exit fi } #--------------------------------------------------- # MAIN #--------------------------------------------------- while getopts a:h:f:v OPTNAME; do case "$OPTNAME" in a) SNMPAUTH="$OPTARG" ;; f) SNMPCONFIG="$OPTARG" ;; h) HOSTNAME="$OPTARG" option_found=1 ;; v) verbose="yes" ;; *) usage ;; esac done # --- read config to get the authentication params for snmp commands test -z "$SNMPAUTH" && read_config # --- read raid and disks to get its single OIDs nbDisk=$($SNMPWALK -OQne -t 10 ${SNMPAUTH} $HOSTNAME $OID_diskID 2> /dev/null | wc -l ) nbRAID=$($SNMPWALK -OQne -t 10 ${SNMPAUTH} $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 ${SNMPAUTH} $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 # _wd ""; _wd "DEBUG: SNMPAUTH= $( echo "$SNMPAUTH" | sed 's#\-A [^\ ]*#-A **********#g' )" # --- output status ph.status "$healthString" echo "$out" ph.exit