#!/usr/bin/perl # # Realtime Bandwidth checker "bw.cgi" # # This script calculates the total bandwidth from 00:00 PST/PDT, # as well as total hits, and some estimates. # # It writes "bwpos.txt" to preserve the last count and the file position # so that next time it will start counting from there, to be efficient. # # It's a light weight tool, and can be used every now and then, # or placed in a crontab for hourly check # or even a bit more often if desired. # # Optionally, it can output only the total bandwidth, so that you can # use this in a (shell) script to alert or take some actions # if the bandwidth usage is getting closer to the limits. # # WARNING: Please place this in a protected directory # # Usage: bw.cgi [-c]|[-q] # or http://yourdomaincom/protected/bw.cgi? # # -c: This option force to check fron the top of the log file # DO NOT use this option unless you think you need to do it. # # -q: When this option is turned on, the program will output # total bandwidth in ascii only. (For using in shell script.) # # These options are recognized in the CGI invocation, as well. # # This script will create "bwpos.txt" in the same directory. # Do not modify/delete that file unless you are removing this script. # # As this script is based on the records of log file, # if the log isn't accurate, the result will follow it, naturally. # Some servers of PowWeb may producing logs containing 20 to 30% less # than it should be for mnay maonths. (as of April/2005) # # # Additional note to "PHP people": # This script and all other normal CGI need permission of 700 (or 500). # CGI script can be placed and used in ANY directory (on PowWeb servers). # # # This script comes with NO GUARANTY what so ever. # It works for me, but maybe not for you, # especially if you are not nice person. # It's not my problem if you experience any problem with it. # # I totally neglected the design aspects of this script, as usuall. # Modify it to add colors and output formats if you like. # # Be happy and don't worry about the bandwidth. # If you really need this tool, maybe it's time for you to look for # another host where you can get more bandwidth, hits, and so on. # $|=1; $verbose = 1 if $ARGV[0] ne '-q'; if( $verbose){ print "Content-type: text/html\n\n" ; print "
";
}
$t=time();
print "Option specified: @ARGV\n" if $verbose and $ARGV[0];
$clean = 1 if grep(/\-c/,@ARGV);
print "'-c' option found. Strting from the top of the log\n" if $clean && $verbose;
$lid = $< - 500;
$fname = "/log/access/".substr($lid,0,1)."/${lid}_access_log";
#print "$fname\n";
$fpos = 'bwpos.txt';
open(FH,$fname) || die "Error: failed to open $fname\n";
read(FH,$line,64);
$line =~s/\n|\r/_/g;
seek(FH,0,0);
if((!$clean) && open(FPOS,$fpos)){
chomp(@pos = );
close(FPOS);
if( $line eq $pos[3]){ # Check if we are dealing with the same log
if( seek(FH,$pos[0],0)){ # if so, seek to the last position.
print "Setting the starting file position to: $pos[0], and counter to: $pos[1]\n" if $verbose;
$c = $pos[1];
$h = $pos[2];
$tt = $pos[4];
}
}else{ # if not, start from the top.
print "$line\n$pos[3]\n-----\n" if $verbose;
}
}else{
$c = 0;
}
$l=0;
print "Counting ..." if $verbose;
while(){ # With 'g' option it's quicker, somehow.
$cc += $1 if /\" [2-5][0-9][0-9] ([0-9]+)/og;
$l++;
}
$c += $cc;
print "\nFinished !\n\n" if $verbose;
#print "cc=$cc, l=$l\n"; # Debug print
#print `ps uww`;
seek(FH,0,2);
$endpos = tell(FH);
close(FH);
$h += $l;
if(open(FPOSW,">$fpos")){
print "writing following data to bwpos.txt:\n\t$endpos <== The end position of log file\n\t$c <== The total count at that point\n\t$h <== The Total hit count of the day\n\t$line <== The first 64 bytes of log (for identification)\n\n" if $verbose;
print FPOSW "$endpos\n$c\n$h\n$line\n$t\n";
close(FPOSW);
}else{
print "Error: failed to open $fname for writing 'position file'\n";
}
if( $verbose){
#printf("time=%d, t-tt=%d\n", time(), $t-$tt);
($sec,$min,$hour,$mday,$mon,$year,$wday, $yday, $isdst) =localtime(time);
$now = localtime(time());
$tn = ($hour*60 + $min)*60 +$sec;
$td = $t - $tt;
$td = $tn if $clean;
print "It's $now (PST/PDT). $tn seconds has passed since the midnight.\n\n";
print "$cc bytes, and $l lines(hits) since last check ($td seconds ago), Total of $h hits, today.\n";
print $c/$h , " bytes/hit average.\n" if $h > 0;
if( $td > 0){
$ctd = $cc/$td;
$htd = $l/$td;
print "\n$ctd bytes/sec, $htd hits/sec (since last check of $td seconds ago)\n";
$hth = $htd*3600;
$ctday = $ctd*360*24/1024/1024;
printf( "Roughly translated into %d Megabytes/day, and %d hits/hour at the current rate (since last check).\n", $ctday,$hth);
print "Note. The estimate above isn't necessarily accurate if the last check was done shortly before.\n";
}
if($tn > 0){
$ctn = $c/$tn;
$htn = $h/$tn;
print "\n$ctn bytes/sec, $htn hits/sec, today (since 00:00 PST/PDT)\n";
$hthn = $htn*3600;
$ctdayn = $ctn*3600*24/1024/1024;
printf( "Roughly translated into %d Megabytes/day, and %d hits/hour at the current rate, today.\n", $ctdayn,$hthn);
}
print "\n'$c' bytes (Total Bandwidth in the logfile: $fname)\n";
if( $c > 4*1024*1024*1024){
print "\nIt's over 4GB, now. I'd start worrying a little.\n";
}elsif( $c < 2*1024*1024*1024){
print "\nYou don't have to worry about the bandwidth limit, yet...\nunless it's pretty early in the day... :)\n" ;
}elsif( $c > 8*1024*1024*1024){
print "\nIt's over 8GB !!! \n";
}else{
print "\nIt's over 2GB ... but under 8GB, now...\n" ;
}
}else{
print $c;
}
1;