[CentOS] Network bandwidth tools. (long)

Sun Jan 16 19:16:00 UTC 2011
cpolish at surewest.net <cpolish at surewest.net>

Barry Brimer wrote:
> > I am wondering what tools are available
> > in CentOS 5.5 that would allow me to measure incoming and
> > outgoing network speeds? My new website seems to be getting a
> > lot more traffic that I had anticipated off the bat and I would
> > like to measure resource usage to ensure it is keeping up.

> Take a look at ntop .. there are packages available from rpmforge.

+1 ntop

At the risk of pissing off the list for such a long
post, here are 2 useful shell-scripts for monitoring Linux
system bandwidth. Although they were developed on another
distro I believe (untested) they will work fine with CentOS.

The first script gets installed as a cronjob, the second is run
when you want a histogram of your bandwidth. As commented in the
script, changing 1 line in the second script gives you TX bandwidth
instead of RX. Probably it should be an argument to the script.

logifx:
----%< cut here %<-----------------------------------------------------------
#!/bin/bash
#	From: William Hunt <wjh at prv8.net>
#	Newsgroups: alt.os.linux.slackware
#	Subject: Fun with Slackware: bandwidth monitor
#	Date: Wed, 23 Jan 2008 02:04:05 -0800
#	A script to periodically calculate the total number of bytes
#	sent and received on the given interface;
#	useful for running under cron, for example.
#	raw data is read from ifconfig(1); the script calculates its
#	output from the current reading and from data stored in a state
#	file by the previous run; the current values are then stored in
#	the state file for the next run, overwriting the previous state.
#	if the state file does not exist then no output is generated, but
#	the new STATEF file is still initialized with current data.
#--------------------------------------------------------------
#	this is a useful escape in case of trouble:
#--------------------------------------------------------------
function PANIC () { echo PANIC: $* ; exit ; }
#--------------------------------------------------------------
#	syntax: logifx <interface>
#--------------------------------------------------------------
[ "$1" == "" ] && PANIC interface required.
IF=$1
#--------------------------------------------------------------
#	FILES & DIRECTORIES:
#--------------------------------------------------------------
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
STATED=/var/run/logifx
[ -d "${STATED}" ] || mkdir -p ${STATED} || PANIC bad ${STATED} ?
STATEF=${STATED}/ifxlog-${IF}.dat
OUTD=/var/log
OUTF=${OUTD}/ifx_${IF}
#--------------------------------------------------------------
#	read ifconfig and return RX and TX values:
#--------------------------------------------------------------
function readif() {
 	ifconfig ${IF} | while read LINE ; do
 		DATA=($(echo ${LINE} | grep 'RX bytes:'))
 		[ $? = 0 ] && echo ${DATA[1]/bytes:} ${DATA[5]/bytes:}
 	done
    exit 0
 	}
#--------------------------------------------------------------
#	read the clock:
#--------------------------------------------------------------
STAMP=$( date '+%Y%m%d%H%M' )		# timestamp for logfile line
SEC=$( date '+%s' )			# time used for calculations
#--------------------------------------------------------------
#	read the data - note how an array is used to receive
#	two return values from the function call
#--------------------------------------------------------------
CURRENT=($( readif )) || PANIC reading ifconfig
CRX=${CURRENT[0]}
CTX=${CURRENT[1]}
#--------------------------------------------------------------
#	if state file exists, read prior values and calculate output.
#	negative results indicate a stale state file, so reset it.
#	(not absolutely correct, but best guess and close enough);
#	then append the output to the log file:
#--------------------------------------------------------------
if [ -e ${STATEF} ] ; then
 	read PSEC PRX PTX < ${STATEF}
 	SPAN=$(( ${SEC} - ${PSEC} ))
 	[ $SPAN -gt 0 ] || PANIC WTF? SPAN=${SPAN}
 	RX=$(( ${CRX} - ${PRX} ))
 	TX=$(( ${CTX} - ${PTX} ))
 	[ $RX -lt 0 ] && RX=${CRX}
 	[ $TX -lt 0 ] && TX=${CTX}
 	echo ${STAMP} ${SPAN} ${RX} ${TX} >> ${OUTF} || PANIC ${OUTF}
