From e9d3cd8bd2e36b780c44366c1364d8efd0ad003c Mon Sep 17 00:00:00 2001 From: niki Date: Fri, 23 Jul 2021 13:28:55 +0500 Subject: [PATCH] Add files via upload --- README.md | 36 ++++++++++- Template smartmonitor.xml | 107 ++++++++++++++++++--------------- smartctl-storage-discovery.ps1 | 7 ++- smartctl-storage-discovery.sh | 65 +++++++++++++------- zabbix_agentd.conf | 13 ++-- 5 files changed, 150 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index 50e5637..6622632 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ ### Installing for linux #### Requirements: -- OS: RedHat family +- OS: Linux - Zabbix-agent: 4.0 and later - Smartmontools: 7.1 and later @@ -61,6 +61,40 @@
+### Installing for MacOS(In developing!!!) +#### Requirements: +- OS: MacOS +- Zabbix-agent: 4.0 and later +- Smartmontools: 7.1 and later + +#### Get utils smartmontools +- https://builds.smartmontools.org/ + +#### Copy bash script: +- **github**/smartctl-storage-discovery.sh in /usr/local/etc/zabbix/smartctl-storage-discovery.sh + +#### Chmod and Chown +- ```chmod 755 /usr/local/etc/zabbix/smartctl-storage-discovery.sh``` + +#### Check bash script(Out json): +- ```/usr/local/etc/zabbix/smartctl-storage-discovery.sh``` + +#### Set UnsafeUserParameters=1 +(In developing!!!) + +#### Add from zabbix_agentd.conf "UserParameter" in zabbix_agentd.conf: +- **github**/zabbix_agentd.conf + +#### Add in /etc/sudoers OR visudo +- Defaults:zabbix !requiretty +- zabbix ALL=(root) NOPASSWD: /usr/local/sbin/smartctl +- zabbix ALL=(root) NOPASSWD: /usr/local/etc/zabbix/smartctl-storage-discovery.sh + +#### Import zabbix template: +- **github**/Template smartmonitor.xml + +
+ #### Examples images: - Graph: Temperature smartmonitor ![Image alt](https://github.com/nikimaxim/zbx-smartmonitor/blob/master/img/1.png) diff --git a/Template smartmonitor.xml b/Template smartmonitor.xml index 8917c2a..e15add4 100644 --- a/Template smartmonitor.xml +++ b/Template smartmonitor.xml @@ -1,7 +1,7 @@ 5.0 - 2020-12-17T07:27:23Z + 2021-07-23T08:27:01Z Templates Users @@ -13,7 +13,7 @@ Template SMARTMONTOOLS # # .VERSION -# 0.4 +# 0.7 # # .DESCRIPTION # Author: Nikitin Maksim @@ -69,6 +69,46 @@ + + {#STORAGE.NAME}: Error сount + DEPENDENT + storage.error["{#STORAGE.CMD}"] + 0 + 0 + CHAR + HDD +SSD +NVME + + + SMART monitoring (smartctl) + + + + + JAVASCRIPT + if (value.search("No Errors Logged") != -1) { + return "No Errors Logged" +} else if (value.search("ATA Error Count:") != -1) { + return value.match(/(?:ATA Error Count:).+\b([0-9]+)/i)[1] +} else { + return "Not supported" +} + + + + + storage.get["{#STORAGE.CMD}"] + + + + {str(No Errors Logged)}=0 and {str(Not supported)}=0 + {#STORAGE.NAME}: SMART error status is not "No Errors Logged" + AVERAGE + YES + + + {#STORAGE.NAME}: Smartctl storage.get["{#STORAGE.CMD}"] @@ -90,15 +130,12 @@ {str("FAILING_NOW")}=1 - {#STORAGE.NAME}: One or more SMART attributes are FAILING_NOW + {#STORAGE.NAME}: One or more SMART attributes are "FAILING_NOW" AVERAGE + YES - {#STORAGE.NAME}: SMART status is not OK - {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str({$SMARTCTL_OK_STATUS:"SATA"})}=0 and {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str({$SMARTCTL_OK_STATUS:"SAS"})}=0 - - - {#STORAGE.NAME}: SMART test status FAILED + {#STORAGE.NAME}: SMART test status is "FAILED" {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str("FAILED!")}=1 @@ -132,21 +169,9 @@ SSD storage.get["{#STORAGE.CMD}"] - - {str({$SMARTCTL_OK_STATUS:"SATA"})}=0 and {str({$SMARTCTL_OK_STATUS:"SAS"})}=0 - {#STORAGE.NAME}: SMART status is not OK - WARNING - YES - - - {#STORAGE.NAME}: SMART test status FAILED - {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str("FAILED!")}=1 - - - {str("FAILED!")}=1 - {#STORAGE.NAME}: SMART test status FAILED + {#STORAGE.NAME}: SMART test status is "FAILED" AVERAGE @@ -171,6 +196,8 @@ NVME REGEX (?:Vendor:|Product:|Device [Mm]odel:|Model [Nn]umber:).+ (.+) \1 + CUSTOM_ERROR + Not supported @@ -197,6 +224,8 @@ NVME REGEX (?:Serial [Nn]umber:).+ ([\d\w-]+) \1 + CUSTOM_ERROR + Not supported @@ -246,11 +275,7 @@ SSD YES - {#STORAGE.NAME}: SMART status is not OK - {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str({$SMARTCTL_OK_STATUS:"SATA"})}=0 and {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str({$SMARTCTL_OK_STATUS:"SAS"})}=0 - - - {#STORAGE.NAME}: SMART test status FAILED + {#STORAGE.NAME}: SMART test status is "FAILED" {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str("FAILED!")}=1 @@ -276,6 +301,8 @@ NVME REGEX (?:9 Power_On_Hours|Power On Hours:|[Nn]umber of hours powered up|Accumulated power on time).+ ([0-9]+) \1 + CUSTOM_ERROR + Not supported MULTIPLIER @@ -352,7 +379,7 @@ NVME {last()}<=100 RECOVERY_EXPRESSION {avg(5m)}<{$TEMP_CRIT}-3 - {#STORAGE.NAME}: Disk temperature CRITICAL + {#STORAGE.NAME}: Disk temperature is "CRITICAL" AVERAGE YES @@ -360,12 +387,12 @@ NVME {avg(5m)}>{$TEMP_WARN} RECOVERY_EXPRESSION {avg(5m)}<{$TEMP_WARN}-3 - {#STORAGE.NAME}: Disk temperature WARNING + {#STORAGE.NAME}: Disk temperature is "WARNING" WARNING YES - {#STORAGE.NAME}: Disk temperature CRITICAL + {#STORAGE.NAME}: Disk temperature is "CRITICAL" {Template SMARTMONTOOLS:storage["{#STORAGE.CMD}", 190/194 Temperature_Celsius].avg(5m)}>{$TEMP_CRIT} and {Template SMARTMONTOOLS:storage["{#STORAGE.CMD}", 190/194 Temperature_Celsius].last()}<=100 {Template SMARTMONTOOLS:storage["{#STORAGE.CMD}", 190/194 Temperature_Celsius].avg(5m)}<{$TEMP_CRIT}-3 @@ -410,11 +437,7 @@ NVME {Template SMARTMONTOOLS:storage["{#STORAGE.CMD}", 05 Reallocated_Sector_Ct].last()}=0 or {Template SMARTMONTOOLS:storage["{#STORAGE.CMD}", 05 Reallocated_Sector_Ct].delta(864000)}=0 - {#STORAGE.NAME}: SMART status is not OK - {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str({$SMARTCTL_OK_STATUS:"SATA"})}=0 and {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str({$SMARTCTL_OK_STATUS:"SAS"})}=0 - - - {#STORAGE.NAME}: SMART test status FAILED + {#STORAGE.NAME}: SMART test status is "FAILED" {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str("FAILED!")}=1 @@ -447,17 +470,13 @@ SSD - {delta(7d)}>0 + {diff()}=1 {#STORAGE.NAME}: SMART uncorrectable sector count has been registered AVERAGE YES - {#STORAGE.NAME}: SMART status is not OK - {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str({$SMARTCTL_OK_STATUS:"SATA"})}=0 and {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str({$SMARTCTL_OK_STATUS:"SAS"})}=0 - - - {#STORAGE.NAME}: SMART test status FAILED + {#STORAGE.NAME}: SMART test status is "FAILED" {Template SMARTMONTOOLS:storage.health["{#STORAGE.CMD}"].str("FAILED!")}=1 @@ -559,14 +578,6 @@ NVME - - {$SMARTCTL_OK_STATUS:"SAS"} - OK - - - {$SMARTCTL_OK_STATUS:"SATA"} - PASSED - {$TEMP_CRIT} 65 diff --git a/smartctl-storage-discovery.ps1 b/smartctl-storage-discovery.ps1 index d3e884b..fdf3f68 100644 --- a/smartctl-storage-discovery.ps1 +++ b/smartctl-storage-discovery.ps1 @@ -1,6 +1,6 @@ <# .VERSION - 0.4 + 0.7 .DESCRIPTION Author: Nikitin Maksim @@ -10,6 +10,7 @@ .TESTING PowerShell: 5.1 and later Smartmontools: 7.1 and later + OS: Windows 7, Windows 8, Windows 10 #> $CTL = "C:\Program Files\smartmontools\bin\smartctl.exe" @@ -94,7 +95,7 @@ foreach ($device in $smart_scan) { # Get device type: # - 0 is for HDD # - 1 is for SSD - # - 1 is for NVMe + # - 2 is for NVMe $rotation_rate = $info | Select-String "Rotation Rate:" if ($rotation_rate -like "*rpm*") { $storage_type = 0 @@ -102,7 +103,7 @@ foreach ($device in $smart_scan) { $storage_type = 1 } elseif ($storage_args -like "*nvme*" -or $storage_name -like "*nvme*") { # Device NVMe and SMART - $storage_type = 1 + $storage_type = 2 $storage_smart = 1 } diff --git a/smartctl-storage-discovery.sh b/smartctl-storage-discovery.sh index 1c58e30..8cf52c2 100644 --- a/smartctl-storage-discovery.sh +++ b/smartctl-storage-discovery.sh @@ -1,7 +1,7 @@ #!/bin/bash # # .VERSION -# 0.4 +# 0.7 # # .DESCRIPTION # Author: Nikitin Maksim @@ -10,18 +10,40 @@ # # .TESTING # Smartmontools: 7.1 and later +# OS: CentOS 7 x64, Ubuntu 18.04 x64, MacOS High Sierra # -CTL='/usr/sbin/smartctl' +# Get OS type +OS=`uname` + +CTL='' + +if [[ -z "$CTL" ]]; then + # Default path "smartctl" + # For Linux: /usr/sbin/smartctl + # For MacOS: /usr/local/sbin/smartctl + # For Other: smartctl + if [[ $OS == 'Linux' ]]; then + CTL='/usr/sbin/smartctl' + elif [[ $OS == 'Darwin' ]]; then + CTL='/usr/local/sbin/smartctl' + else + CTL='smartctl' + fi +fi if [[ ! -x "$CTL" ]]; then echo "Could not find path: $CTL" exit fi -LLDSmart() -{ - smart_scan=$($CTL --scan-open | sed -e 's/\s*$/;/') +LLDSmart() { + # For MacOS + if [[ $OS == 'Darwin' ]]; then + smart_scan=$(diskutil list | grep -i "physical" | cut -f 1 -d' ') + else + smart_scan=$($CTL --scan-open | sed -e 's/\s*$/;/') + fi disk_sn_all=() IFS=";" @@ -34,20 +56,20 @@ LLDSmart() storage_type=0 storage_args="" - device=$(/bin/echo $device | grep -iE "^(\w*|\d*).") + device=$(echo $device | grep -iE "^(\w*|\d*).") # Remove non-working disks # Example: "# /dev/sdb -d scsi" if [[ ! ${device} =~ (^\s*#|^#) ]]; then # Extract and concatenate args - storage_args=$(/bin/echo ${device} | cut -f 1 -d'#' | awk '{print $2 $3}') + storage_args=$(echo $device | cut -f 1 -d'#' | awk '{print $2 $3}') # Get device name - storage_name=$(/bin/echo ${device} | cut -f 1 -d'#' | awk '{print $1}') + storage_name=$(echo $device | cut -f 1 -d'#' | awk '{print $1}') - temp_info=$($CTL -i $storage_name $storage_args) + info=$($CTL -i $storage_name $storage_args) # Get device SN - storage_sn=$(/bin/echo ${temp_info} | grep -i "Serial Number:" | cut -f2 -d":" | sed -e 's/^\s*//') + storage_sn=$(echo $info | grep -i "Serial Number:" | cut -f2 -d":" | sed -e 's/^\s*//') # Check duplicate storage if [[ ! -z $storage_sn ]] && [[ ! $disk_sn_all == *"$storage_sn"* ]]; then @@ -60,24 +82,24 @@ LLDSmart() storage_cmd="${storage_name} ${storage_args}" # Device SMART - if [ -n $(/bin/echo $temp_info | grep -iE "^SMART support is:.+Enabled\s*$") ]; then + if [ -n $(echo $info | grep -iE "^SMART support is:.+Enabled\s*$") ]; then storage_smart=1 fi # Get device model(For different types of devices) - d=$(/bin/echo $temp_info | grep "Device Model:" | cut -f2 -d":" | sed -e 's/^\s*//') + d=$(echo $info | grep -i "Device Model:" | cut -f2 -d":" | sed -e 's/^\s*//') if [ -n $d ]; then storage_model=$d else - m=$(/bin/echo $temp_info | grep "Model Number:" | cut -f2 -d":" | sed -e 's/^\s*//') + m=$(echo $info | grep -i "Model Number:" | cut -f2 -d":" | sed -e 's/^\s*//') if [ -n $m ]; then storage_model=$m else - p=$(/bin/echo $temp_info | grep "Product:" | cut -f2 -d":" | sed -e 's/^\s*//') + p=$(echo $info | grep -i "Product:" | cut -f2 -d":" | sed -e 's/^\s*//') if [ -n $p ]; then storage_model=$p else - v=$(/bin/echo $temp_info | grep "Vendor:" | cut -f2 -d":" | sed -e 's/^\s*//') + v=$(echo $info | grep -i "Vendor:" | cut -f2 -d":" | sed -e 's/^\s*//') if [ -n $v ]; then storage_model=$v else @@ -90,24 +112,23 @@ LLDSmart() # Get device type: # - 0 is for HDD # - 1 is for SSD - # - 1 is for NVMe - if [ -n "$(/bin/echo $temp_info | grep -iE "^Rotation Rate:.*rpm.*$")" ]; then + # - 2 is for NVMe + if [ -n "$(echo $info | grep -iE "^Rotation Rate:.*rpm.*$")" ]; then storage_type=0 - elif [ -n "$(/bin/echo $temp_info | grep -iE "^Rotation Rate:\s*Solid State Device\s*$")" ]; then + elif [ -n "$(echo $info | grep -iE "^Rotation Rate:\s*Solid State Device\s*$")" ]; then storage_type=1 elif [[ $storage_args == *"nvme"* ]] || [[ $storage_name == *"nvme"* ]]; then # Device NVMe and SMART - storage_type=1 + storage_type=2 storage_smart=1 fi - storage_info="{\"{#STORAGE.SN}\":\"${storage_sn}\",\"{#STORAGE.MODEL}\":\"${storage_model}\",\"{#STORAGE.NAME}\":\"${storage_name}\",\"{#STORAGE.CMD}\":\"${storage_cmd}\",\"{#STORAGE.SMART}\":\"${storage_smart}\",\"{#STORAGE.TYPE}\":\"${storage_type}\"}," - storage_json=$storage_json$storage_info + storage_json=$storage_json"{\"{#STORAGE.SN}\":\"${storage_sn}\", \"{#STORAGE.MODEL}\":\"${storage_model}\", \"{#STORAGE.NAME}\":\"${storage_name}\", \"{#STORAGE.CMD}\":\"${storage_cmd}\", \"{#STORAGE.SMART}\":\"${storage_smart}\", \"{#STORAGE.TYPE}\":\"${storage_type}\"}," fi fi done - echo "{\"data\":[$(/bin/echo ${storage_json} | sed -e 's/,$//')]}" + echo "{\"data\":[$(echo $storage_json | sed -e 's/,$//')]}" } LLDSmart diff --git a/zabbix_agentd.conf b/zabbix_agentd.conf index de840a2..ccfd555 100644 --- a/zabbix_agentd.conf +++ b/zabbix_agentd.conf @@ -1,9 +1,14 @@ # Windows smartctl monitor UserParameter=storage.discovery[*],powershell -NoProfile -ExecutionPolicy Bypass -File "C:\service\smartctl-storage-discovery.ps1" -UserParameter=storage.get[*],for /F "tokens=* usebackq" %a in (`""C:\Program Files\smartmontools\bin\smartctl.exe" -i -H -A -l error -l background $1"`) do @echo %a -UserParameter=smartctl.version,powershell -NoProfile -ExecutionPolicy Bypass -Command "(((& 'C:\Program Files\smartmontools\bin\smartctl.exe' --version | Where-Object {$_ -match '^smartctl\s\d'}) -ireplace 'smartctl\s') -ireplace '\s\[.+$').Trim()" +UserParameter=storage.get[*],powershell -NoProfile -ExecutionPolicy Bypass -Command "if (\"$1\") {& 'C:\Program Files\smartmontools\bin\smartctl.exe' -i -H -A -l error -l background $1}" +UserParameter=smartctl.version,powershell -NoProfile -ExecutionPolicy Bypass -Command "((& 'C:\Program Files\smartmontools\bin\smartctl.exe' --version | Where-Object {$_ -match '^smartctl\s\d'}) -ireplace 'smartctl\s' -ireplace '\s\[.+$').Trim()" # Linux smartctl monitor UserParameter=storage.discovery[*],sudo /opt/zabbix/smartctl-storage-discovery.sh -UserParameter=storage.get[*],sudo smartctl -i -H -A -l error -l background $1 -UserParameter=smartctl.version,smartctl --version | grep -Eo "^smartctl\s[0-9\.[:space:]\r-]+" | sed -e 's/^smartctl\s//' +UserParameter=storage.get[*],if [ -n "$1" ]; then sudo /usr/sbin/smartctl -i -H -A -l error -l background $1; fi +UserParameter=smartctl.version,/usr/sbin/smartctl --version | grep -Eo "^smartctl\s[0-9\.[:space:]\r-]+" | sed -e 's/^smartctl.//' + +# MacOS smartctl monitor +UserParameter=storage.discovery[*],sudo /usr/local/etc/zabbix/smartctl-storage-discovery.sh +UserParameter=storage.get[*],if [ -n "$1" ]; then sudo /usr/local/sbin/smartctl -i -H -A -l error -l background $1; fi +UserParameter=smartctl.version,/usr/local/sbin/smartctl --version | grep -Eo "^smartctl\s[0-9\.[:space:]\r-]+" | sed -e 's/^smartctl.//' \ No newline at end of file