#! /usr/bin/perl
#
#  Purpose:
#  FlowTracker_Grapher runs periodically (configurable) to update FlowTracker 
#  graphs with the latest data collected by FlowTracker_Collector.
#
#  Description:
#  The user initiates the script from a command line appending an "&" to put
#  it in the background. The script re-creates four graphs for each existing 
#  RRDtool file (i.e., last 24 hours, last 7 days, last month, last year.)
#  A set of rrdtool parameters, in the FlowViewer_Configuration.pm file,
#  permits the user to configure parameters like size and color, etc.. When
#  finished with all of the existing Trackings, the script will go to sleep for
#  the remainder of the specified graphing period.
#
#  Controlling Parameters (specified in FlowViewer_Configuration.pm):
#  Name                 Description
#  -----------------------------------------------------------------------
#  rrd_area             Color of the area underneath the graph
#  rrd_line             Color of the line at the top of the graphed area
#  rrd_width            Width of the graph
#  rrd_height           Height of the graph
#  rrd_font             Color of the font used in the graphs
#  rrd_back             Image background color
#  rrd_canvas           Color of the background of the actual graph
#  rrd_grid             Color of the minor grid lines
#  rrd_mgrid            Color of the major grid lines
#  rrd_frame            Color of the graph frame
#  rrd_shadea           Color for the top and left border
#  rrd_shadeb           Color for the right and bottom border
#  rrd_thick            Thickness of the line at teh top of the graph
#  rrd_lower_limit      Bottom of the y-axis
#  rrd_slope_mode       "--slope-mode" will round off tops of graph  
#  rrd_vrule_color      Color of the line that indicates when the filter was changed
#
#  Modification history:
#  Author       Date            Vers.   Description
#  -----------------------------------------------------------------------
#  J. Loiacono  07/04/2006      3.0     Original version.
#
#$Author$
#$Date$
#$Header$
#
###########################################################################
#
#               BEGIN EXECUTABLE STATEMENTS
#
 
use FlowViewer_Configuration;
use FlowViewer_Utilities;
use lib $cgi_bin_directory;