fi
#--------------------------------------------------------------
#	update state file (overwrite)
#--------------------------------------------------------------
echo ${SEC} ${CRX} ${CTX} > ${STATEF} || PANIC updating ${STATEF}
#--------------------------------------------------------------
# the end.

#	Okay? Okay!   With that in /root/cron/logifx, now, the next step is
#	to stuff it into cron, using crontab -l of course.
#	
#	* * * * * /root/cron/logifx eth0 
#	* * * * * /root/cron/logifx eth1 
#	* * * * * /root/cron/logifx eth2
#	
#	Note that any errors running the script are written to stdout,
#	which cron will mail to the owner (root).  So check for that.
#	
#	Note that the output record is formatted:
#	  1: timestamp YYYYMMDDHHMM
#	  2: interval, in seconds
#	  3: total bytes received during interval preceeding timestamp;
#	  4: total bytes sent during interval preceding timestamp;
----%< cut here %<-----------------------------------------------------------

view_TX:
----%< cut here %<-----------------------------------------------------------
#!/bin/awk -f
#	Okay? Okay!   With that in /root/cron/logifx, now, the next step is
#	to stuff it into cron, using crontab -l of course.
#	
#	* * * * * /root/cron/logifx eth0 
#	* * * * * /root/cron/logifx eth1 
#	* * * * * /root/cron/logifx eth2
#	
#	Note that any errors running the script are written to stdout,
#	which cron will mail to the owner (root).  So check for that.
#	
#	Note that the output record is formatted:
#	  1: timestamp YYYYMMDDHHMM
#	  2: interval, in seconds
#	  3: total bytes received during interval preceeding timestamp;
#	  4: total bytes sent during interval preceding timestamp;

#	Okay? Okay!  Now comes the fun part - analyzing the data.  One
#	could simply use a pager (ex: less) to view the accumulated
#	readings, but a graphical interpretation makes it so much easier
#	to visualize the data and observe patterns.  Since I work mainly
#	at text consoles, I use a histogram  for this.
#	
function histo( X ) {
 	B=""
 	N=X^0.5				# NOTE scaling ...
 	for (a=0;a<N;a++) {B=B"*";}
 	return B
 	}
{
 	Data = ($3)
 	Size = Data / 1024		# kilobytes
 	Rate = Data / 128 / ($2)	# kilobits per second
 	Graph = histo( Rate )
 	mask = "%s %5.0f KB %8.3f Kb/s %s\n"
 	printf( mask, $1, Size, Rate, Graph )
 	}
# the end.


# The second script i call view_TX and it is exactly the same
# as view_RX except for one line:
#  	Data = ($3)
# is replaced with:
#  	Data = ($4)
# 
# I know i should rewrite these into one script, in such a way
# that RX vs TX would be indicated by the script name, or an
# argument, or whatever.  But for my purpose this is good enough,
# and maybe some day I'll rewrite it (again :*)
# 
# These scripts get called something like:
# 
#      view_TX /var/log/ifx_eth0 | less
# 
# and generate a report something like this:
# 
# [...]
# 200801222211   852 KB  113.586 Kb/s ***********
# 200801222212  4445 KB  592.651 Kb/s *************************
# 200801222213    10 KB    1.337 Kb/s **
# 200801222214   505 KB   66.245 Kb/s *********
# 200801222215  1232 KB  164.312 Kb/s *************
# 200801222216   403 KB   54.646 Kb/s ********
# 200801222217  3379 KB  450.586 Kb/s **********************
# 200801222218   172 KB   22.913 Kb/s *****
# 200801222219    19 KB    2.580 Kb/s **
# 200801222220   705 KB   94.007 Kb/s **********
# [...]
# 

# Okay? Okay!

# The same ifx_eth0 file can also be used to calculate totals
# for longer intervals, like monthly, for example.  I rotate
# my logs into a file tree like /var/log/YYYY/MM/DD/, so:
# 
# cat /var/log/2007/12/*/ifx_eth0 | while read A B C D ; do
#  	TOTRX=$(( $TOTRX + $C ))
# done
# echo "TOTAL RX for December, $(( $TOTRX / 1024 / 1024 )) MB."
# 
# Okay? Okay!
# 
# Have fun,
# 
# -- 
# William Hunt, Portland Oregon USA
----%< cut here %<-----------------------------------------------------------

-- 
Charles Polisher