-
Hahn Axel (hahn) authoredHahn Axel (hahn) authored
check_disk-io 5.49 KiB
#!/bin/bash
# ======================================================================
#
# Check DISK IO over all disks
#
# data besed on /proc/diskstats
# https://www.kernel.org/doc/Documentation/iostats.txt
#
# based on /sys/block/*/stat
# https://www.kernel.org/doc/Documentation/block/stat.txt
#
# Requires: bc, lsblk
#
# ----------------------------------------------------------------------
# 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
# ======================================================================
. $( dirname $0 )/inc_pluginfunctions
export self_APPVERSION=1.1
# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------
# diskinfo based on lsblk
# param string comma separated list of names (no spaces)
function _diskInfo(){
local _fields=$1
test -z "$_fields" && _fields='NAME,MAJ:MIN,TYPE,SIZE,FSTYPE,MOUNTPOINT,STATE,ROTA,VENDOR,MODEL,SERIAL,HCTL'
lsblk -ai --output "$_fields"
}
# get a list of local disks
function getDisks(){
_diskInfo "NAME,TYPE" | grep "disk" | awk '{ print $1 }' | sed "s#[^a-z0-9]##g"
}
# UNUSED get a list of local partitions
# function getPartitions(){
# _diskInfo "NAME,TYPE" | grep "part" | awk '{ print $1 }' | sed "s#[^a-z0-9]##g"
# }
# show help
function showHelp(){
local _self; _self=$(basename $0)
cat <<EOF
$( ph.showImlHelpHeader )
Disk infos based on /sys/block/[NAME]/stat
See https://www.kernel.org/doc/Documentation/block/stat.txt
and https://www.kernel.org/doc/Documentation/iostats.txt
The system data are counters that are difficult to read.
The output of this check for each value a delta value per second since
last check.
SYNTAX:
$_self -m MODE
OPTIONS:
-m MODE set mode for type of output (required)
-h or --help show this help.
PARAMETERS:
MODE
io read I/Os, write I/Os, discard I/0s
ticks read ticks, write ticks, discard ticks
wait total wait time for all requests
EXAMPLE:
$_self -m io
EOF
}
# ----------------------------------------------------------------------
# MAIN
# ----------------------------------------------------------------------
typeset -i iDelta=0
case "$1" in
"--help"|"-h")
showHelp
exit 0
;;
*)
esac
ph.require bc lsblk
# --- set mode
sMode=$( ph.getValueWithParam '' m "$@")
# --- labels and its columns in /sys/block/$myDisk/stat
# Name units description
# ---- ----- -----------
# 1 read I/Os requests number of read I/Os processed
# 2 read merges requests number of read I/Os merged with in-queue I/O
# 3 read sectors sectors number of sectors read
# 4 read ticks milliseconds total wait time for read requests
# 5 write I/Os requests number of write I/Os processed
# 6 write merges requests number of write I/Os merged with in-queue I/O
# 7 write sectors sectors number of sectors written
# 8 write ticks milliseconds total wait time for write requests
# 9 in_flight requests number of I/Os currently in flight
# 10 io_ticks milliseconds total time this block device has been active
# 11 time_in_queue milliseconds total wait time for all requests
# 12 discard I/Os requests number of discard I/Os processed
# 13 discard merges requests number of discard I/Os merged with in-queue I/O
# 14 discard sectors sectors number of sectors discarded
# 15 discard ticks milliseconds total wait time for discard requests
case "$sMode" in
"io")
info="read I/Os, write I/Os, discard I/0s, number of I/Os currently in flight"
aNames=(ReadIO WriteIO DiscardIO FlightIO)
aColums=(1 5 12 9)
;;
"ticks")
info="ticks=total wait time [ms] --> read ticks, write ticks, discard ticks, io ticks (total time this block device has been active)"
aNames=(ReadTicks WriteTicks DiscardTicks IoTicks)
aColums=(4 8 15 10)
;;
"wait")
info="total wait time [ms] for all requests"
aNames=(Wait)
aColums=(11)
;;
*)
echo "ERROR: missing or wrong MODE parameter -m"
showHelp
exit 1
esac
tmpfile1=$(mktemp)
# --- add data for each disk
for myDisk in $(getDisks)
do
echo >>"$tmpfile1"
echo "--- $myDisk" >> "$tmpfile1"
diskdata=$( cat /sys/block/$myDisk/stat )
# echo $diskdata >> $tmpfile1
for index in ${!aNames[*]}
do
label="disk-$myDisk-${aNames[$index]}"
column=${aColums[$index]}
value=$( echo $diskdata | cut -f $column -d " " )
iDelta=$(ph.perfdeltaspeed "$label" $value)
typeset -i aTotals[$index]=${aTotals[$index]}+$iDelta
# echo " $label $iDelta per sec ... total: $value" >> "$tmpfile1"
printf "%30s %10d \n" "$label:" "$iDelta" >> "$tmpfile1"
done
done
# --- add total
echo >>"$tmpfile1"
echo "--- TOTAL" >> "$tmpfile1"
for index in ${!aNames[*]}
do
label="${aNames[$index]}"
value=${aTotals[$index]}
# echo " $label: $value" >> $tmpfile1
printf "%30s %10d \n" "$label:" "$value" >> "$tmpfile1"
ph.perfadd "$label" "$value"
done
echo >>"$tmpfile1"
# --- output
ph.status "Disk data ... $info " # READ `toUnit $iTotalRead M` MB/s << [DISC] << `toUnit $iTotalWrite M` MB/s WRITE"
cat "$tmpfile1"
# --- cleanup and bye
rm -f "$tmpfile1"
ph.exit