Use bash to compare remote cpu load and print lowest value of array

Written by - 0 comments

Published on - Listed in Linux Shell Coding

In some cases it might be useful to compare remote load values of different servers and use these values to determine the server with the lowest load. Practical examples would be a provisioning server or a load balancing server.

The current load averages (1min, 5min, 15min) can be displayed by using /proc/loadavg:

cat /proc/loadavg
0.18 0.24 0.20 1/563 28186

For balancing or provisioning purposes, the value to take a look at is the third value which is the load average during the last 15 minutes.

cat /proc/loadavg | awk '{print $3}'

This of course also possible by using a remote SSH command (don't forget to escape the Dollar sign):

ssh root@remoteserver "cat /proc/loadavg | awk '{print \$3}'"

To get the current load average on a bunch of server and to show the server with the lowest cpu load (in the last 15 minutes), the following script can be launched:

for server in server01 server02 server03 server04; do
  case $server in
    server01) load[1]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'");;
    server02) load[2]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'");;
    server03) load[3]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'");;
    server04) load[4]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'");;

echo "${load[*]}" | tr ' ' '\n' | awk 'NR==1{min=$0}NR>1 && $1
Server #:3 Load: 0.07

This can of course easily be verified

echo ${load[@]}
0.22 0.36 0.07 0.20 0.30

As a short explanation what this scriopt is doing:

For each server, a remote ssh command is executed to get the current 15min load average value. This value is saved into an array "load" and the array index number "1" (because I start with server #1, the array index should have the same number as the servername). After the for loop, the full array "load" is returned. Each array value is compared with the previous array value. If the current array value is smaller than the previous one, then the variable "min" is set with the value value of the new lowest value. Besides that, the variable "pos" is set, which defines the position of the current value (NR).
At the end, the information is printed to stdout with additional information ("Server #" and "Load:") as strings.

This of course also works without the case loop (see below) but the case loop may be helpful if additional information wants to be gathered at the same time.

i=1; for server in server01 server02 server03 server04 server05; do
myload[$i]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'")
let i++

echo "${myload[*]}" | tr ' ' '\n' | awk 'NR==1{min=$0}NR>1 && $1
Server #:3 Load: 0.06

Source for this very neat awk comparison:

Update September 29th 2014: I had an issue today with exactly this method, when every variable in the array had the same value. See "awk issue when trying to sort variables with same values" for a solution.

Add a comment

Show form to leave a comment

Comments (newest first)

No comments yet.