Google the SiteQuicksearchCategoriesSyndicate This BlogCreative CommonsBlog Administration |
Sunday, September 19. 2004MRTG Totals Perl Script
I recently got a mail from someone (hi Dennis!) about how the MRTG totals script works on the MRTG site. For those too lazy to look at the totals page, the general idea is that the total transfer statistics for a device - in this case my ADSL router - are displayed all on one page. In this way you can see easily how much data was transferred either by month or by day for any period during which the mrtg_total script has been collating data.
I use a perl script written by a chap called Josef Wendel to collate the stats pages from a daily cron job. The stats can then be displayed using a PHP script, again written by the same bloke. I can't find a specific reference to Josef's home site, but I'm sure googling for 'josef wendel perl mrtg' should turn something up (or even just google for 'mrtg_total.pl', the name of the script. Just in case I'll add the scripts in the extended entry here anyway, I'm sure Josef won't mind given I just mentioned his name about half a dozen times here in credit!!! Excellent script thanks for that Josef. EDIT: Yes a quick google for mrtg_total.pl came up with Josef's home page for the mrtg total script. Go google! See over there for more 'authoratative' info. See the extended article for the complete mrtg_total.pl script and associated PHP frontend script. Here is the backend mrtg_total.pl script that collates the stats into output files. This is run once a day via cron, see the script for an example of a suitable crontab.
CODE: #!/usr/bin/perl #----------------------------------------------------------------------- # mrtg_total.pl # # v0.21 31.10.2003 Josef Wendel <josef.wendel@web.de> # - fixed some white space problems in .cfg file # - tested with ActivePerl 5.8.0.806 and # GD (v2.11) # GDGraph (v1.43) # GDTextUtil (v0.86) # GDGraph3d (v0.63) # comming from http://theoryx5.uwinnipeg.ca/ppms # # v0.20 22.05.2003 David Hardy <David.Hardy@panaseer.com.au> # - fixed a long lasting prob with EOL char in Windows # # v0.19 21.11.2002 Josef Wendel <josef.wendel@web.de> # - New config switch: # #-#Total-Output: DWM # D: Outputs the daily totals for one month # W: Outputs the weekly totals for one year # M: Outputs the monthly totals for one year # if omitted: like the older versions (DM) # # v0.18 never released # # v0.17 23.07.2001 Josef Wendel <josef.wendel@web.de> # - New config switch: # #-#Total-Directory: # works similar to "Directory" of mrtg. # # v0.16 11.07.2001 Josef Wendel <josef.wendel@web.de> # - Bugfix: output for all dev in mrtg.cfg with any of # the recognized tags was generated, not only # for dev with #-#Total tag. # Thanx to Viana Gomes <viana.gomes@bnpparibas.com> # # v0.15 22.05.2001 Josef Wendel <josef.wendel@web.de> # - Format of output date customizable ($DATEFORMAT) # # v0.14 18.05.2001 Josef Wendel <josef.wendel@web.de> # - now parses for [_] directives # # v0.13 04.05.2001 Josef Wendel <josef.wendel@web.de> # - 1000nd-seperator ($TSEP) now customizable in # the script # # v0.12 28.04.2001 Josef Wendel <josef.wendel@web.de> # - now takes care of "Includes" in mrtg.config file # - calculates in/out ratio on demand # (#-#Total-Ratio: yes) # - background color changed to light yellow # - image size adjusted # - pays attention for "HtmlDir" and "LogDir" ("ImageDir" is # ignored by intention) # - reads and uses "Directory" and "Extension" # Thanx to Jorge Valdes <jvaldes@sv.cciglobal.net> # - Homepage: http://www.geocities.com/josef_wendel # # v0.11 20.03.2001 Josef Wendel <josef.wendel@web.de> # - better error message, if logfile doesn't exist # # v0.10 01.03.2001 Josef Wendel <josef.wendel@web.de> # - Additional tag added # #-#Total-Unit: <unit> # with <unit> one of KMGTPE Bytes. # The table output will be adjusted # # v0.09 never released # # v0.08 24.01.2001 Josef Wendel <josef.wendel@web.de> # - now we are Windows aware too. Tested with # ActivePerl 623 (http://www.activestate.com/Products/ActivePerl) # installed on a Windows 2000 box. The packages # mentioned below has been installed with PPM. # # v0.07 11.01.2001 Josef Wendel <josef.wendel@web.de> # - minor bug fixing (</table> missed) # thanks to Max Mudde <M.Mudde@fab.hvu.nl> # # v0.06 09.01.2001 Josef Wendel <josef.wendel@web.de> # - minor bug fixing (close statement missed) # thanks to Mark Campbell <mark@uis.co.za> # # v0.05 18.12.2000 Josef Wendel <josef.wendel@web.de> # - debugging improvements # - support for RRDs (http://rrdtool.eu.org/) # # v0.04 13.12.2000 Josef Wendel <josef.wendel@web.de> # - Tested with the following library versions: # GD-1.32 (cpan.org) # GDGraph-1.33 (cpan.org) # GDGraph3d-0.55 (cpan.org) # GDTextUtil-0.80 (cpan.org) # # v0.03 05.06.2000 Josef Wendel <josef.wendel@web.de> # - Don't break, just ignore a nonexistent Logfile # # v0.02 05.04.2000 Josef Wendel <josef.wendel@web.de> # - Table output formated with "thousand-dots" # - year-table with link to month # # v0.01 24.03.2000 Josef Wendel <josef.wendel@web.de> # # Initial version # # Use: mrtg_total.pl <mrtg-config-file> # # Collects and outputs daily and monthly totals # as .html file with embedded .png graphic. # # Based on the initial work of # Seth Mos <Stimpy@multiweb.nl> http://stimpy.multiweb.nl/ # and # Matt Petach <mattp@Internex.NET> # # Use pseudo-commment # #-#Total[<device>]: <header-for-html-file> # to activate the generation of totals for this device # in your mrtg config file # # Should be called daily out of the crontab, i.e. # 5 1 * * * /usr/local/bin/mrtg_total.pl /usr/local/mrtg/mrtg.cfg # # mrtg by # Tobi Oetiker <oetiker@ee.ethz.ch> # can be found at # http://mrtg.eu.org/ # #----------------------------------------------------------------------- #----------------------------------------------------------------------- # USER CUSTOMIZABLE GLOBALS my ($DEBUG)= (0); # 1 to get debugging printouts to STDERR, # 0 otherwise my ($TSEP)= (','); # set to . (dot) for German... locale # to , (comma) for Anglo... locale # to whatever you want (1 char) my ($DATEFORMAT)= (0); # set to 0 for German date format (DD-MM-YYYY) # set to 1 for English date format (MM/DD/YYYY) # END OF USER CUSTOMIZABLE GLOBALS #----------------------------------------------------------------------- use strict qw(vars refs); use Time::Local; use File::Basename; use FileHandle; use GD::Graph::bars; use GD::Graph::bars3d; require 5.004; $| = 1 ; # Some colors (html-coded) my ($gray)= "#808080"; my ($lightgray)= "#f0f0f0"; my ($red)= "#ff0000"; my ($green)= "#00ff00"; my ($blue)= "#0000ff"; my ($yellow)= "#ffff00"; my ($lightyellow)= "#ffffcc"; my ($purple)= "#ff00ff"; # well :-) my @monthname= qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); # Device specific parameters as index values my ($IDEVNAM)= 0; my ($IHEADER)= 1; my ($IUNIT)= 2; my ($IDIR)= 3; my ($IEXT)= 4; my ($IRATIO)= 5; my ($ITDIR)= 6; my ($IOPUT)= 7; #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub errorexit { print STDERR "$0: Error: @_.\n"; exit(21); } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub debug { my ($l,$s)= @_ if @_; # print STDERR "DEBUG $0 $l: $s\n" if $DEBUG; print STDERR "DEBUG $l: $s\n" if $DEBUG; } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub format_dot { my ($num)= @_; my ($i,$s,$r); $s= sprintf("%.0f",$num); $r= ""; for ($i= 1; $i<=length($s); $i++) { if ( ($i>1) && ( ($i-1)%3 == 0 ) ) { $r= $TSEP.$r; } $r= substr($s,$i*(-1),1).$r; } return $r; } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub get_factor { my ($unit) = @_; my ($factor) = 1; SWITCH: { $unit=~/K/ && do {$factor= 1024; last SWITCH; }; $unit=~/M/ && do {$factor= 1024*1024; last SWITCH; }; $unit=~/G/ && do {$factor= 1024*1024*1024; last SWITCH; }; $unit=~/T/ && do {$factor= 1024*1024*1024*1024; last SWITCH; }; $unit=~/P/ && do {$factor= 1024*1024*1024*1024*1024; last SWITCH; }; $unit=~/E/ && do {$factor= 1024*1024*1024*1024*1024*1024; last SWITCH; }; } # debug(__LINE__,"get_factor= ".$unit.":".$factor); return ($factor); } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub scale_bytes { my ($bytes) = @_; ($bytes =~ /^[\d.]+$/) or return "ERROR"; my ($units) = "Byte"; foreach my $unit ("KByte", "MByte", "GByte", "TByte", "PByte", "Ebyte") { last unless ($bytes / 1024 > 1); $bytes = $bytes / 1024; $units = $unit; } return ($bytes, $units); } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub scale_bytes1 { my ($bytes) = @_; my ($factor) = 1; while ( $bytes/1024 > 1 ) { $bytes/= 1024; $factor*= 1024; } return $factor; } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub scale_data { my ($max,@data) = @_; my ($units); my ($i,$j,$v) = 0; ($v,$units)= &scale_bytes($max); my ($factor)= &scale_bytes1($max); for $i (1 .. $#data) { for $j (0 .. $#{$data[$i]} ) { $data[$i][$j]/= $factor; } } return ($units, @data); } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub find_max { my (@data) = @_; my ($i,$j,$max) = 0; for $i (1 .. $#data) { for $j (0 .. $#{$data[$i]} ) { if ( $data[$i][$j] > $max ) { $max= $data[$i][$j]; } } } return $max; } #----------------------------------------------------------------------- sub get_args { my($mrtgfile); unless( $#ARGV == 0 ) { my($name) = basename($0) ; $name =~ s/\s+//g ; print STDERR "usage: $name <mrtg-cfg-file>\n" ; exit(1) ; } $mrtgfile = $ARGV[0]; if (! -r $mrtgfile) { &errorexit("Couldn't read $mrtgfile: $!"); } return($mrtgfile); } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub scan_mrtgcfg { my ($mrtgfile) = @_; my ($v,$w,$dev,$uni,$hea,$rat,$oput); my (%devices); my ($rrdtool,$workdir,$htmldir,$imagedir,$logdir); my ($directory,$extension,$total_unit,$total_ratio,$total_directory,$total_oput); my (@includes); push @includes, $mrtgfile; # Scan for additional Includes: debug(__LINE__,"scan_mrtgcfg Scanning: @_ for Includes"); open(MRTG,$mrtgfile) or &errorexit("Couldn't open mrtg config file $mrtgfile: $!"); while (<MRTG>) { $_ =~ s/\r//; # Replace DOS carriage-return \r with null 19/05/03 Dave Hardy chomp $_; if (/^Include:/i) { ($v,$w)= split (/:/,$_,2); $w=~ s/\s*//g; # Eliminate all whitespaces push @includes, $w; debug(__LINE__,"scan_mrtgcfg Found: $w"); } } # Process main file + includes: for my $file (@includes) { debug(__LINE__,"scan_mrtgcfg Processing: $file "); open(MRTG,$file) or &errorexit("Couldn't open mrtg config file $file: $!"); while (<MRTG>) { $_ =~ s/\r//; # Replace DOS carriage-return \r with null 19/05/03 Dave Hardy chomp $_; # Global mrtg parameters if (/^WorkDir:/i) { ($v,$workdir)= split(/:/,$_,2); $workdir=~ s/^\s*//; $workdir.= "/" if ( substr($workdir,-1,1) ne "/" ); } if (/^HtmlDir:/i) { ($v,$htmldir)= split(/:/,$_,2); $htmldir=~ s/^\s*//; $htmldir.= "/" if ( substr($htmldir,-1,1) ne "/" ); } if (/^ImageDir:/i) { ($v,$imagedir)= split(/:/,$_,2); $imagedir=~ s/^\s*//; $imagedir.= "/" if ( substr($imagedir,-1,1) ne "/" ); } if (/^LogDir:/i) { ($v,$logdir)= split(/:/,$_,2); $logdir=~ s/^\s*//; $logdir.= "/" if ( substr($logdir,-1,1) ne "/" ); } if (/^LogFormat:/i) { ($v,$w)= split(/:/,$_,2); $w=~ s/\s*//g; $rrdtool |= ($w =~ /^rrdtool/i); } if (/^PathAdd:/i) { ($v,$w)= split(/:/,$_,2); $w=~ s/\s//g; $ENV{PATH}= "$w:$ENV{PATH}"; } if (/^LibAdd:/i) { ($v,$w)= split(/:/,$_,2); $w=~ s/\s//g; unshift @INC, $w; } # Device specific mrtg parameters if (/^Directory/i) { ($v,$dev,$w)= split(/[\[\]]/,$_,4); $w=~ s/[\s:]//g; $w.= "/" if ( substr($w,-1,1) ne "/" ); if ( $dev eq '_' ) { $directory= $w; } else { $devices{lc($dev)}[$IDIR]= $w; } } if (/^Extension/i) { ($v,$dev,$w)= split(/[\[\]]/,$_,4); $w=~ s/[\s:]//g; if ( $dev eq '_' ) { $extension= $w; } else { $devices{lc($dev)}[$IEXT]= $w; } } # Device specific mrtg_total parameters if (/^\#\-\#Total\[/i) { ($v,$dev,$hea)= split(/[\[\]]/,$_,4); $hea=~ s/://; $devices{lc($dev)}[$IHEADER]= $hea; $devices{lc($dev)}[$IDIR]= $directory if ( $directory ne '' && $directory ne '/' ); $devices{lc($dev)}[$IEXT]= $extension if ( $extension ); $devices{lc($dev)}[$IUNIT]= $total_unit if ( $total_unit ); $devices{lc($dev)}[$IRATIO]= $total_ratio if ( $total_ratio ); $devices{lc($dev)}[$ITDIR]= $total_directory if ( $total_directory ne '' && $total_directory ne '/' ); $devices{lc($dev)}[$IOPUT]= $total_oput if ( $total_oput ); } if (/^\#\-\#Total-Unit\[/i) { ($v,$dev,$uni)= split(/[\[\]]/,$_,4); $uni=~ s/[\s:]//g; if ( $dev eq '_' ) { $total_unit= uc($uni); } else { $devices{lc($dev)}[$IUNIT]= uc($uni); } } if (/^\#\-\#Total-Ratio\[/i) { ($v,$dev,$rat)= split(/[\[\]]/,$_,4); $rat=~ s/[\s:]//g; $rat= 'yes' if ($rat =~ /y/i || $rat =~ /yes/i); if ( $dev eq '_' ) { $total_ratio= $rat; } else { $devices{lc($dev)}[$IRATIO]= $rat; } } if (/^\#\-\#Total-Directory\[/i) { ($v,$dev,$w)= split(/[\[\]]/,$_,4); $w=~ s/[\s:]//g; $w.= "/" if ( substr($w,-1,1) ne "/" ); if ( $dev eq '_' ) { $total_directory= $w; } else { $devices{lc($dev)}[$ITDIR]= $w; } } if (/^\#\-\#Total-Output\[/i) { ($v,$dev,$oput)= split(/[\[\]]/,$_,4); $uni=~ s/[\s:]//g; if ( $dev eq '_' ) { $total_oput= uc($oput); } else { $devices{lc($dev)}[$IOPUT]= uc($oput); } } } # end while close MRTG; } if ( $rrdtool ) { require RRDs; import RRDs qw(RRDs::fetch RRDs::error RRDs::info); debug(__LINE__,"RRDs required and imported"); } if ( $workdir ) { $htmldir= $workdir; $imagedir= $workdir; $logdir= $workdir; debug(__LINE__,"WorkDir overwrote [ HtmlDir, ImageDir, LogDir ]"); } return ($rrdtool, $workdir, $htmldir, $imagedir, $logdir, %devices); } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub exist_logfile { my ($logdir, $devnam, $rrdtool) = @_; my ($logfile); debug(__LINE__,"exist_logfile ( @_ )"); if ( $rrdtool ) { $logfile= $logdir.$devnam.".rrd"; my $hash = RRDs::info($logfile); # foreach my $key (keys %$hash){ # debug(__LINE__,"$key = $$hash{$key}"); # } my $ERR= RRDs::error(); errorexit("RRD-Error $ERR") if $ERR; return $logfile; } else { $logfile= $logdir.$devnam.".log"; debug(__LINE__,"logfile= ".$logfile); if ( open ( LOG, $logfile ) ) { close(LOG); return $logfile; } } print STDERR "Couldn't open $logfile: $!\n"; return 0; } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub get_totals_log { my ($logfile, $start,$end) = @_ if @_; my($itot,$otot,$interval) = (0,0,0); my($aline,$curr_date,$avg_in,$avg_out,$pin,$pout); # debug(__LINE__,"get_totals_log ( $logfile, ".localtime($start).", ".localtime($end)." )"); # File is in reverse, from end to start, so we count down... open(LOG,"$logfile"); # seek LOG,0,0; my($prev_date) = 0; while (<LOG>) { $aline = $_; chomp($aline); ($curr_date,$avg_in,$avg_out,$pin,$pout) = split(' ',$aline); if ( $prev_date==0 ) { $prev_date= $curr_date; } $interval = $prev_date - $curr_date; $prev_date = $curr_date; next if (($curr_date > $end) || ($curr_date < $start)); $itot = $itot + ($avg_in * $interval); $otot = $otot + ($avg_out * $interval); # debug(__LINE__,"get_totals_log (int=$interval itot=$itot otot=$otot)"); } close(LOG); return($itot,$otot); } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub get_totals_rrd { my ($logfile, $start,$end) = @_ if @_; my ($itot,$otot) = (0,0); my ($curr_date,$interval, $rheader,$rdata,$rdata1); debug(__LINE__,"get_totals_rrd ( $logfile, ".localtime($start).", ".localtime($end)." )"); ($curr_date,$interval, $rheader,$rdata)= RRDs::fetch ( $logfile, "AVERAGE", "--start",$start, "--end",$end ); my $ERR= RRDs::error(); errorexit("RRD-Error $ERR") if $ERR; foreach $rdata1 (@$rdata) { $itot+= @$rdata1[0] * $interval if defined @$rdata1[0]; $otot+= @$rdata1[1] * $interval if defined @$rdata1[1]; # debug(__LINE__,"get_totals_rrd (int=$interval itot=$itot otot=$otot)"); } return($itot,$otot); } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub get_totals { my ($rrdtool,$logfile, $start,$end) = @_ if @_; if ( $rrdtool ) { return get_totals_rrd ( $logfile, $start,$end ); } else { return get_totals_log ( $logfile, $start,$end ); } } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub print_header { my ($title, $header, $unit,$ratio, $imagedir,$directory,$pngfile) = @_; print HTML "<html>\n"; print HTML "<head>\n"; print HTML " <title> $title </title>\n"; print HTML "</head>\n"; print HTML "<body bgcolor="$lightyellow">\n"; print HTML " <basefont face="verdana,tahoma,arial">\n"; print HTML " <h2 align="center"> $header </h2>\n"; print HTML " <p align="center">\n"; print HTML " <img vspace=10 alt="$title" src="$pngfile"></p>\n"; print HTML " <table border align="center">\n"; print HTML " <tr align="center"> <font size="-1">\n"; print HTML " <th bgcolor="$gray"><font size="-1"> Date-from </font></th>\n"; print HTML " <th bgcolor="$gray"><font size="-1"> Date-to </font></th>\n"; print HTML " <th bgcolor="$red"><font size="-1">",$unit,"Bytes-IN </font></th>\n"; print HTML " <th bgcolor="$green"><font size="-1">",$unit,"Bytes-OUT </font></th>\n"; print HTML " <th bgcolor="$blue"><font size="-1">",$unit,"Bytes-TOTAL </font></th>\n"; if ( $ratio eq 'yes' ) { print HTML " <th bgcolor="$yellow"><font size="-1"> Ratio </font></th>\n"; } print HTML " </tr>\n"; } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub print_values { my ($start,$end, $in,$out, $unit,$ratio, $htmldir,$dir,$dev,$ext) = @_; my ($d_start, $d_end); my ( $s_sec, $s_min, $s_hour, $s_mday, $s_mon, $s_year, $s_wday, $s_yday, $s_isdst ) = localtime($start); my ( $e_sec, $e_min, $e_hour, $e_mday, $e_mon, $e_year, $e_wday, $e_yday, $e_isdst ) = localtime($end); if ( $DATEFORMAT == 0 ) { # German / European: DD.MM.YYYY $d_start= sprintf "%0.2d.%0.2d.%0.4d %0.2d:%0.2d ", $s_mday, $s_mon+1, $s_year+1900, $s_hour, $s_min; $d_end= sprintf "%0.2d.%0.2d.%0.4d %0.2d:%0.2d ", $e_mday, $e_mon+1, $e_year+1900, $e_hour, $e_min; } else { # otherwise: MM/DD/YYYY $d_start= sprintf "%0.2d/%0.2d/%0.4d %0.2d:%0.2d ", $s_mon+1, $s_mday, $s_year+1900, $s_hour, $s_min; $d_end= sprintf "%0.2d/%0.2d/%0.4d %0.2d:%0.2d ", $e_mon+1, $e_mday, $e_year+1900, $e_hour, $e_min; } print HTML " <tr align=right>\n"; if ( $dev ) { my $fout_mon= sprintf "%s.total.%d.%.2d.%s", $dev, $s_year+1900, $s_mon+1, $ext; if (-e $htmldir.$dir.$fout_mon) { print HTML " <td><font size="-1"><a href="$fout_mon">$d_start</a></font></td>\n"; } else { print HTML " <td><font size="-1">$d_start</font></td>\n"; } } else { print HTML " <td><font size="-1">$d_start</font></td>\n"; } print HTML " <td><font size="-1">$d_end</font></td>\n"; my ($factor)= get_factor($unit); my ($v1) = &format_dot($in/$factor); my ($v2) = &format_dot($out/$factor); my ($v3) = &format_dot(($in+$out)/$factor); print HTML " <td> <font size="-1">",$v1,"</font></td>\n"; print HTML " <td> <font size="-1">",$v2,"</font></td>\n"; print HTML " <td> <font size="-1">",$v3,"</font></td>\n"; if ( $ratio eq 'yes' ) { my ($v4) = ($in <= $out) ? # Calculate ratio sprintf("1 : %.2f", $in == 0 ? 0 : $out/$in) : sprintf("%.2f : 1", $out == 0 ? 0 : $in/$out); print HTML " <td> <font size="-1">",$v4,"</font></td>\n"; } print HTML " </tr>\n"; } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub print_footer { my ($footer) = @_ if @_; print HTML "</table>\n"; print HTML "<br>\n"; print HTML "<p align="center">$footer</p>\n" if $footer; print HTML "</body>\n"; print HTML "</html>\n"; } #----------------------------------------------------------------------- #----------------------------------------------------------------------- sub make_graph { my ( $fimg, $xlabel, $ylabel, $title, @data ) = @_; my $graph = GD::Graph::bars3d->new(600, 300); # my $graph = GD::Graph::bars->new(600, 200); $graph->set_text_clr("black"); $graph->set_legend_font(GD::Text::gdTinyFont); $graph->set_title_font(GD::Text::gdMediumBoldFont); $graph->set (x_label => $xlabel, y_label => $ylabel, title => $title, bar_spacing => 2, y_tick_number => 7, y_label_skip => 1 ); open(IMG, "> $fimg") or die $!; binmode(IMG); # only for Windows, but won't hurt for Linux print IMG $graph->plot(\@data)->png; close(IMG); } #----------------------------------------------------------------------- #----------------------------------------------------------------------- # MAIN my ($start_date, $end_date, # from - to $mrtgfile, # name of mrtg config file $logfile, # current mrtg file .log $htmlfile, # HTML output file $pngfile, # PNG output file $workdir, # WorkDir: from $mrtgfile $htmldir, # HtmlDir: from $mrtgfile $imagedir, # ImageDir: from $mrtgfile $logdir, # LogDir: from $mrtgfile $rrdtool, # where RRD resides %devices, # List with devices to totalize $devnam, # Totals for this device are requested $directory, # Directory[$devnam]: from $mrtgfile $extension, # Extension[$devnam]: from $mrtgfile $header, # #-#Total[$devnam]: Header for the HTML output $unit, # #-#Total-Unit[$devnam]: Unit (K/M/G byte) for table output $ratio, # #-#Total-Ratio[$devnam]: output w/wo in/out ratio $tdir, # #-#Total-Directory[$devnam]: subdir similar to Directory $oput, # #-#Total-Output[$devnam]: output to generate (DWM) $odir, # output directory $in_tot, $out_tot, # counter for incoming / outgoing totals ); my ($d, $m, $v, $w, $wday_newyear, $w_offset1, $w_offset2, $yesterday); $mrtgfile= &get_args; # Get name of mrtg file from command line # only for test purposes :-) # ($workdir, $htmldir,$imagedir,$logdir, @devices)= ( "/usr/local/mrtg/web", # "/usr/local/mrtg/web", # "/usr/local/mrtg/web", # "/usr/local/mrtg/web", # ["inbound.ser2"]); ($rrdtool, $workdir, $htmldir, $imagedir, $logdir, %devices) = scan_mrtgcfg($mrtgfile); # scan throu mrtg config file and find devices debug(__LINE__,"RRDtool= ".$rrdtool); debug(__LINE__,"WorkDir= ".$workdir); debug(__LINE__,"HtmlDir= ".$htmldir); debug(__LINE__,"ImageDir= ".$imagedir); debug(__LINE__,"LogDir= ".$logdir); # Find yesterday $yesterday= time - (60*60*24-1); # if you need to run the script at a spcific date (here: 1st of May, 2000 00:05:00) # comment out the following 7 lines. Afterthat - please - comment it in again! # my ($day) = 31; # <--- day # my ($mon) = 5; # <--- month # my ($year)= 2000; # <--- year # my ($sec, $min, $hour)= (0,5,0); # $year-= 1900; # $mon-= 1; # $yesterday= timelocal($sec, $min, $hour, $day, $mon, $year) - (60*60*24-1); my ($sec, $min, $hour, $day, $mon, $year, $wday, $yday)= localtime($yesterday); $year+= 1900; $mon+= 1; foreach $v ( keys %devices ) { # next if ($v =~ m/mem/i); # optional jump out $devnam= $v; $directory= $devices{$v}[$IDIR]; if ( $devices{$v}[$IEXT] ) { $extension= $devices{$v}[$IEXT]; } else { $extension= "html"; } $header= $devices{$v}[$IHEADER]; $unit= $devices{$v}[$IUNIT]; $ratio= $devices{$v}[$IRATIO]; $tdir= $devices{$v}[$ITDIR]; if ( $devices{$v}[$IOPUT] ) { $oput= $devices{$v}[$IOPUT]; } else { $oput= "DM"; } debug(__LINE__,"devnam= ".$devnam); debug(__LINE__," directory= ".$directory); debug(__LINE__," extension= ".$extension); debug(__LINE__," header = ".$header); debug(__LINE__," unit = ".$unit); debug(__LINE__," ratio = ".$ratio); debug(__LINE__," tdir = ".$tdir); $odir= $directory; $odir= $tdir if (length($tdir) > 0); next if ( length($header) == 0 ); # no #-#Total tag for this device if ( $logfile= exist_logfile ( $logdir.$directory, $devnam, $rrdtool ) ) { # Print daily totals for this month ################################### if ( $oput =~ /D/i ) { $htmlfile= sprintf "%s.total.%d.%.2d.%s", $devnam, $year, $mon, $extension; $pngfile= sprintf "%s.total.%d.%.2d.png",$devnam, $year, $mon; if (! -d $htmldir.$odir) { mkdir $htmldir.$odir, 0777; debug(__LINE__,"Creating Dir: $htmldir.$odir"); } open(HTML,"> $htmldir$odir$htmlfile") or &errorexit("Couldn't open/create $htmldir$odir$htmlfile: $!"); debug(__LINE__,"File opened: $htmldir$odir$htmlfile "); &print_header("Traffic statistics, totals for $devnam", $header, $unit,$ratio, $htmldir,$odir,$pngfile); # Find totals for every day my (@data); for ( $d= 1; $d <= $day; $d++ ) { $start_date= timelocal( 0, 0, 0,$d,$mon-1,$year); $end_date= timelocal(59,59,23,$d,$mon-1,$year); ($in_tot,$out_tot) = &get_totals($rrdtool,$logfile, $start_date,$end_date); $data[0][$d-1]= $d; $data[1][$d-1]= $in_tot; $data[2][$d-1]= $out_tot; $data[3][$d-1]= ($out_tot+$in_tot); &print_values($start_date,$end_date,$in_tot,$out_tot,$unit,$ratio); } # &print_footer("<center>Questions to <a href="mailto:josef.wendel\@web.de">me</a>, please.</center>"); &print_footer; # Scale totals my ($max)= &find_max(@data); my ($units); ($units,@data)= &scale_data($max,@data); # Make and print the graph &make_graph ( $htmldir.$odir.$pngfile, "Day", $units, "$mon.$year", @data ); close(HTML); } # Print weekly totals for this year ################################### if ( $oput =~ /W/i ) { $htmlfile= sprintf "%s.total.%d"."w.%s", $devnam, $year, $extension; $pngfile= sprintf "%s.total.%d"."w.png",$devnam, $year; open(HTML,"> $htmldir$odir$htmlfile") or &errorexit("Couldn't open/create $htmldir$odir$htmlfile: $!"); debug(__LINE__,"File opened: $htmldir$odir$htmlfile "); &print_header("Traffic statistics, totals for $devnam", $header, $unit,$ratio, $htmldir,$odir,$pngfile); # first week of a year is the week with the first Thursday # and the week starts with Monday (not with Sunday as in Perl) $wday_newyear= ( localtime ( timelocal(0,0,0,1,0,$year) ) ) [6]; if ( $wday_newyear <= 4 ) # 1.1. in [ Sun, Mon, Tue, Wed, Thu ] { $w_offset1= -$wday_newyear + 1; } else # 1.1. in [ Fri, Sat ] { $w_offset1= 8 - $wday_newyear; } # similar for the last week = ends 1 day before the 1. week of the next yr starts $wday_newyear= ( localtime ( timelocal(0,0,0,1,0,$year+1) ) ) [6]; if ( $wday_newyear <= 4 ) # 1.1. in [ Sun, Mon, Tue, Wed, Thu ] { $w_offset2= -$wday_newyear + 1; } else # 1.1. in [ Fri, Sat ] { $w_offset2= 8 - $wday_newyear; } my $ny_date2= timelocal(0,0,0,1,0,$year+1) + $w_offset2 *60*60*24; # undef (@data); my (@data); for ( $w= 1; $w <= 53; $w++ ) { $start_date= timelocal(0,0,0,1,0,$year) + (($w-1)*7 + $w_offset1) *60*60*24; $end_date = timelocal(0,0,0,1,0,$year) + ($w*7 + $w_offset1) *60*60*24 - 1; if ( $end_date < $ny_date2 ) { # for years with only 52 weeks ($in_tot,$out_tot) = &get_totals($rrdtool,$logfile, $start_date,$end_date); $data[0][$w-1]= ""; $data[0][$w-1]= $w if (($w%5)==0); $data[1][$w-1]= $in_tot; $data[2][$w-1]= $out_tot; $data[3][$w-1]= ($out_tot+$in_tot); &print_values($start_date,$end_date,$in_tot,$out_tot,$unit,$ratio, $htmldir,$odir,$devnam,$extension) } } # Scale it my ($max)= &find_max(@data); my ($units); ($units,@data)= &scale_data($max,@data); &print_footer; # Make and print the graph &make_graph ( $htmldir.$odir.$pngfile, "Week", $units, $year, @data ); close(HTML); } # Print monthly totals for this year #################################### if ( $oput =~ /M/i ) { $htmlfile= sprintf "%s.total.%d.%s", $devnam, $year, $extension; $pngfile= sprintf "%s.total.%d.png",$devnam, $year; open(HTML,"> $htmldir$odir$htmlfile") or &errorexit("Couldn't open/create $htmldir$odir$htmlfile: $!"); debug(__LINE__,"File opened: $htmldir$odir$htmlfile "); &print_header("Traffic statistics, totals for $devnam", $header, $unit,$ratio, $htmldir,$odir,$pngfile); # undef (@data); my (@data); for ( $m= 1; $m <= 12; $m++ ) { $start_date= timelocal(0,0,0,1,$m-1,$year); if ( $m<12 ) { $end_date= timelocal(0,0,0,1,$m,$year); } # Jan-Nov else { $end_date= timelocal(0,0,0,1,0,$year+1); } # Dez ($in_tot,$out_tot) = &get_totals($rrdtool,$logfile, $start_date,$end_date); $data[0][$m-1]= @monthname[$m-1]; $data[1][$m-1]= $in_tot; $data[2][$m-1]= $out_tot; $data[3][$m-1]= ($out_tot+$in_tot); &print_values($start_date,$end_date,$in_tot,$out_tot,$unit,$ratio, $htmldir,$odir,$devnam,$extension) } # Scale it my ($max)= &find_max(@data); my ($units); ($units,@data)= &scale_data($max,@data); &print_footer; # Make and print the graph &make_graph ( $htmldir.$odir.$pngfile, "Month", $units, $year, @data ); close(HTML); } } # if logfile exists } # for $v (@devices) #----------------------------------------------------------------------- # The main 'frontend' PHP script looks like this: PHP:
<?php
$title="Alcatel Speedtouch 510 v3, 512/256K ADSL Traffic Totals";
$device="st510_tx";
?>
<HTML>
<HEAD>
<TITLE><?php print $title;?></TITLE>
</HEAD>
<BODY>
<?
$d= dir("/usr/local/mrtg/web/");
$muster= $device."\.total\.[0-9][0-9][0-9][0-9]\.png";
$fcount= 0;
print "<h2>$title</h2>";
while ( $entry= $d->read() ) {
if ( ereg($muster, $entry) ) {
$i= strrpos($entry,".");
$f= substr($entry,0,$i);
$files[]= $f;
$fcount++;
}
}
$d->close();
if ( $files ) {
rsort($files);
for ( $i= 0; $i<$fcount; $i++) {
print "<IMG SRC=\"".$files[$i].".png\" ALIGN=MIDDLE VSPACE=10>";
print " <A HREF=\"".$files[$i].".php\">Details</A>";
print "<BR>\n";
}
}
print "</CENTER>";
?>
</BODY>
</HTML>
This basically builds up an html page with links to all the individual totals pages that have been generated by mrtg_total.pl. Trackbacks
Trackback specific URI for this entry
No Trackbacks
|

