File: cms_monPerf

package info (click to toggle)
xrootd 5.9.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 25,956 kB
  • sloc: cpp: 244,425; sh: 2,691; python: 1,980; ansic: 1,027; perl: 814; makefile: 272
file content (96 lines) | stat: -rwxr-xr-x 3,798 bytes parent folder | download
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