1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
#!/bin/bash
# https://xrootd.web.cern.ch/doc/dev410/cms_config.htm#_Toc8247264
# The specified program must write 5 white-space separated numbers to standard out.
# The last number must be terminated by a new-line character (ā\nā).
# Each number must be normalized to 100, with 0 indicating no load and 100 indicating saturation. The numbers are in the order:
# 1. system load
# 2. cpu utilization
# 3. memory utilization
# 4. paging load, and
# 5. network utilization.
INTERVAL="${1:-1}" # take as parameter the interval between runs, default to 1; NB! the loop take more than a few seconds to run
NCPU=$(awk '/processor/ {nr++} END{print nr}' /proc/cpuinfo)
# replace sleep subprocess
snore() {
local IFS
[[ -n "${_snore_fd:-}" ]] || exec {_snore_fd}<> <(:)
read ${1:+-t "$1"} -u $_snore_fd || :
}
# return highest load (integer percentage) of either RX or TX
IFACE_LOAD () {
local iface="${1}"
SPEED=$(< "${iface}"/speed)
[[ "$?" -ne 0 || ! "${SPEED}" -gt 0 ]] && { echo 0; return; } # just consider the interface load to be 0
RX1=$(< "${iface}"/statistics/rx_bytes)
TX1=$(< "${iface}"/statistics/tx_bytes)
snore 1
RX2=$(< "${iface}"/statistics/rx_bytes)
TX2=$(< "${iface}"/statistics/tx_bytes)
awk -v rx1="${RX1}" -v rx2="${RX2}" -v tx1="${TX1}" -v tx2="${TX2}" -v speed="${SPEED}" 'BEGIN {
speed_bytes = int(speed * 1000000/8);
rx_diff = rx2 - rx1;
tx_diff = tx2 - tx1;
rx_perc = rx_diff*100/speed_bytes;
tx_perc = tx_diff*100/speed_bytes;
max = rx_perc;
if ( tx_perc > rx_perc) max = tx_perc;
printf "%.0f",max;
}' # ' end of awk
} # end of function
CPU_UTIL () {
# http://man7.org/linux/man-pages/man5/proc.5.html ; /proc/stat
read -a CPU_ARR_BEGIN < /proc/stat
snore 1
read -a CPU_ARR_END < /proc/stat
awk -v ncpu="${NCPU}" -v CPU_BEGIN_USR="${CPU_ARR_BEGIN[1]}" -v CPU_BEGIN_SYS="${CPU_ARR_BEGIN[3]}" -v CPU_END_USR="${CPU_ARR_END[1]}" -v CPU_END_SYS="${CPU_ARR_END[3]}" 'BEGIN {
printf "%.0f", (CPU_END_USR + CPU_END_SYS - CPU_BEGIN_USR - CPU_BEGIN_SYS)/ncpu ;
}' # ' end of awk
}
while(true); do # keep infinte loop
LOAD5=$(awk -v ncpu="${NCPU}" '{ LOAD_PERC = $2*100/ncpu; printf "%.0f",LOAD_PERC; }' /proc/loadavg) #'
[[ "${LOAD5}" -gt "100" ]] && LOAD5="100"
MEM=$(awk '/MemTotal/{ MEM_TOT=$(NF-1) } /MemAvailable/ { MEM_AVAIL=$(NF-1) } END{ MEM_PERC = (MEM_TOT - MEM_AVAIL)*100/MEM_TOT; printf "%.0f",MEM_PERC; }' /proc/meminfo) #'
# legacy, let's default to 0
PGIO=0
IFACE_DIR="/sys/class/net"
LIST_OF_ETH=""
for iface in ${IFACE_DIR}/*; do # create a list of valid,physical and UP network interfaces
[[ $(readlink -f "${iface}") =~ virtual ]] && continue
OPERSTATE=$(< "${iface}"/operstate)
[[ "$OPERSTATE" != "up" ]] && continue
[[ -z "${LIST_OF_ETH}" ]] && LIST_OF_ETH="${iface}" || LIST_OF_ETH="${LIST_OF_ETH} ${iface}"
done
exec {cpu_util}< <( CPU_UTIL )
NET_LOAD=0
LIST_OF_NET_FD=""
for iface in ${LIST_OF_ETH}; do
exec {iface_load}< <( IFACE_LOAD "${iface}" )
[[ -z "${LIST_OF_NET_FD}" ]] && LIST_OF_NET_FD="${iface_load}" || LIST_OF_NET_FD="${LIST_OF_NET_FD} ${iface_load}"
done
CPU=$(< /dev/fd/${cpu_util})
eval "exec ${cpu_util}<&-"
for NET_FD in ${LIST_OF_NET_FD}; do # select from all network interfaces the one with the biggest load
THIS_NET_LOAD=$(< /dev/fd/${NET_FD})
[[ "${THIS_NET_LOAD}" -gt "${NET_LOAD}" ]] && NET_LOAD=${THIS_NET_LOAD}
eval "exec ${NET_FD}<&-"
done
echo -ne "${LOAD5} ${CPU} ${MEM} ${PGIO} ${NET_LOAD}\n"
[[ "${INTERVAL}" -eq "0" ]] && break || snore ${INTERVAL}
done # end of while loop
|