Browse Source

Add smart plugin

Emmanuel Bouthenot 7 years ago
parent
commit
ebec3ba80f

+ 2 - 0
plugins/client/smart/conf/smart.conf

@@ -0,0 +1,2 @@
+UserParameter=sys.smart.list,sudo /etc/zabbix/scripts/smart -s
+UserParameter=sys.smart.info[*],sudo /etc/zabbix/scripts/smart -d '$1' -a '$2'

+ 151 - 0
plugins/client/smart/scripts/smart

@@ -0,0 +1,151 @@
+#!/bin/sh
+
+# {{{ Variables
+DEVICE=
+ATTRIBUTE=
+ATTRIBUTE_ID=
+SCAN=0
+ZBX_DISCOVERY_OUTPUT=0
+# }}}
+
+# {{{ usage()
+usage() {
+cat <<EOH
+USAGE: $(basename "$0") -d DEVICE -a ATTRIBUTE
+
+Get SMART attribute value for a device
+
+Options:
+    -d  Device path compatible with smarctl (e.g /dev/sda or '/dev/bus/0 -d megaraid,4')
+    -a  Attribute name or ID (e.g Temperature_Celsius, Offline_Uncorrectable, 194, 233, etc.)
+    -S  Scan devices and display list in a 'smartctl' compatible way
+    -s  Scan devices and display list in a 'smartctl' compatible way (Zabbix discovery output)
+EOH
+}
+# }}}
+
+# {{{ scan_megaraid_devices()
+scan_megaraid_devices() {
+    if which storcli >/dev/null 2>&1 ; then
+        ctrlcount=$(storcli show ctrlcount| sed -n 's/^Controller Count = //p')
+        if [ "${ctrlcount}" -gt 0 ]; then
+            ctrlcount=$(( ${ctrlcount} - 1))
+            devices_ids=""
+            for i in $(seq 0 ${ctrlcount}) ; do
+                devices_ids="${devices_ids} $(storcli /c${i}/dall show| sed -r -n 's/\s*[0-9]+\s+[0-9]+\s+[0-9]+\s+[0-9]+:[0-9]+\s+([0-9]+)\s+DRIVE.*/\1/p' | xargs)"
+            done
+            for d in ${devices_ids} ; do
+                printf "/dev/bus/0 -d sat+megaraid,${d}\n"
+            done
+        fi
+    fi
+}
+# }}}
+
+# {{{ scan_devices()
+scan_devices() {
+    find /dev -regex '/dev/sg[0-9]'
+    find /dev -regex '/dev/sd[a-z]'
+    smartctl --scan | \
+        sed -r 's/\s+#.*$//' | \
+        sed 's/megaraid/sat+megaraid/g'
+    scan_megaraid_devices
+}
+# }}}
+
+# {{{ list_smart_devices()
+list_smart_devices() {
+    ZBX="${1}"
+    if [ "${ZBX}" = 1 ]; then
+        printf '{"data":['
+    fi
+    if which smartctl >/dev/null 2>&1 ; then
+        serials=""
+        scan_devices | \
+            while read d ; do
+                diskinfo=$(smartctl -i $d)
+                if echo "${diskinfo}" | egrep -q '^Device is:' ; then
+                    serial=$(echo "${diskinfo}" | sed -r -n 's/^Serial Number:\s+(.*)$/\1/p')
+                    if ! echo "${serials}" | grep -q "${serial}" ; then
+                        serials="${serials} ${serial}"
+                        capacity=$(echo "${diskinfo}" | sed -r -n 's/User Capacity:\s+.*\[(.*)\]$/\1/p')
+                        hwrot=$(echo "${diskinfo}" | sed -r -n 's/Rotation Rate:\s+(.*)$/\1/p')
+                        if [ "${ZBX}" = 1 ]; then
+                            printf '{'
+                            printf '"{#DEVICE}":"%s",' "${d}"
+                            printf '"{#SERIAL}":"%s",' "${serial}"
+                            printf '"{#CAPACITY}":"%s",' "${capacity}"
+                            printf '"{#HWROT}":"%s"' "${hwrot}"
+                            printf '},'
+                        else
+                            echo "${d}|${serial}|${capacity}|${hwrot}"
+                        fi
+                    fi
+                fi
+            done | sed 's/},$/}/'
+    fi
+    if [ "${ZBX}" = 1 ]; then
+        printf ']}'
+    fi
+}
+# }}}
+
+# {{{ main()
+while getopts "d:a:Ss" OPT ; do
+    case "$OPT" in 
+        \?|h)
+            usage
+            exit 0
+            ;;
+        d)
+            DEVICE="$OPTARG"
+            ;;
+        a)
+            ATTRIBUTE="$OPTARG"
+            ;;
+        S)
+            SCAN=1
+            ;;
+        s)
+            SCAN=1
+            ZBX_DISCOVERY_OUTPUT=1
+            ;;
+    esac
+done
+
+if [ "${SCAN}" = 1 ]; then
+    list_smart_devices "${ZBX_DISCOVERY_OUTPUT}"
+    exit 0
+fi
+
+if [ -z "${DEVICE}" ] ; then
+    printf "[ERR] device is not defined\n"
+    usage
+    exit 1
+fi
+
+if [ -z "${ATTRIBUTE}" ] ; then
+    printf "[ERR] attribute name or attribute ID is not defined\n"
+    usage
+    exit 1
+fi
+
+if echo "${ATTRIBUTE}" | egrep -q '^[[:digit:]]+$'; then
+    data=$(smartctl -A ${DEVICE} | egrep "^[[:space:]]*${ATTRIBUTE}[[:space:]]+[A-Z]+")
+else
+    data=$(smartctl -A ${DEVICE} | egrep "^[[:space:]]*[[:digit:]]+[[:space:]]+${ATTRIBUTE}")
+fi
+
+if [ $? != 0 ]; then
+    printf -- "-1\n"
+else
+    printf "${data}\n" | \
+        tr -s ' ' | \
+        sed 's/^[[:space:]]*\(.*\)[[:space:]]*$/\1/' | \
+        cut -d ' ' -f 10
+fi
+
+exit 0
+# }}}
+
+# vim: foldmethod=marker foldlevel=0 foldenable

+ 4 - 0
plugins/client/smart/sudo/zabbix_plugins_smart

@@ -0,0 +1,4 @@
+#
+# Permit to zabbix user to execute 'smart' plugin
+#
+zabbix ALL=NOPASSWD: /etc/zabbix/scripts/smart