Author Topic: Wrapper script for vnstat to measure bandwidth usage during preceding 24hrs  (Read 303 times)

Offline coonhunter

  • Full Member
  • ***
  • Posts: 203
BASH Script:displays total download usage in specified time

Background:
This bash script displays the total downloaded and uploaded quantity within the preceding 24 hours for the time interval you specify.This is helpful if your ISP has a traffic management policy with caps.You specify the time interval for which you want the usage data (via the start_hour and end_hour parameters:see below).

Ofcourse you can do this by just running the command:vnstat -h.This will display something like:

eth0                                                                     16:55
  ^           r                                                                
  |           r                                                                
  |           r                                                                
  |           r     r                                                          
  |           r     r                                                          
  |           r     r                                                          
  |        r  r     r                                                          
  |        r  r     r                                                          
  |        r  r     r                                                          
  |        r  rt r  r  r  r                                                    
 -+--------------------------------------------------------------------------->
  |  17 18 19 20 21 22 23 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16    
                                                                                
 h  rx (KiB)   tx (KiB)      h  rx (KiB)   tx (KiB)      h  rx (KiB)   tx (KiB)
17          0          0    01          0          0    09          0          0
18          0          0    02          0          0    10          0          0
19      13862       1693    03          0          0    11          0          0
20      31498       3330    04          0          0    12          0          0
21       5597        927    05          0          0    13          0          0
22      23857       1100    06          0          0    14          0          0
23       5951       1173    07          0          0    15          0          0
00       4425        447    08  

Now you can add up all the Tx and Rx values within the time interval that you're interested in to get your bandwidth usage.However it would be much more convenient if the user just specifies the time interval and the program sums up all the values for you.So that's what i set out to do.

This script is essentially a wrapper script for vnstat.So first you need to install the vnstat package from the repos.vnstat displays bandwidth usage on the machine that its installed on.By default it updates every 5 minutes.That means that the script cannot display bandwidth usage right upto the current time.For example say that the current time on your pc is 16:38 hrs;the script will display bandwidth usage only upto 16:35 hrs (i.e:the nearest fifth minute).It may be possible to make vnstat update more frequently but i haven't checked its man pages as i'm quite happy with its default behaviour.Furthermore more frequent updating means more CPU cycles.This script also cannot calculate the total bandwidth usage of ALL the computers on your network unless you run it on all those machines and sum up all the values.As i'm the only main downloader in the family i'm not particularly fussed by this limitation.

Usage:

whatever_script_name <start_hour> <end_hour>

Say you want to see how much you have downloaded and uploaded today from 10am to 7pm.start_hour is 10 and end_hour is 19 (ie:19:00hrs in 24 hr notation but you omit the minute section as it only calculates from hour to hour).So you enter:
whatever_script_name 10 19

If you omit the second parameter,ie:the end_hour.It will display the total downloaded and uploaded usage from the start_hour to the current time (to the nearest 5th minute).For example suppose the current time on your pc is 22.47hrs and you want to know how much you have downloaded and uploaded from 1pm today right until the present moment (to the nearest 5th minute:ie:22:45hrs),you will enter:

whatever_script_name 13

In this case start_hour is 13 as this corresponds to 1pm in the 24hour notation.You omit the end_hour (ie:the second parameter)

The start_hour parameter may be greater in value than the end_hour.For example in the situation where you want to know how much you have downloaded from 18:00hrs the previous evening till 7am today,you will enter:

whatever_script_name 18 7

If you don't input any parameters and just run:

whatever_script_name

Then the script will by default show the usage over the preceding 24 hours(to the nearest 5th minute)

Note that the script outputs several echo messages preceded by "+++".These were put in for my benefit to see if the script was running as planned and can be ignored.You can comment out these echo statements in the script if you don't wish to see them.

Remember to set the ETH_INF variable in the script!!:
In the script notice the line ETH_INF=<substitute your network interface here>
You need to assign your network interface to the variable ETH_INF.On my machine this corresponds to eth0.So:
ETH_INF=eth0


Code: [Select]
#!/bin/bash

ETH_INF=<substitute your network interface here>
DOWN=0
UP=0
j=0
TIME=`date | awk '{print $4}' | cut -d: -f1`
TIME_1=$1
TIME_2=$2



set_time1(){

if [ -n "$TIME_1" ];then #If TIME_1 is not an empty string:

if [[ $TIME_1 =~ ^[0-9]+$ ]];then #if TIME_1 is an integer:

[ $TIME_1 -eq 24 ] && TIME_1=0 || :
       if [ $TIME_1 -lt 00 ] || [ $TIME_1 -gt 24 ];then
         echo "+++Don't be ridiculous.Enter a suitable start_hour value.I will exit now."
         exit 1
       else
echo "+++Inputted TIME_1 value is:" $TIME_1
       fi

else #if TIME_1 is not an integer then exit
echo "+++Don't be ridiculous.Enter a numeric start_hour value.I will exit now."
exit 1
fi
      
      
    else #if $TIME_1 is an empty string:

TIME_1=`expr $TIME + 1`
[ $TIME_1 -eq 24 ] && TIME_1=0 || :
echo "+++No parameters entered.TIME_1 set to (Current_Time+1) on previous day":$TIME_1

    fi
}

