So, I developed a bash script that will do this on a modern Linux kernel. It's not perfected yet, but it should help you find the process doing the most io without having to install anything on the server.
#! /bin/bash
function is_number() {
if [ $1 -eq $1 2> /dev/null ]; then
return 1
fi
}
function get_leaf_path() {
leaf_path=${1##*/}
}
first_flag=1
flip=0
while [[ 1 ]]; do
# loop through running processes
unset DeltaReads
unset DeltaWrites
for p in /proc/*
do
if [ -d $p ]; then
#set leaf_path to the last subdirectory name in the path
get_leaf_path $p
#check if the leaf_path is numeric
is_number $leaf_path
res=$?
if (( $res > 0 )); then
#now we have a PID let's get its stats
io=`cat $p/io`
cmd=`cat $p/cmdline`
cmd=`echo "$cmd"|tr -d '[:cntrl:]\000\040'`
#get write_bytes number
pattern="write_bytes: ([0-9]+)"
[[ $io =~ $pattern ]]
#get bytes
wbytes=${BASH_REMATCH[1]}
#get read_bytes number
pattern="read_bytes: ([0-9]+)"
[[ $io =~ $pattern ]]
rbytes=${BASH_REMATCH[1]}
#set Reads element to 0 if it is null or empty
if [[ -z "${Reads[$leaf_path]+x}" ]]; then
Reads[$leaf_path]=0
fi
if [[ -z "${Writes[$leaf_path]+x}" ]]; then
Writes[$leaf_path]=0
fi
# is this PID reused?
if [[ "$cmd" != "${Cmdline[$leaf_path]}" ]]; then
DeltaReads[$leaf_path]=0
DeltaWrites[$leaf_path]=0
#echo "cmd " $cmd "||||||||||"
#echo "prevcmd " ${Cmdline[$leaf_path]} "||||||||||"
else
DeltaReads[$leaf_path]=$(($rbytes - Reads[$leaf_path]))
DeltaWrites[$leaf_path]=$(($wbytes - Writes[$leaf_path]))
fi
DeltaTot[$leaf_path]=$((DeltaReads[$leaf_path]+DeltaWrites[$leaf_path]))
Reads[$leaf_path]=$rbytes
Writes[$leaf_path]=$wbytes
Cmdline[$leaf_path]=$cmd
fi
fi
done
#remove information for old PIDs
for i in "${!Cmdline[@]}"; do
if [[ ! -d /proc/$i ]]; then
#process $i was not found on this cycle
unset DeltaTot[$i]
unset DeltaReads[$i]
unset DeltaWrites[$i]
unset Reads[$i]
unset Writes[$i]
unset Cmdline[$i]
fi
done
#Output results
clear
if [[ $first_flag -eq 0 ]]; then
printf "%5s %35s %10s %10s %10s\n" "PID" "CMD" "DeltaTot" "DWrites" "DReads"
deltatoto=0
for i in "${!DeltaTot[@]}"; do
printf "%5s %35s %10s %10s %10s %10s\n" $i ${Cmdline["$i"]:0:35} ${DeltaTot["$i"]} ${DeltaWrites["$i"]} ${DeltaReads["$i"]}
done |
sort -brn -k4 | head -20
for i in "${!DeltaTot[@]}"; do
deltatoto=$((${DeltaTot[$i]} + $deltatoto))
done
tput bold
echo "Delta Total: " $deltatoto
tput sgr0
fi
first_flag=0
done
No comments:
Post a Comment