$a = 0; while ($a == 0) {

	if ($log_grapher   eq "Y") { open (LOG,">>$log_directory/FlowTracker_Grapher.log"); }
	if ($debug_tracker eq "Y") { open(DEBUG,">$work_directory/DEBUG_TRACKER"); }

	$end_rrd       = time;
	$num_trackings = 0;
	@trackings = "";

	if (($log_grapher eq "Y") || (debug_grapher eq "Y")) { 
                $current_time = time;
                $current_time_out = epoch_to_date($current_time,"LOCAL"); 
                $current_time_rrd = $current_time_out; 
                $current_time_rrd =~ s/:/\\:/g; 

		if ($log_grapher   eq "Y") { print LOG   "Starting a graphing loop at: $current_time_out\n"; }
		if ($debug_tracker eq "Y") { print DEBUG "Starting a graphing loop at: $current_time_out\n"; }
	}

	# Work through each tracking
	
	while ($rrdtool_file = <$rrdtool_directory/*>) {
	
		($directory,$tracking) = $rrdtool_file =~ m/(.*\/)(.*)$/;
		($tracking,$extension) = split(/\./,$tracking);
	
		$num_trackings++;

                # Look for revisions to a Tracking and prepare graph notation (vrule) if requested
      
                $filter_file = "$filter_directory/$tracking" . ".fil";  
		$vrule_1 = "";
		$vrule_2 = "";
		$vrule_3 = "";

                open (FILTER,"<$filter_file"); 
                while (<FILTER>) { 
                        chop;    
                        $key = substr($_,0,8); 
                        if ($key eq " input: ") { 
                                ($input,$field,$field_value) = split(/: /); 
                                if ($field eq "revision") { 

                                        ($notate_graphs,$revision_date,$revision_comment) = split(/\|/,$field_value);  
                                        $revision_date_out = epoch_to_date($revision_date,"LOCAL"); 
                                        $revision_date_out =~ s/:/\\:/g;

                                        if ($notate_graphs eq "Y") {   
                                                if ($vrule_1 eq "") { 
                                                        $vrule_1 = "     VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
                                                        next; }  
                                                elsif ($vrule_2 eq "") { 
                                                        $vrule_2 = "     VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
                                                        next; }  
                                                elsif ($vrule_3 eq "") { 
                                                        $vrule_3 = "     VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
                                                        next; }  
                                        } 
                                }       
				if ($field eq "tracking_label") { $trackings{$tracking} = $field_value; }
				if ($field eq "general_comment") { $trackings{$tracking} .= "^" . $field_value; }
			}
                }                
                close (FILTER);

		if ($log_grapher) { print LOG "creating graphs for: $tracking\n"; }
	
		# Create each of the four graphs for this tracking
		
		foreach $graph_type ("Daily", "Weekly", "Monthly", "Yearly") {
		
			if ($graph_type eq "Daily") {
				$start_rrd = $end_rrd - 86400;
				$sample = "     Data collected over 5 minute periods              Graph Last Updated\\: $current_time_rrd";
				$rrd_title = "\"Last 24 Hours\"";
				$graph_file = "$tracker_directory/$tracking/daily.png"; }
			elsif ($graph_type eq "Weekly") {
				$start_rrd = $end_rrd - (7*86400);
				$sample = "     Data averaged over 30 minute periods              Graph Last Updated\\: $current_time_rrd";
				$rrd_title = "\"Last 7 Days\"";
				$graph_file = "$tracker_directory/$tracking/weekly.png"; }
			elsif ($graph_type eq "Monthly") {
				$start_rrd = $end_rrd - (28*86400);
				$sample = "     Data averaged over 2 hour periods                 Graph Last Updated\\: $current_time_rrd";
				$rrd_title = "\"Last 4 Weeks\"";
				$graph_file = "$tracker_directory/$tracking/monthly.png"; }
			elsif ($graph_type eq "Yearly") {
				$start_rrd = $end_rrd - (365*86400);
				$sample = "     Data averaged over 24 hour periods                Graph Last Updated\\: $current_time_rrd";
				$rrd_title = "\"Last 12 Months\"";
				$graph_file = "$tracker_directory/$tracking/yearly.png";
			}

                        @graph_parameters =
                                ('--title',"$rrd_title",
                                '--start',$start_rrd,
                                '--end',$end_rrd,
                                '--width',$rrd_width,
                                '--height',$rrd_height,
                                '--interlace',
                                '--lazy',
                                '--vertical-label',"\"Bits per Second\"",
                                $rrd_slope_mode,
                                "--color=FONT#$rrd_font",
                                "--color=BACK#$rrd_back",
                                "--color=CANVAS#$rrd_canvas",
                                "--color=GRID#$rrd_grid",
                                "--color=MGRID#$rrd_mgrid",
                                "--color=FRAME#$rrd_frame",
                                "--color=SHADEA#$rrd_frame",
                                "--color=SHADEB#$rrd_frame",
                                '--lower-limit',$rrd_lower_limit,
                                "DEF:flowbits=$rrdtool_file:flowbits:AVERAGE",
                                'VDEF:flowbitsmax=flowbits,MAXIMUM',
                                'VDEF:flowbitsavg=flowbits,AVERAGE',
                                'VDEF:flowbitsmin=flowbits,MINIMUM',
                                'VDEF:flowbitspct=flowbits,95,PERCENT',
                                "AREA:flowbits#$rrd_area",
                                "LINE$rrd_thick:flowbits#$rrd_line:",
                                "COMMENT:\"$sample   \"",
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"     95th percentile    \"",
                                "GPRINT:flowbitspct:\"%6.2lf %Sbps\"",
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"             Maximum    \"",
                                "GPRINT:flowbitsmax:\"%6.2lf %Sbps \"",
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"             Average    \"",
                                "GPRINT:flowbitsavg:\"%6.2lf %Sbps \"",
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"             Minimum    \"",
                                "GPRINT:flowbitsmin:\"%6.2lf %Sbps \"",
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"   \"",
                                $vrule_1,
                                "COMMENT:\"   \"",
                                $vrule_2,
                                "COMMENT:\"   \"",
                                $vrule_3);
 
                        $rrdgraph_command = "$rrdtool_bin_directory/rrdtool graph " . "$graph_file " . "@graph_parameters " . ">/dev/null";
                        system($rrdgraph_command);

                        if ($debug_tracker eq "Y") { print DEBUG "finished $graph_type for $graph_file\n"; }
		}

	}

	# Update the Trackings HTML file

	open(TRACKINGS,">$tracker_directory/$tracker_webpage");

	print TRACKINGS "<html>\n"; 
	print TRACKINGS "<head>\n"; 
	print TRACKINGS "<title>\n"; 
	print TRACKINGS "FlowTracker Active Trackings\n"; 
	print TRACKINGS "</title>\n"; 
	print TRACKINGS "</head>\n"; 
	print TRACKINGS "<body bgcolor=$bg_color text=$text_color link=$link_color vlink=$vlink_color>\n"; 
	print TRACKINGS "<style type=text/css><!-- A { text-decoration:none } --></style>"; 
	print TRACKINGS "<center>\n"; 
	print TRACKINGS "<font face=arial>";
        print TRACKINGS "<table>\n";  
        print TRACKINGS "<tr valign=middle>\n";  
        print TRACKINGS "<td>\n";  
	print TRACKINGS "<a href=$cgi_bin_short/FlowTracker.cgi><img src=$tracker_short/FlowTracker.png border=0></a>\n"; 
        print TRACKINGS "</td><td width=30></td>\n";  
        print TRACKINGS "<td valign=bottom>\n";  
        print TRACKINGS "<center><h3>$trackings_title\n";  
        print TRACKINGS "<br>Active Netflow Trackings</h3>\n";  
        print TRACKINGS "</center></td>\n";  
        print TRACKINGS "</tr>\n";  
        print TRACKINGS "</table>\n";
        print TRACKINGS "<br><br>\n";  
	print TRACKINGS "<font face=arial size=-1>";
        print TRACKINGS "<table frame=border rules=all cellpadding=15>\n";
	print TRACKINGS "<th>Tracking</th>\n";
	print TRACKINGS "<th>General Comment</th>\n";

	@sorted_trackings = sort (keys (%trackings));

	foreach $tracking (@sorted_trackings) {
		if ($debug_tracker eq "Y") { print DEBUG "tracking: $tracking\n"; }
		($tracking_label,$general_comment) = split(/\^/,$trackings{$tracking});
		$tracking_link = "<a href=$tracker_short/$tracking>$tracking_label</a>";
		print TRACKINGS "<tr valign=top>\n";
		print TRACKINGS "<td>\n";
		print TRACKINGS "<font face=arial size=-1>";
		print TRACKINGS "$tracking_link";
		print TRACKINGS "</td>\n";
		print TRACKINGS "<td>\n";
		print TRACKINGS "<font face=arial size=-1>";
		print TRACKINGS "$general_comment<br>";
		print TRACKINGS "</td>\n";
		print TRACKINGS "</tr>\n";
	}

        print TRACKINGS "</table>\n";
	print TRACKINGS "</form>\n"; 
	print TRACKINGS "</body>\n"; 
	print TRACKINGS "</html>\n"; 

	close(TRACKINGS);

	# Update log and go to sleep for what remains of 5-minute period

       	$end_graphing_time = time;
       	$loop_time = $end_graphing_time - $end_rrd;
       	$sleep_period = $graphing_period - $loop_time;

       	if ($log_grapher eq "Y") { print LOG "Finished with this loop. $num_trackings graph sets created. Loop took: $loop_time seconds  sleep_period: $sleep_period\n\n"; }

	close (LOG);
	close (DEBUG);

       	sleep ($sleep_period);
}