set_time2(){

if [ -n "$TIME_2" ];then #if TIME_2 is not an empty string:

       if [[ $TIME_2 =~ ^[0-9]+$ ]];then #if TIME_2 is an integer:

[ $TIME_2 -eq 24 ] && TIME_2=0 || :
if [ $TIME_2 -gt $TIME ];then
         echo "+++Don't be ridiculous.Enter a suitable end_hour value.I will exit now."
         exit 1
       else
TIME_2=`expr $TIME_2 - 1`
echo "+++Inputted TIME_2 decremented by one to:" $TIME_2
       fi

else #if TIME_2 is not an integer then exit

echo "+++Don't be ridiculous.Enter a numeric end_hour value.I will exit now."
exit 1
fi
      
      
else #if TIME_2 is an empty string set TIME_2 to current TIME value
      
 TIME_2=$TIME
          echo "+++No parameters entered.TIME_2 set to Current_Time:"$TIME_2
          
fi
}

set_time1
set_time2

#vnstat -h | tr -d , removes any commas from vnstat's output.Otherwise expr would not be able to do integer arthmetic on the #values
create_array(){
ARRAY=(`vnstat -h | tr -d , | grep -v "$ETH_INF" | grep -v "[h\^|-]" | awk '
($1 >= time_1) && ($1 <= time_2) {printf "%s\t%-14s\t%-14s\n",$1,$2,$3;}
($4 >= time_1) && ($4 <= time_2) {printf "%s\t%-14s\t%-14s\n",$4,$5,$6;}
($7 >= time_1) && ($7 <= time_2) {printf "%s\t%-14s\t%-14s\n",$7,$8,$9;}' time_1="$TIME_1" time_2="$TIME_2" | sort`)
}

create_array1(){
ARRAY1=(`vnstat -h | tr -d , | grep -v "$ETH_INF" | grep -v "[h\^|-]" | awk '
($1 >= time_1) {printf "%s\t%-14s\t%-14s\n",$1,$2,$3;}
($4 >= time_1) {printf "%s\t%-14s\t%-14s\n",$4,$5,$6;}
($7 >= time_1) {printf "%s\t%-14s\t%-14s\n",$7,$8,$9;}' time_1="$TIME_1" | sort`)
}

create_array2(){
ARRAY2=(`vnstat -h | tr -d , | grep -v "$ETH_INF" | grep -v "[h\^|-]" | awk '
($1 <= time_2) {printf "%s\t%-14s\t%-14s\n",$1,$2,$3;}
($4 <= time_2) {printf "%s\t%-14s\t%-14s\n",$4,$5,$6;}
($7 <= time_2) {printf "%s\t%-14s\t%-14s\n",$7,$8,$9;}' time_2="$TIME_2" | sort`)
}

create_combine_array(){
create_array1
create_array2
COMBINE=( ${ARRAY1[*]} ${ARRAY2[*]} )
}



display_array(){

ARRAY_LENGTH=${#ARRAY[@]}
echo +++Value of ARRAY_LENGTH:$ARRAY_LENGTH
printf "%s\t%-16s\t%-14s\n" "hour:" "downloaded(KiB):" "uploaded(KiB):"

while [ $j -lt $ARRAY_LENGTH ]
do
      
      #echo array_index["$j"]:  "${ARRAY[j]}" :Downloaded:"${ARRAY[j+1]}" Uploaded:"${ARRAY[j+2]}"  
         printf "%s\t%-16s\t%-14s\n" ${ARRAY[j]} ${ARRAY[j+1]} ${ARRAY[j+2]}
         DOWN=`expr $DOWN + ${ARRAY[j+1]}`
         UP=`expr $UP + ${ARRAY[j+2]}`
         j=`expr $j + 3`

done

echo
printf "%-21s\t%-14s\n" "Total Downloaded(KiB):" $DOWN
printf "%-21s\t%-14s\n" "Total Uploaded(KiB):" $UP
}


display_combine_array(){

COMBINE_ARRAY_LENGTH=${#COMBINE[@]}
echo +++Value of COMBINE_ARRAY_LENGTH:$COMBINE_ARRAY_LENGTH
printf "%s\t%-16s\t%-14s\n" "hour:" "downloaded(KiB):" "uploaded(KiB):"

while [ $j -lt $COMBINE_ARRAY_LENGTH ]
do
      
      #echo array_index["$j"]:  "${COMBINE[j]}" :Downloaded:"${COMBINE[j+1]}" Uploaded:"${COMBINE[j+2]}"  
         printf "%s\t%-16s\t%-14s\n" ${COMBINE[j]} ${COMBINE[j+1]} ${COMBINE[j+2]}
         DOWN=`expr $DOWN + ${COMBINE[j+1]}`
         UP=`expr $UP + ${COMBINE[j+2]}`
         j=`expr $j + 3`

done

echo
printf "%-21s\t%-14s\n" "Total Downloaded(KiB):" $DOWN
printf "%-21s\t%-14s\n" "Total Uploaded(KiB):" $UP
}


if [ $TIME_1 -lt $TIME_2 ];then
   echo "+++TIME_1 is less than TIME_2"
   create_array
   display_array
else
   echo "+++TIME_1 is greater than TIME_2"
   create_combine_array
   display_combine_array
fi



« Last Edit: August 10, 2012, 05:35:03 PM by coonhunter »