Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Jul 2002 17:01:53 -0600 (CST)
From:      Ryan Thompson <ryan@sasknow.com>
To:        Brad Davis <striker_d@hotmail.com>
Cc:        freebsd-net@FreeBSD.ORG
Subject:   Re: monthly traffic stats
Message-ID:  <20020728165343.R3433-200000@ren.sasknow.com>
In-Reply-To: <F138xIuITlK2gMyXh7t00016fe6@hotmail.com>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
Brad Davis wrote to freebsd-net@FreeBSD.ORG:

> > take a look at mrtg in ports (/usr/ports/net/mrtg/), or if you
> > don't want to deal with mrtg you can run the output of netstat
> > -inb through some perl and into rrdtool.....
> >
> >		--eli
>
> I already use MRTG to monitor it.. but I'm looking for a more
> absolute value.

mrtg's log format is very easy to script against. You probably have
many months of historical data already! :-)

I've attached a Perl script that I found somewhere a few years back
that has been lurking in ~/bin/ ever since, with some minor tweaks. I
can't remember where, and there is no author information in the file.

You could probably do a Google search for some of the strings in the
file to find the real thing.

I've modified versions of this to do automated traffic billing,
network monitoring (high/low bandwidth thresholds), etc...

- Ryan

-- 
  Ryan Thompson <ryan@sasknow.com>

  SaskNow Technologies - http://www.sasknow.com
  901 1st Avenue North - Saskatoon, SK - S7K 1Y4

        Tel: 306-664-3600   Fax: 306-244-7037   Saskatoon
  Toll-Free: 877-727-5669     (877-SASKNOW)     North America

[-- Attachment #2 --]
#!/usr/bin/perl5
 
#-----------------------------------------------------------------------
# calculate_traffic.cgi
#
# $Id: calculate_traffic.cgi,v 1.7 1999/04/02 07:57:08 mrtg Exp $
#
# This cgi takes a log file name, a start date, and an
# end date as the three mandatory values passed to the script.
# It returns the total Octets In and Out from that interface
# between those two dates, inclusive.  The start date and 
# end date MUST be specified as: MM-DD-YYYY-HH:MM, and the
# start date MUST be earlier than the end date.
#-----------------------------------------------------------------------
 
#-----------------------------------------------------------------------
# GLOBALS
 
use strict;
use Time::Local;

require 5.004;
 
$| = 1 ;
 
my($DEBUG)     = 0;

my($topdir)    = "/home/httpd/html/traffic";

my($datestr)   = "";
my($start_date)= "";
my($end_date)  = "";
my($logfile)   = "";

#-----------------------------------------------------------------------
 
#-----------------------------------------------------------------------
sub errorexit {
   print ("$0:  error:  @_.\n");
   exit(21);
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub scale 
{
   my ($bits) = @_;
   ($bits =~ /^[\d.]+$/) or return "ERROR";
   my ($units) = "bps";
   foreach my $unit ("Kbps", "Mbps", "Gbps", "Tbps") {
      last unless ($bits / 1024 > 1);
      $bits = $bits / 1024;
      $units = $unit;
   }
   return sprintf "%0.2f %s", $bits, $units;
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub get_args {
   my($logfile,$start,$end,$start_str,$end_str);

   unless( $#ARGV == 2 ) {
      my($name) = `basename $0` ;
      $name =~ s/\s+//g ;
      print STDERR "usage: $name <logfile> <start_date> <end_date>\n" ;
      print STDERR "   where <start_date> and <end_date> are in the\n";
      print STDERR "   format: MM-DD-YYYY-HH:MM\n";
      #exit(1) ;
   }

   if ($#ARGV < 1) {
   	$logfile = "/www/mrtg/switch.log";
   	$start_str = `date +%m-01-%Y-00:00`;
   	$end_str = `date -v-1M +%m-%d-%Y-%H:%M`;
   } else {
   	$logfile = $ARGV[0];
   	$start_str = $ARGV[1];
   	$end_str = $ARGV[2];
   }

   
   if (! -r $logfile) {
      &errorexit("Couldn't read $logfile: $!");
   }
   if (($start_str eq "") || ($end_str eq "")) {
      &errorexit("Sorry, null dates NOT allowed!");
   }
   $start_str =~ m/^(\d\d)\-(\d\d)\-(\d\d\d\d)\-(\d\d)\:(\d\d)$/ or
      &errorexit("You specified an invalid start date: $start_str");
   $start = timelocal(0,$5,$4,$2,$1-1,$3);
   $end_str =~ m/^(\d\d)\-(\d\d)\-(\d\d\d\d)\-(\d\d)\:(\d\d)$/ or
      &errorexit("You specified an invalid end date: $end_str");
   $end = timelocal(0,$5,$4,$2,$1-1,$3);
   if ($start > $end) {
      # just swap them, don't complain
      my($tmp_date) = $start;
      $start = $end;
      $end = $tmp_date;
   }
   return($logfile,$start,$end);
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub print_params {
   my($log,$start,$end) = @_ if @_;
   my($start_str, $end_str);
   $start_str = scalar localtime($start);
   $end_str = scalar localtime($end);

   #print STDOUT "Total stats from $start_str till $end_str";
   #print STDOUT "Logfile: $log\n";
   #print STDOUT "Start time: $start_str\n";
   #print STDOUT "End time: $end_str\n";
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub get_totals {
   my($logfile,$start,$end) = @_ if @_;
   my($itot,$otot,$interval) = (0,0,0);
   my($aline,$curr_date,$avg_in,$avg_out,$pin,$pout);
   # File is in reverse, from end to start, so we count down...
   my($prev_date) = time;
   open(LOG,"$logfile") or &errorexit("Couldn't open $logfile: $!");
   while (<LOG>) {
      $aline = $_;
      chomp($aline);
      ($curr_date,$avg_in,$avg_out,$pin,$pout) = split(' ',$aline);
      $interval = $prev_date - $curr_date; 
      $prev_date = $curr_date;
      next if ($curr_date > $end);
      next if ($curr_date < $start);
      $itot = $itot + ($avg_in * $interval);
      $otot = $otot + ($avg_out * $interval);
      print STDOUT "IN: $avg_in * $interval = $itot\tOUT: $avg_out * $interval = $otot\n" if ($DEBUG);
   }
   return($itot,$otot);
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
sub print_totals {
   my($in,$out,$interval) = @_ if @_;
   my($inm,$outm) = @_ if @_;
	$inm = $in/1024/1024 ; 
	$outm = $out/1024/1024 ;
	
   print "-----------------------------------------------------------------\n";
   print "Total Traffic\n";
   print "-----------------------------------------------------------------\n";
   print sprintf "Total Megabytes in: %0.2f %s MB\n", $inm ;
   print sprintf "Total Megabytes out: %0.2f %s MB \n", $outm ;
   print "-----------------------------------------------------------------\n";
   print "Average Traffic (24-hour)\n" ;
   print "-----------------------------------------------------------------\n";
	my($a_in) = &scale($in*8/$interval);
	my($a_out) = &scale($out*8/$interval);
   print "Average traffic in: $a_in\n";
   print "Average traffic out: $a_out \n"; 
   print "-----------------------------------------------------------------\n";
   
}
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# MAIN

($logfile,$start_date,$end_date) = &get_args;
&print_params($logfile,$start_date,$end_date);

my($interval) = $end_date - $start_date;

my($in_tot,$out_tot) = &get_totals($logfile,$start_date,$end_date);
&print_totals($in_tot,$out_tot,$interval);
#-----------------------------------------------------------------------
#
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020728165343.R3433-200000>