diff --git a/check_disk-io b/check_disk-io index 4e4c6cba57cbb2b3cdb84b7f895bec48e9d81e3a..4f0e72635e67a1463a5e0f7c7314d1baf9c44afc 100755 --- a/check_disk-io +++ b/check_disk-io @@ -15,12 +15,13 @@ # 2020-07-17 v1.0 <axel.hahn@iml.unibe.ch> # 2023-07-27 v1.1 <axel.hahn@unibe.ch> shell fixes; remove unsupported warn and critical # 2025-02-10 v1.2 <axel.hahn@unibe.ch> harden sourcing files +# 2025-04-02 v1.3 <axel.hahn@unibe.ch> add mode "measure" for read write speed # ====================================================================== # shellcheck source=/dev/null . "$( dirname "$0" )/inc_pluginfunctions" || exit 1 -export self_APPVERSION=1.2 +export self_APPVERSION=1.3 # ---------------------------------------------------------------------- # FUNCTIONS @@ -39,6 +40,27 @@ function getDisks(){ _diskInfo "NAME,TYPE" | grep "disk" | awk '{ print $1 }' | sed "s#[^a-z0-9]##g" } + +function measureline(){ + local mydevice="$1" + local bsize="$2" + local mode="$3" + local out="$4" + local timer + local speed + timer=$( tail -1 <<< "${out}" | cut -f 3 -d ",") + speed=$( tail -1 <<< "${out}" | cut -f 4 -d ",") + + info+=" $mode $speed" + + # printf "%-25s %-10s %-10s %-15s %10s\n" "$mydevice" "$mode" "$bsize" "$timer" "$speed" + # perf="$( sed "s#\ \([.]\).*#\1#g" <<< "$speed" )" + perf="$( awk '{ print $1 " " $2 }' <<< "$speed" | sed "s#\ \(.\).*#\1#g" )" + perf="$( ph.toUnit "$perf" "M" )" + ph.perfadd "$mode" "$perf" + +} + # UNUSED get a list of local partitions # function getPartitions(){ # _diskInfo "NAME,TYPE" | grep "part" | awk '{ print $1 }' | sed "s#[^a-z0-9]##g" @@ -63,18 +85,32 @@ $_self -m MODE OPTIONS: - -m MODE set mode for type of output (required) -h or --help show this help. + -m MODE set mode for type of output (required) + -d DIR for measure: set a directory, default: "/tmp" + -s SIZE for measure: set a size, default: "100M" PARAMETERS: MODE io read I/Os, write I/Os, discard I/0s + measure measure write and read speed ticks read ticks, write ticks, discard ticks wait total wait time for all requests + DIR + Directory to perform read and write test. + + SIZE + Block size for dd command: a number followed multiplicative suffix. + c=1, w=2, b=512, kB=1000, K=1024, MB=1000*1000, M=1024*1024, xM=M, + GB=1000*1000*1000, G=1024*1024*1024, and so on for T, P, E, Z, Y, R, Q + EXAMPLE: -$_self -m io + + $_self -m io + $_self -m measure + $_self -m measure -d /mnt/data -s 10M EOF } @@ -98,6 +134,22 @@ ph.require bc lsblk # --- set mode sMode=$( ph.getValueWithParam '' m "$@") +if [ "$sMode" = "measure" ]; then + sDir=$( ph.getValueWithParam '/tmp' d "$@") + bsize=$( ph.getValueWithParam '100M' s "$@") + target="${sDir}/$( tr -cd 'a-f0-9' <<< /dev/urandom | head -c 32 )" + + info="Disk speed in ${sDir} using $bsize - " + + measureline "${sDir}" "$bsize" "WRITE" "$( dd if=/dev/zero of="${target}" bs=$bsize count=1 oflag=dsync 2>&1 )" + measureline "${sDir}" "$bsize" "READ" "$( dd if="${target}" of=/dev/null bs=$bsize count=1 oflag=dsync 2>&1 )" + rm -f "${target}" + + ph.status "$info" + + ph.exit +fi + # --- labels and its columns in /sys/block/$myDisk/stat # Name units description @@ -160,9 +212,14 @@ do column=${aColums[$index]} value=$( echo $diskdata | cut -f $column -d " " ) - iDelta=$(ph.perfdeltaspeed "$label" $value) + iDelta=$(ph.perfdeltaspeed "$label" "$value") - typeset -i aTotals[$index]=${aTotals[$index]}+$iDelta + # typeset -i aTotals["$index"]=${aTotals["$index"]}+$iDelta + + typeset -i aMax["$index"] + if [ -z "${aMax["$index"]}" ] || [ ${aMax["$index"]} -lt $iDelta ]; then + aMax["$index"]=$iDelta + fi # echo " $label $iDelta per sec ... total: $value" >> "$tmpfile1" printf "%30s %10d \n" "$label:" "$iDelta" >> "$tmpfile1" @@ -171,12 +228,13 @@ done # --- add total echo >>"$tmpfile1" -echo "--- TOTAL" >> "$tmpfile1" +echo "--- MAX" >> "$tmpfile1" for index in ${!aNames[*]} do label="${aNames[$index]}" - value=${aTotals[$index]} + # value=${aTotals[$index]} + value=${aMax[$index]} # echo " $label: $value" >> $tmpfile1 printf "%30s %10d \n" "$label:" "$value" >> "$tmpfile1" ph.perfadd "$label" "$value" diff --git a/docs/20_Checks/check_disk_io.md b/docs/20_Checks/check_disk_io.md index 2df6455ad2e0cbc5822517a42a9ef3d7452cb4d2..1926991158dfbc2a43a6c218837c0e2932a00972 100644 --- a/docs/20_Checks/check_disk_io.md +++ b/docs/20_Checks/check_disk_io.md @@ -21,13 +21,13 @@ From this repository you need next to this script: ```txt ______________________________________________________________________ -CHECK_DISK-IO -v1.2 - -Check dis io and latency +CHECK_DISK-IO +v1.3 (c) Institute for Medical Education - University of Bern Licence: GNU GPL 3 + +https://os-docs.iml.unibe.ch/icinga-checks/Checks/check_disk_io.html ______________________________________________________________________ Disk infos based on /sys/block/[NAME]/stat @@ -43,18 +43,32 @@ check_disk-io -m MODE OPTIONS: - -m MODE set mode for type of output (required) -h or --help show this help. + -m MODE set mode for type of output (required) + -d DIR for measure: set a directory, default: "/tmp" + -s SIZE for measure: set a size, default: "100M" PARAMETERS: MODE io read I/Os, write I/Os, discard I/0s + measure measure write and read speed ticks read ticks, write ticks, discard ticks wait total wait time for all requests + DIR + Directory to perform read and write test. + + SIZE + Block size for dd command: a number followed multiplicative suffix. + c=1, w=2, b=512, kB=1000, K=1024, MB=1000*1000, M=1024*1024, xM=M, + GB=1000*1000*1000, G=1024*1024*1024, and so on for T, P, E, Z, Y, R, Q + EXAMPLE: -check_disk-io -m io + + check_disk-io -m io + check_disk-io -m measure + check_disk-io -m measure -d /mnt/data -s 10M ``` @@ -64,28 +78,36 @@ check_disk-io -m io ## Examples +### Disk io + `$ check_disk-io -m io` returns ```txt OK: Disk data ... read I/Os, write I/Os, discard I/0s, number of I/Os currently in flight ---- sda - disk-sda-ReadIO: 0 - disk-sda-WriteIO: 0 - disk-sda-DiscardIO: 0 - disk-sda-FlightIO: 0 - --- nvme0n1 - disk-nvme0n1-ReadIO: 3 - disk-nvme0n1-WriteIO: 16 - disk-nvme0n1-DiscardIO: 4 + disk-nvme0n1-ReadIO: 401 + disk-nvme0n1-WriteIO: 61 + disk-nvme0n1-DiscardIO: 0 disk-nvme0n1-FlightIO: 0 ---- TOTAL - ReadIO: 3 - WriteIO: 16 - DiscardIO: 4 +--- MAX + ReadIO: 401 + WriteIO: 61 + DiscardIO: 0 FlightIO: 0 - |readio=3;; writeio=16;; discardio=4;; flightio=0;; + |readio=401;; writeio=61;; discardio=0;; flightio=0;; ``` + +### Measure + +The mode `measure` writes a randomly generated filename with `dd` and reads the file afterwards. From the output is the of the command we fetch the speed in MB/s or GB/s. + +```txt +$ check_disk-io -m measure +OK: Disk speed in /tmp using 100M - WRITE 952 MB/s READ 4.1 GB/s + |write=952;; read=4198.4;; +``` + +By default the check is done in /tmp with 100MB generated random data. You can set another directory eg. to perform a check on a mounted filesystem. diff --git a/inc_pluginfunctions b/inc_pluginfunctions index 528fc7c67d430e10eee1d5cfe5ace6e3f533419d..b900bcb4a2ece849b9ae47b07f6e7b94fc61b88a 100644 --- a/inc_pluginfunctions +++ b/inc_pluginfunctions @@ -42,6 +42,7 @@ # 2023-09-05 v1.14 <axel.hahn@unibe.ch> ph.require - show error below status line # 2023-09-14 v1.15 <axel.hahn@unibe.ch> add ph.showtimer; fix broken pipe messages in journallog # 2024-05-30 v1.16 <axel.hahn@unibe.ch> updatate link to online help (Daux replaces "-"" to "_") +# 2025-04-01 v1.17 <axel.hahn@unibe.ch> update check for zero in ph.toUnit() # ====================================================================== @@ -329,7 +330,7 @@ function ph.toUnit(){ local _digits=${3:-0} local _dots - if [ "$_value" -eq "0" ]; then + if [ "$_value" = "0" ]; then echo "0" return 0 fi