#!/usr/bin/env bash # ====================================================================== # # NAGIOS / ICINGA CHECK :: check_snmp_data # this plugin checks snmp performance data # # DOCS: # - Synology - see docs: # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_MIB_Guide.pdf # # - IODs uc davis http://oidref.com/1.3.6.1.4.1.2021 # # ---------------------------------------------------------------------- # # SYNTAX: # label --> DATA:[method]:label:[text] # n x data --> DATA:[method]:data:[perf-label]:[oid]:[optional unit]:[loop oid] # # DATA:cpu:label:CPU usage # DATA:cpu:data:cpu-user:1.3.6.1.4.1.2021.11.9.0:% # DATA:cpu:data:cpu-system:1.3.6.1.4.1.2021.11.10.0:% # DATA:cpu:data:cpu-idle:1.3.6.1.4.1.2021.11.11.0:% # # DATA:load:label:System load # DATA:load:data:load1:1.3.6.1.4.1.2021.10.1.5.1: # DATA:load:data:load5:1.3.6.1.4.1.2021.10.1.5.2: # DATA:load:data:load15:1.3.6.1.4.1.2021.10.1.5.3: # # DATA:mem:label:Memory status # DATA:mem:data:memTotalSwap:1.3.6.1.4.1.2021.4.3.0: # DATA:mem:data:memAvailSwap:1.3.6.1.4.1.2021.4.4.0: # DATA:mem:data:memTotalReal:1.3.6.1.4.1.2021.4.5.0: # DATA:mem:data:memAvailReal:1.3.6.1.4.1.2021.4.6.0: # DATA:mem:data:memTotalFree:1.3.6.1.4.1.2021.4.11.0: # DATA:mem:data:memShared:1.3.6.1.4.1.2021.4.13.0: # DATA:mem:data:memBuffer:1.3.6.1.4.1.2021.4.14.0: # DATA:mem:data:memCached:1.3.6.1.4.1.2021.4.15.0: # # DATA:netio:label:Network IO # DATA:netio:data:in:1.3.6.1.2.1.4.3.0: # DATA:netio:data:out:1.3.6.1.2.1.4.10.0: # # DATA:disc:label:Synology Disc usage # DATA:disc:data:disc-free:1.3.6.1.4.1.6574.3.1.1.2::1.3.6.1.4.1.6574.3.1.1.4 # DATA:disc:data:disc-space:1.3.6.1.4.1.6574.3.1.1.2::1.3.6.1.4.1.6574.3.1.1.5 # # DATA:synotemp:label:Synology NAS temperature # DATA:synotemp:data:temp:1.3.6.1.4.1.6574.1.2.0:°C # # DATA:synoio:label:Synology Space IO # DATA:synoio:data:syno-io-read:1.3.6.1.4.1.6574.102.1.1.12.1 # DATA:synoio:data:syno-io-write:1.3.6.1.4.1.6574.102.1.1.13.1 # # ---------------------------------------------------------------------- # 2020-08-11 <axel.hahn@iml.unibe.ch> initial version # 2020-08-13 <axel.hahn@iml.unibe.ch> add host in label for counter data # 2022-10-21 v0.4 <axel.hahn@unibe.ch> remove grep: warning: stray \ before white space # 2022-10-21 v0.5 <andrea.gottsponer@unibe.ch> remove grep: warning: stray \ before white space # 2022-10-25 v0.6 <axel.hahn@unibe.ch> fix empty value in performance data; shell fixes # 2023-05-05 v0.7 <axel.hahn@unibe.ch> source shared func, support snmpv3; add synoio # ====================================================================== . $(dirname $0)/inc_pluginfunctions . $(dirname $0)/check_snmp_includes # --- basic vars self_APPNAME=$( basename $0 | tr [:lower:] [:upper:] ) self_APPVERSION=0.7 METHOD="" # --- OID declarations # OID_syno="1.3.6.1.4.1.6574" # OID_ucdavis="1.3.6.1.4.1.2021" # University of California, Davis - private UCD SNMP MIB extensions # --- output variables SYNO="" out="" #--------------------------------------------------- # FUNCTIONS #--------------------------------------------------- # --- write verbose text _wd() { if [ "$verbose" = "yes" ] ; then out="${out}$* " ; fi } #--------------------------------------------------- # --- get config entries in the DATA comment lines # get line(s) for config # param string one of label|data _cfg_reader(){ grep "^# DATA:$METHOD:$1:" $0 } _cfg_getlabel(){ _cfg_reader "label" | cut -f 4- -d ":" } _cfg_dataitem(){ _cfg_reader "data" | cut -f $1 -d ":" | while read item do echo -n "$item " done } # get a list existing methods _cfg_getMethods(){ grep "^# DATA:.*:label:" $0 | cut -f 2 -d ":" } #--------------------------------------------------- # --- get a value from SNMP output data # global string $SYNO output of snmpget # param string mib string _getresult(){ echo "$SYNO" | grep "${1} " | cut -d "=" -f2 | cut -f 2- -d " " } # --- get a value from SNMP output data # param string mib string _get(){ _getresult $1 | cut -d ":" -f2 | cut -f 2- -d " " } # is given oid a counter? # function resturns "true" or "false" _iscounter(){ if _getresult $1 | cut -d ":" -f1 | grep -i "Counter" >/dev/null; then echo "true" else echo "false" fi } _isinteger(){ if _getresult $1 | cut -d ":" -f1 | grep -i "Integer" >/dev/null; then echo "true" else echo "false" fi } #--------------------------------------------------- # --- show usage function showHelp(){ _self=$( basename $0 ) local _methods=$( _cfg_getMethods | while read -r line do METHOD=$(echo "$line" | cut -f 1 -d ":") descr=$(_cfg_getlabel) printf " %-10s %-50s\n" "$METHOD" "$descr" done ) cat <<EOH ______________________________________________________________________ $self_APPNAME v$self_APPVERSION (c) Institute for Medical Education - University of Bern Licence: GNU GPL 3 ______________________________________________________________________ SNMP performance data of Synology storages. USAGE: $_self [options] -h SNMPTARGET PARAMETERS: -a STRING authentication params for snmpwalk/ snmpget to connect to target; default: \"-v2c -c public\" (Snmpv2 with community string \"public\") -h SNMPTARGET as fqdn or ip address; default: localhost -f FILE read authentication from config file default: "/etc/icinga2/snmp.cfg" -m method what to show method is one of ... $_methods -v verbose output CONFIG FILE: The config file can be multiline and has the syntax [SNMPTARGET]:[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: $_self -h 192.168.100.12 -v -m cpu EOH ph.abort "" } #--------------------------------------------------- # MAIN #--------------------------------------------------- while getopts a:h:m:v OPTNAME; do case "$OPTNAME" in a) SNMPAUTH="$OPTARG" ;; C) SNMPCOMMUNITY="$OPTARG" ;; f) SNMPCONFIG="$OPTARG" ;; h) SNMPTARGET="$OPTARG" option_found=1 ;; m) METHOD="$OPTARG" ;; v) verbose="yes" _wd "" ;; *) usage ;; esac done if [ "$option_found" = "0" ] || [ "$SNMPTARGET" = "" ] ; then usage # remark: script aborts ... fi test -z "$SNMPAUTH" && read_config # --- read metadata of the selected METHOD info=$(_cfg_getlabel) if [ -z "$info" ]; then echo "ERROR: unknown METHOD [$METHOD]" showHelp fi prflist=( $(_cfg_dataitem 4) ) oidlist=( $(_cfg_dataitem 5) ) unitlist=( $(_cfg_dataitem 6) ) looplist=( $(_cfg_dataitem 7) ) # --- check for looplist if [ -n "$looplist" ]; then nb=$($SNMPWALK -OQne -t $SNMPTIMEOUT $SNMPAUTH $SNMPTARGET ${oidlist[*]} 2> /dev/null | wc -l) declare -a tmpPrflist=() declare -a tmpOidlist=() declare -a tmpUnitlist=() for i in $(seq 1 $nb); do for j in $(seq 1 ${#looplist[@]}) do tmpPrflist+=("${prflist[$(($j-1))]}.$(($i-1))") tmpOidlist+=("${looplist[$(($j-1))]}.$(($i-1))") tmpUnitlist+=("${unitlist[$(($j-1))]}") done done prflist=( "${tmpPrflist[@]}" ) oidlist=( "${tmpOidlist[@]}" ) unitlist=( "${tmpUnitlist[@]}" ) fi # --- SNMPGET to all wanted oids SYNO=$($SNMPGET -One -t $SNMPTIMEOUT $SNMPAUTH $SNMPTARGET ${oidlist[*]} 2> /dev/null) if [ $? -ne 0 ] ; then $SNMPGET -One -t $SNMPTIMEOUT $SNMPAUTH $SNMPTARGET ${oidlist[*]} ph.abort "Problem with SNMP request" fi # --- performance data # typeset -i value for index in ${!oidlist[*]} do label="${prflist[$index]}" value=$(_get ${oidlist[$index]}) unit="${unitlist[$index]}" # handle loop data if [ -n "$looplist" ]; then _wd "$( printf '%-14s %s %s' $label $value $unit )" else # handle counter data if [ "$(_iscounter ${oidlist[$index]})" = "true" ]; then value2=$(ph.perfdeltaspeed "snmp-data-${SNMPTARGET}-${method}-${label}" $value) _wd "$( printf '%-14s total: %-14s delta: %6s %s per sec' $label $value $value2 $unit )" value=$value2 elif [ "$(_isinteger ${oidlist[$index]})" = "true" ]; then _wd "$( printf '%-14s %s %s' $label $value $unit )" value2=$( echo "${value}" | sed -E "s#([0-9]*) (.).*#\1\2#g") value=${value2} else _wd "$( printf '%-14s %s %s' $label $value $unit )" fi fi ph.perfadd "${label}" "${value}" done # --- output ph.status "SNMP performance data :: $info $out" ph.exit