Making GeekTool a little easier on the system

technology.pngI love me some system monitors. I like making my system monitors lightweight. The two are not always compatible.

I’ve used Samurize on Winboxen, use Conky on linux, and got introduced to GeekTool on OS X. Geektool uses a lot of similar output to Conky, so it wasn’t hard to get what I wanted pretty quickly (internal/external IP, uptime, load, free ram, and CPU stats).

What I noticed, though, were the example scripts. I threw some in to get the hang of the thing, and saw that something as trivial as CPU load was using a good 5% of my CPU power. When I looked at the code, I saw why:

top -l 2 |awk ‘/CPU usage/ && NR > 5 {print $1, “:”, $3, $4}’
top -l 2 |awk ‘/CPU usage/ && NR > 5 {print $1, “:”, $5, $6}’
top -l 2 |awk ‘/CPU usage/ && NR > 5 {print $1, “:”, $7, $8}’

top is a great little command, but calling it three times (actually six, the second iteration is due to a quirk) is enough to put a bit of load on the system. This was only one example – another script pinged an external IP, ran six top commands, did some math, and so on… every second.

Obviously, lowering the refresh rate helps. I split two scripts up – one with a refresh rate of 300 sec (the uptime, load, and IP addresses) and the other with a refresh rate of 3 sec (system monitoring). That’s not the cool bit – because OS X is overtop of BSD, I could use bash scripting to make it work better. Call the high-load process once, store the output as a variable, and re-parse the variable for your output.

So here’s the code for you; I’ve simply commented it so you can cut and paste as you like.

#system statistics
#we run it once here to get physical memory free
top -n1 -l 1| awk ‘/PhysMem/ {print “ram free : ” $10 ” “}’

#get data from top – we just want header info
#run it twice so we get real CPU percentages
topdata=`top -n1 -l 2`;
echo “$topdata”|awk ‘/CPU usage/ && NR > 5 {print “cpu user : ” $3}’
echo “$topdata”|awk ‘/CPU usage/ && NR > 5 {print “cpu sys : ” $5}’
echo “$topdata”|awk ‘/CPU usage/ && NR > 5 {print “cpu idle : ” $7}’
#end

#ethernet
myen0=`ifconfig en0 | grep “inet ” | grep -v 127.0.0.1 | awk ‘{print $2}’`

if [ “$myen0” != “” ]
then
echo “ethernet : $myen0”
else
echo “ethernet : INACTIVE”
fi

myen1=`ifconfig en1 | grep “inet ” | grep -v 127.0.0.1 | awk ‘{print $2}’`

if [ “myen1” != “” ]
then
echo “airport : $myen1”
else
echo “airport : INACTIVE”
fi

inetip=$(curl -s https://checkip.dyndns.org/ | sed ‘s/[a-zA-Z/ :]//g’)
if [ “$inetip” = “” ]
then
inetip=”offline”
fi
echo “ext ip : $inetip”

# Change this to en1 for airport instead of ethernet
INTF=en0
#end

#uptime info
updata=`uptime`
echo “$updata” | awk ‘{print “uptime : ” $3 ” ” $4 ” “$5″ ” }’
echo “$updata” | awk ‘{print “load : ” $8 ” “$9” “$10” “$11” “}’
#end