Cool zoom/history feature for cacti :)

Addons for Cacti and discussion about those addons

Moderators: Developers, Moderators

Post Reply
Bruno Prigent

Cool zoom/history feature for cacti :)

Post by Bruno Prigent »

Hi

I wrote a few lines in order to add a zoom in cacti. It's usefull to see what append a month ago, just change the number of row in the daily rra (17280 is the value I use). I based my developpement on cacti-0.8-pre20030415.tar.gz.

I think decompress the archive in cacti dir should work. Click on a graph and select zoom.

Don't hesitate to send comments.

Bruno.

Here is the code :
cacti_dir/zoom_graph.php (new file) :

Code: Select all

<?php
/*
 This file is based on graph.php
*/

include_once ("include/rrd_functions.php");
include_once ("include/functions.php");
include_once ("include/form.php");
include ("include/top_graph_header.php");

if ($_GET["rra_id"] == "all") {
	$sql_where = " where id is not null";
}else{
	$sql_where = " where id=" . $_GET["rra_id"];
}

/* take graph permissions into account here, if the user does not have permission
give an "access denied" message */
if (read_config_option("global_auth") == "on") {
	$user_auth = db_fetch_row("select user_id from user_auth_graph where local_graph_id=" . $_GET["local_graph_id"] . " and user_id=" . $_SESSION["sess_user_id"]);
	
	$access_denied = false;
	
	if ($current_user["graph_policy"] == "1") {
		if (sizeof($user_auth) > 0) { $access_denied = true; }
	}elseif ($current_user["graph_policy"] == "2") {
		if (sizeof($user_auth) == 0) { $access_denied = true; }
	}
	
	if ($access_denied == true) {
		print "<strong><font size='+1' color='FF0000'>ACCESS DENIED</font></strong>"; exit;
	}
}

/* make sure the graph requested exists (sanity) */
if (!(db_fetch_cell("select local_graph_id from graph_templates_graph where local_graph_id=" . $_GET["local_graph_id"]))) {
	print "<strong><font size='+1' color='FF0000'>GRAPH DOES NOT EXIST</font></strong>"; exit;
}
$graph_param = "";

if ($start_year != "") {
        $graph_param .= "&graph_start=".mktime($start_hour, $start_min, $start_sec, $start_month, $start_day, $start_year)."&graph_end=".mktime($end_hour, $end_min, $end_sec, $end_month, $end_day, $end_year)."&graph_height=$graph_height"."&graph_width=$graph_width";
}
else {
        $start_year = date("Y");
        $start_month = date("m");
        $start_day = date("d", strtotime("-1 day"));
        $start_hour = date("H");
        $start_min = date("i");
        $start_sec = date("s");
        $end_year = date("Y");
        $end_month = date("m");
        $end_day = date("d");
        $end_hour = date("H");
        $end_min = date("i");
        $end_sec = date("s");
        $graph_height = 192;
        $graph_width = 800;
}

$graph_title = get_graph_title($_GET["local_graph_id"]);

print "<table width='98%' style='background-color: #f5f5f5; border: 1px solid #bbbbbb;' align='center' cellpadding='3'>";
print "<tr bgcolor='#" . $colors["header_panel"] . "'><td colspan='3' class='textHeaderDark'><strong>Viewing Graph '$graph_title'</strong></td></tr>";

	print "<tr><td>";
	
	print " <div align='center'><img src='graph_image.php?local_graph_id=" . $_GET["local_graph_id"] . "&rra_id=" . $rra_id . $graph_param . "' border='0' alt='$graph_title'></div>\n";
	print "</td></tr>";
	

print "</table>";
print "<br><br>";

print "<table width='98%' style='background-color: #f5f5f5; border: 1px solid #bbbbbb;' align='center' cellpadding='3'>";
	print "<tr bgcolor='#" . $colors["header"] . "'><td colspan='3' class='textHeaderDark'><strong>Zoom parameters</strong></td></tr>";
	print "<tr><td>";

	print "<form method='post'>";
        start_box("Start graph at", "100%", $colors["header_panel"],"3", "center","");
        print "<tr><td>&&&<select name='start_year'>";
        for ($i=$start_year-2 ; $i<=$end_year+2 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_year) {?> selected<?}?>><?printf("%04d", $i);?></option>
<?      } 
        print "</select> / ";
        print "<select name='start_month'>";

        for ($i=1 ; $i<=12 ; $i++)
        {
                ?> <option value="<?print $i;?>"<?if ($i==$start_month) {?> selected<?}?>><?print date("M", mktime($start_hour, $start_min, $start_sec, $i, $start_day, $start_year));?></option>
<?      } 
        print "</select> / ";
        print "<select name='start_day'>";

        for ($i=1 ; $i<=31 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_day) {?> selected<?}?>><?printf("%02d", $i);?></option>

<?      } 
        print "</select> at ";
        print "<select name='start_hour'>";

        for ($i=0 ; $i<=23 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_hour) {?> selected<?}?>><?printf("%02d", $i);?></option>

<?      } 
        print "</select> H ";
        print "<select name='start_min'>";

        for ($i=0 ; $i<=59 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_min) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> m ";
        print "<select name='start_sec'>";

        for ($i=0 ; $i<=59 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_sec) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> sec";
        print "</td></tr>";

	end_box();

        start_box("End graph at", "100%", $colors["header_panel"],"3", "center","");
        print "<tr><td>&&&<select name='end_year'>";

        for ($i=$start_year-2 ; $i<=$end_year+2 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_year) {?> selected<?}?>><?printf("%04d", $i);?></option>
<?      } 
        print "</select> / ";
        print "<select name='end_month'>";

        for ($i=1 ; $i<=12 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_month) {?> selected<?}?>><?print date("M", mktime($end_hour, $end_min, $end_sec, $i, $end_day, $end_year));?></option>
<?      } 
        print "</select> / ";
        print "<select name='end_day'>";

        for ($i=1 ; $i<=31 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_day) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> at ";
        print "<select name='end_hour'>";

        for ($i=0 ; $i<=23 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_hour) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> H ";
        print "<select name='end_min'>";

        for ($i=0 ; $i<=59 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_min) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> m ";
        print "<select name='end_sec'>";

        for ($i=0 ; $i<=59 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_sec) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> sec";
        print "</td></tr>";
	end_box();

	start_box("Width", "100%", $colors["header_panel"],"3", "center","");
        print "<tr><td><input type='text' name='graph_width' size='20' value='" . $graph_width . "'></td></tr>";
	end_box();

	start_box("Height", "100%", $colors["header_panel"],"3", "center","");
        print "<tr><td><input type='text' name='graph_height' size='20' value='" . $graph_height . "'></td></tr>";
	end_box();
	print "<input type='image' src='images/button_view.gif' alt='Go' border='0' align='absm iddle' action='submit'>";
	print "</td></tr>";
	print "</table>";	
	print "</form>";
include_once ("include/bottom_footer.php");

?>


cacti_dir/graph.php :
<?php
/*
 +-------------------------------------------------------------------------+
 | Copyright (C) 2003 Ian Berry                                            |
 |                                                                         |
 | This program is free software; you can redistribute it and/or           |
 | modify it under the terms of the GNU General Public License             |
 | as published by the Free Software Foundation; either version 2          |
 | of the License, or (at your option) any later version.                  |
 |                                                                         |
 | This program is distributed in the hope that it will be useful,         |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
 | GNU General Public License for more details.                            |
 +-------------------------------------------------------------------------+
 | cacti: a php-based graphing solution                                    |
 +-------------------------------------------------------------------------+
 | Most of this code has been designed, written and is maintained by       |
 | Ian Berry. See about.php for specific developer credit. Any questions   |
 | or comments regarding this code should be directed to:                  |
 | - iberry@raxnet.net                                                     |
 +-------------------------------------------------------------------------+
 | - raXnet - http://www.raxnet.net/                                       |
 +-------------------------------------------------------------------------+
*/

include_once ("include/rrd_functions.php");
include_once ("include/functions.php");
include ("include/top_graph_header.php");

if ($_GET["rra_id"] == "all") {
	$sql_where = " where id is not null";
}else{
	$sql_where = " where id=" . $_GET["rra_id"];
}

/* take graph permissions into account here, if the user does not have permission
give an "access denied" message */
if (read_config_option("global_auth") == "on") {
	$user_auth = db_fetch_row("select user_id from user_auth_graph where local_graph_id=" . $_GET["local_graph_id"] . " and user_id=" . $_SESSION["sess_user_id"]);
	
	$access_denied = false;
	
	if ($current_user["graph_policy"] == "1") {
		if (sizeof($user_auth) > 0) { $access_denied = true; }
	}elseif ($current_user["graph_policy"] == "2") {
		if (sizeof($user_auth) == 0) { $access_denied = true; }
	}
	
	if ($access_denied == true) {
		print "<strong><font size='+1' color='FF0000'>ACCESS DENIED</font></strong>"; exit;
	}
}

/* make sure the graph requested exists (sanity) */
if (!(db_fetch_cell("select local_graph_id from graph_templates_graph where local_graph_id=" . $_GET["local_graph_id"]))) {
	print "<strong><font size='+1' color='FF0000'>GRAPH DOES NOT EXIST</font></strong>"; exit;
}

$rras = db_fetch_assoc("select id,name from rra $sql_where order by steps");

$graph_title = get_graph_title($_GET["local_graph_id"]);

print "<table width='98%' style='background-color: #f5f5f5; border: 1px solid #bbbbbb;' align='center' cellpadding='3'>";
print "<tr bgcolor='#" . $colors["header_panel"] . "'><td colspan='3' class='textHeaderDark'><strong>Viewing Graph '$graph_title'</strong></td></tr>";

$i = 0;
if (sizeof($rras) > 0) {
foreach ($rras as $rra) {
	print "<tr><td>";
	
	print "	<div align='center'><img src='graph_image.php?local_graph_id=" . $_GET["local_graph_id"] . "&rra_id=" . $rra["id"] . "' border='0' alt='$graph_title'></div>\n
                <div align='center'><strong>" . $rra["name"] . "</strong> [<a href='graph.php?local_graph_id=" . $_GET["local_graph_id"] . "&rra_id=" . $rra["id"] . "&show_source=true'>source</a>][<a href='zoom_graph.php?local_graph_id=" . $_GET["local_graph_id"]. "&rra_id=" . $rra["id"] . "'>zoom</a>]</div><br>\n";	
	print "</td></tr>";
	
	$i++;
}
}

print "</table>";
print "<br><br>";

include_once ("include/bottom_footer.php");

?>


cacti_dir/graph_image.php
<?php
/*
 +-------------------------------------------------------------------------+
 | Copyright (C) 2003 Ian Berry                                            |
 |                                                                         |
 | This program is free software; you can redistribute it and/or           |
 | modify it under the terms of the GNU General Public License             |
 | as published by the Free Software Foundation; either version 2          |
 | of the License, or (at your option) any later version.                  |
 |                                                                         |
 | This program is distributed in the hope that it will be useful,         |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
 | GNU General Public License for more details.                            |
 +-------------------------------------------------------------------------+
 | cacti: a php-based graphing solution                                    |
 +-------------------------------------------------------------------------+
 | Most of this code has been designed, written and is maintained by       |
 | Ian Berry. See about.php for specific developer credit. Any questions   |
 | or comments regarding this code should be directed to:                  |
 | - iberry@raxnet.net                                                     |
 +-------------------------------------------------------------------------+
 | - raXnet - http://www.raxnet.net/                                       |
 +-------------------------------------------------------------------------+
*/

/* since we'll have addition headers, tell php when to flush them */
ob_start();

$guest_account = true; include ('include/auth.php');
include_once ("include/rrd_functions.php");

header("Content-type: image/png");

/* flush the headers now */
ob_end_flush();

$graph_data_array = array();

/* check to see if there are user specified vars */
if (!empty($_GET["graph_start"])) {
	$graph_data_array["use"] = true;
	$graph_data_array["graph_start"] = $_GET["graph_start"];
        if ($graph_end !="") { $graph_data_array["graph_end"] = $graph_end;}
	$graph_data_array["graph_height"] = $_GET["graph_height"];
	$graph_data_array["graph_width"] = $_GET["graph_width"];
}

/* treat the legend separatly */
if (!empty($_GET["graph_nolegend"])) {
	$graph_data_array["graph_nolegend"] = $_GET["graph_nolegend"];
}

if (!empty($_GET["showsource"])) {
	$graph_data_array["print_source"] = $_GET["showsource"];
}

print rrdtool_function_graph($_GET["local_graph_id"], $_GET["rra_id"], $graph_data_array);

?>


cacti_dir/include/rrd_function.php
<?php
/*
 +-------------------------------------------------------------------------+
 | Copyright (C) 2003 Ian Berry                                            |
 |                                                                         |
 | This program is free software; you can redistribute it and/or           |
 | modify it under the terms of the GNU General Public License             |
 | as published by the Free Software Foundation; either version 2          |
 | of the License, or (at your option) any later version.                  |
 |                                                                         |
 | This program is distributed in the hope that it will be useful,         |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
 | GNU General Public License for more details.                            |
 +-------------------------------------------------------------------------+
 | cacti: a php-based graphing solution                                    |
 +-------------------------------------------------------------------------+
 | Most of this code has been designed, written and is maintained by       |
 | Ian Berry. See about.php for specific developer credit. Any questions   |
 | or comments regarding this code should be directed to:                  |
 | - iberry@raxnet.net                                                     |
 +-------------------------------------------------------------------------+
 | - raXnet - http://www.raxnet.net/                                       |
 +-------------------------------------------------------------------------+
*/

define("RRD_NL", " \\\n");

function escape_command($command) {
	return ereg_replace("(\\\$|`)", "", $command);
}

function rrdtool_execute($command_line, $log_command, $output_flag) {
	include ('config.php');
	include_once ('functions.php');
	
	if ($log_command == true) {
		LogData("CMD: " . read_config_option("path_rrdtool") . " $command_line");
	}
	
	if ($output_flag == "") { $output_flag = "1"; }
	
	/* WIN32: before sending this command off to rrdtool, get rid
	of all of the '\' characters. Unix does not care; win32 does. 
	Also make sure to replace all of the fancy \'s at the end of the line,
	but make sure not to get rid of the "\n"'s that are supposed to be
	in there (text format) */
	$command_line = str_replace("\\\n", " ", $command_line);
	
	/* if we want to see the error output from rrdtool; make sure to specify this */
	if ($output_flag == "2") {
		$command_line .= " 2>&1";
	}
	
	/* use popen to eliminate the zombie issue */
	if ($config["cacti_server_os"] == "unix") {
		$fp = popen(read_config_option("path_rrdtool") . escape_command(" $command_line"), "r");
	}elseif ($config["cacti_server_os"] == "win32") {
		$fp = popen(read_config_option("path_rrdtool") . escape_command(" $command_line"), "rb");
	}
	
	/* Return Flag:
	0: Null
	1: Pass output back
	2: Pass error output back */
	
	switch ($output_flag) {
		case '0':
			return; break;
		case '1':
			return fpassthru($fp); break;
		case '2':
			$output = fgets($fp, 1000000);
			
			if (substr($output, 0, 4) == "‰PNG") {
				return "OK";
			}
			
			if (substr($output, 0, 5) == "GIF87") {
				return "OK";
			}
			
			print $output;
			break;
	}
}

function rrdtool_function_create($local_data_id, $show_source) {
	include_once ("functions.php");
	include ("config_arrays.php");
	
	$data_source_path = get_data_source_path($local_data_id, true);
	
	/* ok, if that passes lets check to make sure an rra does not already
	exist, the last thing we want to do is overright data! */
	if ($show_source != true) {
		if (file_exists($data_source_path) == true) {
			return -1;
		}
	}
	
	/* the first thing we must do is make sure there is at least one
	rra associated with this data source... * 
	UPDATE: As of version 0.6.6, we are splitting this up into two
	SQL strings because of the multiple DS per RRD support. This is 
	not a big deal however since this function gets called once per
	data source */
	
	$rras = db_fetch_assoc("select 
		data_template_data.rrd_step,
		rra.x_files_factor,
		rra.steps,
		rra.rows,
		rra_cf.consolidation_function_id,
		(rra.rows*rra.steps) as rra_order
		from data_template_data
		left join data_template_data_rra on data_template_data.id=data_template_data_rra.data_template_data_id
		left join rra on data_template_data_rra.rra_id=rra.id
		left join rra_cf on rra.id=rra_cf.rra_id
		where data_template_data.local_data_id=$local_data_id
		order by rra_cf.consolidation_function_id,rra_order");
	
	/* if we find that this DS has no RRA associated; get out */
	if (sizeof($rras) <= 0) {
		LogData("There are no RRA's assigned to local_data_id: $local_data_id!");
		return -1;
	}
	
	/* create the "--step" line */
	$create_ds = RRD_NL . "--step ". $rras[0]["rrd_step"] . " " . RRD_NL;
	
	/* query the data sources to be used in this .rrd file */
	$data_sources = db_fetch_assoc("select
		data_template_rrd.id,
		data_template_rrd.rrd_heartbeat,
		data_template_rrd.rrd_minimum,
		data_template_rrd.rrd_maximum,
		data_template_rrd.data_source_type_id
		from data_template_rrd
		where data_template_rrd.local_data_id=$local_data_id");
	
	/* ONLY make a new DS entry if:
	- There is multiple data sources and this item is not the main one.
	- There is only one data source (then use it) */
	
	if (sizeof($data_sources) > 0) {
	foreach ($data_sources as $data_source) {
		/* use the cacti ds name by default or the user defined one, if entered */
		$data_source_name = get_data_source_name($data_source["id"]);
	
		$create_ds .= "DS:$data_source_name:" . $data_source_types{$data_source["data_source_type_id"]} . ":" . $data_source["rrd_heartbeat"] . ":" . $data_source["rrd_minimum"] . ":" . $data_source["rrd_maximum"] . RRD_NL;
	}
	}
	
	$create_rra = "";
	/* loop through each available RRA for this DS */
	foreach ($rras as $rra) {
		$create_rra .= "RRA:" . $consolidation_functions{$rra["consolidation_function_id"]} . ":" . $rra["x_files_factor"] . ":" . $rra["steps"] . ":" . $rra["rows"] . RRD_NL;
	}
	
	if ($show_source == true) {
		return read_config_option("path_rrdtool") . " create" . RRD_NL . "$data_source_path$create_ds$create_rra";
	}else{
		if (read_config_option("log_create") == "on") { $log_data = true; }
		rrdtool_execute("create $data_source_path $create_ds$create_rra",$log_data,1);
	}
}

function rrdtool_function_update($update_cache_array) {
	include_once ("functions.php");
	
	while (list($local_data_id, $update_array) = each($update_cache_array)) {
		$data_source_path = get_data_source_path($local_data_id, true);
		
		$i = 0; $rrd_update_template = ""; $rrd_update_values = "";
		while (list($field_name, $field_value) = each($update_array)) {
			$rrd_update_template .= $field_name;
			$rrd_update_values .= $field_value;
			
			if (($i+1) < count($update_array)) {
				$rrd_update_template .= ":";
				$rrd_update_values .= ":";
			}
			
			$i++;
		}
		
		if (read_config_option("log_update") == "on") {
			$log_data = true;
		}else{
			$log_data = false;
		}
		
		/* if we have "invalid data", give rrdtool an Unknown (U) */
		if ($rrd_update_values == "") {
			$rrd_update_values = "U";
		}
		
		print "update $data_source_path --template $rrd_update_template N:$rrd_update_values\n";
		rrdtool_execute("update $data_source_path --template $rrd_update_template N:$rrd_update_values",$log_data,1);
	}
}

function rrdtool_function_tune($rrd_tune_array) {
	include_once ('functions.php');
	include ('config_arrays.php');
	
	$data_source_name = get_data_source_name($rrd_tune_array["data_source_id"]);
	$data_source_type = $data_source_types{$rrd_tune_array["data-source-type"]};
	$data_source_path = get_data_source_path($rrd_tune_array["data_source_id"], true);
	
	if ($rrd_tune_array["heartbeat"] != "") {
		$rrd_tune .= " --heartbeat $data_source_name:" . $rrd_tune_array["heartbeat"];
	}
	
	if ($rrd_tune_array["minimum"] != "") {
		$rrd_tune .= " --minimum $data_source_name:" . $rrd_tune_array["minimum"];
	}
	
	if ($rrd_tune_array["maximum"] != "") {
		$rrd_tune .= " --maximum $data_source_name:" . $rrd_tune_array["maximum"];
	}
	
	if ($rrd_tune_array["data-source-type"] != "") {
		$rrd_tune .= " --data-source-type $data_source_name:" . $data_source_type;
	}
	
	if ($rrd_tune_array["data-source-rename"] != "") {
		$rrd_tune .= " --data-source-rename $data_source_name:" . $rrd_tune_array["data-source-rename"];
	}
	
	if ($rrd_tune != "") {
		if (file_exists($data_source_path) == true) {
			$fp = popen(read_config_option("path_rrdtool") . " tune $data_source_path $rrd_tune", "r");
			pclose($fp);
			
			LogData("CMD: " . read_config_option("path_rrdtool") . " tune $data_source_path $rrd_tune");
		}
	}
}

function rrdtool_function_graph($local_graph_id, $rra_id, $graph_data_array) {
	include_once ("functions.php");
	include_once ("cdef_functions.php");
	include ("config_arrays.php");
	
	/* before we do anything; make sure the user has permission to view this graph,
	if not then get out */
	if (read_config_option("global_auth") == "on") {
		$user_auth = db_fetch_row("select user_id from user_auth_graph where local_graph_id=$local_graph_id and user_id=" . $_SESSION["sess_user_id"]);
		$current_user = db_fetch_row("select * from user where id=" . $_SESSION["sess_user_id"]);
		
		$access_denied = false;
		
		if ($current_user["graph_policy"] == "1") {
			if (sizeof($user_auth) > 0) { $access_denied = true; }
		}elseif ($current_user["graph_policy"] == "2") {
			if (sizeof($user_auth) == 0) { $access_denied = true; }
		}
		
		if ($access_denied == true) {
			return "GRAPH ACCESS DENIED";
		}
	}
	
	/* define the time span, which decides which rra to use */
	$rra = db_fetch_row("select rows,steps from rra where id=$rra_id");
	
        switch ($rra_id) {
                case 1 : $timespan = - 3600 * 24; break;
                case 2 : $timespan = - 3600 * 24 * 7; break;
                case 3 : $timespan = - 3600 * 24 * 34; break;
                case 4 : $timespan = - 3600 * 24 * 365; break;
        }
	
	$graph = db_fetch_row("select
		graph_templates_graph.title,
		graph_templates_graph.vertical_label,
		graph_templates_graph.auto_scale,
		graph_templates_graph.auto_scale_opts,
		graph_templates_graph.auto_scale_log,
		graph_templates_graph.auto_scale_rigid,
		graph_templates_graph.auto_padding,
		graph_templates_graph.base_value,
		graph_templates_graph.upper_limit,
		graph_templates_graph.lower_limit,
		graph_templates_graph.height,
		graph_templates_graph.width,
		graph_templates_graph.image_format_id,
		graph_templates_graph.unit_value,
		graph_templates_graph.unit_exponent_value,
		graph_templates_graph.export
		from graph_templates_graph
		where graph_templates_graph.local_graph_id=$local_graph_id");
	
    	/* lets make that sql query... */
    	$graph_items = db_fetch_assoc("select
		graph_templates_item.id as graph_templates_item_id,
		graph_templates_item.cdef_id,
		graph_templates_item.text_format,
		graph_templates_item.value,
		graph_templates_item.hard_return,
		graph_templates_item.consolidation_function_id,
		graph_templates_item.graph_type_id,
		graph_templates_gprint.gprint_text,
		colors.hex,
		data_template_rrd.id as data_template_rrd_id,
		data_template_rrd.local_data_id,
		data_template_rrd.data_source_name
		from graph_templates_item
		left join data_template_rrd on graph_templates_item.task_item_id=data_template_rrd.id
		left join colors on graph_templates_item.color_id=colors.id
		left join graph_templates_gprint on graph_templates_item.gprint_id=graph_templates_gprint.id
		where graph_templates_item.local_graph_id=$local_graph_id
		order by graph_templates_item.sequence");
	
  	/* +++++++++++++++++++++++ GRAPH OPTIONS +++++++++++++++++++++++ */
	
	/* define some variables */
	$scale = "";
	$rigid = "";
	$graph_legend = "";
	$graph_defs = "";
	$txt_graph_items = "";
	$text_padding = "";
	
    	if ($graph["auto_scale"] == "on") {
		if ($graph["auto_scale_opts"] == "1") {
			$scale = "--alt-autoscale" . RRD_NL;
		}elseif ($graph["auto_scale_opts"] == "2") {
			$scale = "--alt-autoscale-max" . RRD_NL;
			$scale .= "--lower-limit=" . $graph["lower_limit"] . RRD_NL; 
		}
		
		if ($graph["auto_scale_log"] == "on") {
			$scale .= "--logarithmic" . RRD_NL;
		}
	}else{
		$scale =  "--upper-limit=" . $graph["upper_limit"] . RRD_NL;
		$scale .= "--lower-limit=" . $graph["lower_limit"] . RRD_NL;
	}
	
	if ($graph["auto_scale_rigid"] == "on") {
		$rigid = "--rigid" . RRD_NL;
	}
	
	if (!empty($graph["unit_value"])) {
		$unit_value = "--unit=" . $graph["unit_value"] . RRD_NL;
	}
	
	if (!empty($graph["unit_exponent_value"])) {
		$unit_exponent_value = "--units-exponent=" . $graph["unit_exponent_value"] . RRD_NL;
	}
	
	/* optionally you can specify and array that overrides some of the db's
	values, lets set that all up here */
	if (isset($graph_data_array["use"])) {
		if ($graph_data_array["graph_start"] == "0") {
			$graph_start = $timespan;
		}else{
			$graph_start = $graph_data_array["graph_start"];
			if ($graph_data_array["graph_end"] != "") {
                        	$graph_end = $graph_data_array["graph_end"];
                	}
                	else {
                        	$graph_end = time();
                	}
		}
		
		$graph_height = $graph_data_array["graph_height"];
		$graph_width = $graph_data_array["graph_width"];
	}else{
		$graph_start = $timespan;
                $graph_end = time();
		$graph_height = $graph["height"];
		$graph_width = $graph["width"];
	}
	
	if (isset($graph_data_array["graph_nolegend"])) {
		$graph_legend = "--no-legend" . RRD_NL;
	}else{
		$graph_legend = "";
	}
    
	/* export options */
	if (isset($graph_data_array["export"])) {
		$graph_opts = read_config_option("path_html_export") . "/" . $graph_data_array["export_filename"] . RRD_NL;
	}else{
		if (empty($graph_data_array["output_filename"])) {
	    		$graph_opts = "-" . RRD_NL;
		}else{
			$graph_opts = $graph_data_array["output_filename"] . RRD_NL;
		}
	}
    
	/* basic graph options */
	$graph_opts .= 
		"--imgformat=" . $image_types{$graph["image_format_id"]} . RRD_NL . 
		"--start=$graph_start" . RRD_NL .
                "--end=\"$graph_end\"" . " \\\n" . 
		"--title=\"" . get_graph_title($local_graph_id) . "\"" . RRD_NL .
		"$rigid" .
		"--base=" . $graph["base_value"] . RRD_NL .
		"--height=$graph_height" . RRD_NL .
		"--width=$graph_width" . RRD_NL .
		"$scale" .
		"$graph_legend" .
		"--vertical-label=\"" . $graph["vertical_label"] . "\"" . RRD_NL;
    	
	$i = 0;
    	if (sizeof($graph_items > 0)) {
	foreach ($graph_items as $graph_item) {
		if ((ereg("(AREA|STACK|LINE[123])", $graph_item_types{$graph_item["graph_type_id"]})) && (!empty($graph_item["data_source_name"]))) {
			$data_source_name = $graph_item["data_source_name"];
			
			/* use a user-specified ds path if one is entered */
			$data_source_path = get_data_source_path($graph_item["local_data_id"], true);
			
			/* FOR WIN32: Ecsape all colon for drive letters (ex. D\:/path/to/rra) */
			$data_source_path = str_replace(":", "\:", $data_source_path);
			
			/* NOTE: (Update) Data source DEF names are created using the graph_item_id; then passed
			to a function that matches the digits with letters. rrdtool likes letters instead
			of numbers in DEF names; especially with CDEF's. cdef's are created
			the same way, except a 'cdef' is put on the beginning of the hash */
			$graph_defs .= "DEF:" . generate_graph_def_name(("$i")) . "=\"$data_source_path\":$data_source_name:" . $consolidation_functions{$graph_item["consolidation_function_id"]} . RRD_NL;
			
			//print "ds: " . $graph_item["data_template_rrd_id"] . "<br>";
			$cf_ds_cache{$graph_item["data_template_rrd_id"]}{$graph_item["consolidation_function_id"]} = "$i";
			
			$i++;
		}
	}
	}
    
	/* if we are not displaying a legend there is no point in us even processing the auto padding,
	text format stuff. */
	if (!isset($graph_data_array["graph_nolegend"])) {
		/* use this loop to to setup all textformat data (hr, padding, subsitution, etc) */
		$greatest_text_format = 0;
		
		reset($graph_items);
		
		if (sizeof($graph_items) > 0) {
		foreach ($graph_items as $graph_item) {
			/* +++++++++++++++++++++++ LEGEND: TEXT SUBSITUTION (<>'s) +++++++++++++++++++++++ */
			
			/* note the current item_id for easy access */
			$graph_item_id = $graph_item["graph_templates_item_id"];
			
			/* format the textformat string, and add values where there are <>'s */
			$text_format[$graph_item_id] = $graph_item["text_format"];
			$value_format[$graph_item_id] = $graph_item["value"];
			
			/* set hard return variable if selected (\n) */
			if ($graph_item["hard_return"] == "on") { 
				$hardreturn[$graph_item_id] = "\\n"; 
			}else{
				$hardreturn[$graph_item_id] = "";
			}
	    		
			/* +++++++++++++++++++++++ LEGEND: AUTO PADDING (<>'s) +++++++++++++++++++++++ */
			
			/* PADDING: remember this is not perfect! its main use is for the basic graph setup of:
			AREA - GPRINT-CURRENT - GPRINT-AVERAGE - GPRINT-MAXIMUM \n
			of course it can be used in other situations, however may not work as intended.
			If you have any additions to this small peice of code, feel free to send them to me. */
			if ($graph["auto_padding"] == "on") {
				/* only applies to AREA and STACK */
				if (ereg("(AREA|STACK|LINE[123])", $graph_item_types{$graph_item["graph_type_id"]})) {
					$text_format_lengths{$graph_item["data_template_rrd_id"]} = strlen($text_format[$graph_item_id]);
					
					if ((strlen($text_format[$graph_item_id]) > $greatest_text_format) && ($graph_item_types{$graph_item["graph_type_id"]} != "COMMENT")) {
						$greatest_text_format = strlen($text_format[$graph_item_id]);
					}
				}
			}
		}
		}
    	}
	
    	/* +++++++++++++++++++++++ GRAPH ITEMS: CDEF's +++++++++++++++++++++++ */
    	
	$i = 0;
	reset($graph_items);
		
	if (sizeof($graph_items) > 0) {
	foreach ($graph_items as $graph_item) {
		/* CF rules: if we are using a CF because it's defined in the AREA, STACK, LINE[1-3] then
		it is ok to use it elsewhere on the graph. But it is not ok to use a CF DEF because
		its used in a GPRINT; so check that here */
		if ((isset($cf_ds_cache{$graph_item["data_template_rrd_id"]}{$graph_item["consolidation_function_id"]})) && ($graph_item_types{$graph_item["graph_type_id"]} != "GPRINT")) {
			$cf_id = $graph_item["consolidation_function_id"];
		}else{
			$cf_id = 1; /* CF: AVERAGE */
		}
		
		/* make cdef string here; a note about CDEF's in cacti. A CDEF is neither unique to a 
		data source of global cdef, but is unique when those two variables combine. */
		$cdef_graph_defs = ""; $cdef_total_ds = ""; $cdef_total = "";
		
		if ((!empty($graph_item["cdef_id"])) && (isset($cdef_cache{$graph_item["cdef_id"]}{$graph_item["data_template_rrd_id"]}) == false)) {
			$cdef_string = get_cdef($graph_item["cdef_id"]);
			
			/* create cdef string for "total all data sources" if requested */
			if (ereg("ALL_DATA_SOURCES_(NO)?DUPS", $cdef_string)) {
				$item_count = 0;
				for ($t=0;($t<count($graph_items));$t++) {
					if ((ereg("(AREA|STACK|LINE[123])", $graph_item_types{$graph_items[$t]["graph_type_id"]})) && (!empty($graph_items[$t]["data_template_rrd_id"]))) {
						/* if the user screws up CF settings, PHP will generate warnings if left unchecked */
						if (isset($cf_ds_cache{$graph_items[$t]["data_template_rrd_id"]}[$cf_id])) {
							$cdef_total_ds .= generate_graph_def_name($cf_ds_cache{$graph_items[$t]["data_template_rrd_id"]}[$cf_id]) . ",";
						}
						
						$item_count++;
					}
				}
				
				/* if there is only one item to total, don't even bother with the summation. otherwise
				cdef=a,b,c,+,+ is fine. */
				if ($item_count == 1) {
					$cdef_total = str_replace(",", "", $cdef_total_ds);
				}else{
					$cdef_total = $cdef_total_ds . str_repeat("+,", ($item_count - 2)) . "+";
				}
			}
			
			$cdef_string = str_replace("CURRENT_DATA_SOURCE", generate_graph_def_name((isset($cf_ds_cache{$graph_item["data_template_rrd_id"]}[$cf_id]) ? $cf_ds_cache{$graph_item["data_template_rrd_id"]}[$cf_id] : "0")), $cdef_string);
			$cdef_string = str_replace("ALL_DATA_SOURCES_NODUPS", $cdef_total, $cdef_string);
			
			/* make the initial "virtual" cdef name: 'cdef' + [a,b,c,d...] */
			$cdef_graph_defs .= "CDEF:cdef" . generate_graph_def_name("$i") . "=";
			$cdef_graph_defs .= $cdef_string;
			$cdef_graph_defs .= " \\\n";
			
			/* the CDEF cache is so we do not create duplicate CDEF's on a graph */
			$cdef_cache{$graph_item["cdef_id"]}{$graph_item["data_template_rrd_id"]} = "$i";
		}
		
		/* add the cdef string to the end of the def string */
		$graph_defs .= $cdef_graph_defs;
		
		/* note the current item_id for easy access */
		$graph_item_id = $graph_item["graph_templates_item_id"];
		
		/* if we are not displaying a legend there is no point in us even processing the auto padding,
		text format stuff. */
		if ((!isset($graph_data_array["graph_nolegend"])) && ($graph["auto_padding"] == "on")) {
			/* we are basing how much to pad on area and stack text format, 
			not gprint. but of course the padding has to be displayed in gprint,
			how fun! */
			
			$pad_number = ($greatest_text_format - $text_format_lengths{$graph_item["data_template_rrd_id"]});
			//LogData("MAX: $greatest_text_format, CURR: $text_format_lengths[$item_dsid], DSID: $item_dsid");
			$text_padding = str_pad("", $pad_number);
			
			/* two GPRINT's in a row screws up the padding, lets not do that */
			if (($graph_item_types{$graph_item["graph_type_id"]} == "GPRINT") && ($last_graph_type == "GPRINT")) {
				$text_padding = "";
			}
			
			$last_graph_type = $graph_item_types{$graph_item["graph_type_id"]};
		}
		
	
		/* we put this in a variable so it can be manipulated before mainly used
		if we want to skip it, like below */
		$current_graph_item_type = $graph_item_types{$graph_item["graph_type_id"]};
		
		/* IF this graph item has a data source... get a DEF name for it, or the cdef if that applies
		to this graph item */
		if ($graph_item["cdef_id"] == "0") {
			if (isset($cf_ds_cache{$graph_item["data_template_rrd_id"]}[$cf_id])) {
				$data_source_name = generate_graph_def_name($cf_ds_cache{$graph_item["data_template_rrd_id"]}[$cf_id]);
			}else{
				$data_source_name = "";
			}
		}else{
			$data_source_name = "cdef" . generate_graph_def_name($cdef_cache{$graph_item["cdef_id"]}{$graph_item["data_template_rrd_id"]});
		}
		
		/* to make things easier... if there is no text format set; set blank text */
		if (!isset($text_format[$graph_item_id])) {
			$text_format[$graph_item_id] = "";
		}
		
		if (!isset($hardreturn[$graph_item_id])) {
			$hardreturn[$graph_item_id] = "";
		}
		
		/* +++++++++++++++++++++++ GRAPH ITEMS +++++++++++++++++++++++ */
		
		/* this switch statement is basically used to grab all of the graph data above and
		print it out in an rrdtool-friendly fashion, not too much calculation done here. */
		
		switch ($graph_item_types{$graph_item["graph_type_id"]}) {
		case 'AREA':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" . 
			"\"$text_format[$graph_item_id]$hardreturn[$graph_item_id]\" ";
			break;
		case 'STACK':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" .
			"\"$text_format[$graph_item_id]$hardreturn[$graph_item_id]\" ";
			break;
		case 'LINE1':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" . 
			"\"$text_format[$graph_item_id]$hardreturn[$graph_item_id]\" ";
			break;
		case 'LINE2':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" . 
			"\"$text_format[$graph_item_id]$hardreturn[$graph_item_id]\" ";
			break;
		case 'LINE3':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" . 
			"\"$text_format[$graph_item_id]$hardreturn[$graph_item_id]\" ";
			break;
		case 'COMMENT':
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":\"" .
			"$text_format[$graph_item_id]$hardreturn[$graph_item_id]\" ";
			break;
		case 'GPRINT':
			if (!isset($graph_data_array["graph_nolegend"])) {
				$gprint_text = $graph_item["gprint_text"];
				
				$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
				$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" .
				$data_source_name . ":" . $consolidation_functions{$graph_item["consolidation_function_id"]} .
				":\"$text_padding$text_format[$graph_item_id]$gprint_text$hardreturn[$graph_item_id]\" ";
			}
			
			break;
		case 'HRULE':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			
			if ($graph_data_array["graph_nolegend"] == true) {
				$value_format[$graph_item_id] = "0";
			}else{
				$value_format[$graph_item_id] = str_replace(":", "\:" ,$value_format[$graph_item_id]); /* escape colons */
			}
			
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" .
			$value_format[$graph_item_id] . "#" . $graph_item["hex"] . ":\"" . 
			"$text_format[$graph_item_id]$hardreturn[$graph_item_id]\" ";
			break;
		case 'VRULE':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			
			$value_array = explode(":", $graph_item["value"]);
			$value = date("U", mktime($value_array[0],$value_array[1],0));
			
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" .
			$value . "#" . $graph_item["hex"] . ":\"" . 
			"$text_format[$graph_item_id]$hardreturn[$graph_item_id]\" ";
			break;
		}
		
		$i++;
		
		if ($i < sizeof($graph_items)) {
			$txt_graph_items .= RRD_NL;
		}
	}
	}
    
	/* either print out the source or pass the source onto rrdtool to get us a nice PNG */
	if (isset($graph_data_array["print_source"])) {
		print "<PRE>" . read_config_option("path_rrdtool") . " graph $graph_opts$graph_defs$txt_graph_items</PRE>";
	}else{
		if (isset($graph_data_array["export"])) {
			rrdtool_execute("graph $graph_opts$graph_defs$graph_items", false, "0");
			return 0;
		}else{
			$log_data = false;
			if (read_config_option("log_graph") == "on") { $log_data = true; }
			if (!isset($graph_data_array["output_flag"])) { $graph_data_array["output_flag"] = 1; }
			
			return rrdtool_execute("graph $graph_opts$graph_defs$txt_graph_items",$log_data,$graph_data_array["output_flag"]);
		}
	}
}

?>
wesphillips
Posts: 21
Joined: Tue May 28, 2002 8:59 am

Permissions

Post by wesphillips »

I tried putting this code into the 0.8-pre20030417 version and it stopped displaying graphs. I had to run the following SQL code to add the zoom_graph.php filename to the permissions table as follows:

Code: Select all

INSERT INTO user_realm_filename VALUES ('7', 'zoom_graph.php')
This fixed the "Access Denied" when you click on the [zoom] feature, but I still get no graphs in the tree and preview modes. I get the graphs correctly when I click on the box with the red X int the upper left corner, though. The zoom feature seems to work great as well.
wesphillips
Posts: 21
Joined: Tue May 28, 2002 8:59 am

Post by wesphillips »

Found the problem. In graph_view.php you have to edit line 261 as follows

Old Code:

Code: Select all

print "<td align='center' width='" . (98 / read_graph_config_option("num_columns")) . "%'><a href='graph.php?rra_id=all&local_graph_id=" . $graph["local_graph_id"] . "'><img src='graph_image.php?local_graph_id=" . $graph["local_graph_id"] . "&rra_id=" . (empty($set_rra_id) ? read_graph_config_option("default_rra_id") : $set_rra_id) . "&graph_start=-" . (empty($set_rra_id) ? read_graph_config_option("timespan") : "0") . "&graph_height=" . read_graph_config_option("default_height") . "&graph_width=" . read_graph_config_option("default_width") . "&graph_nolegend=true' border='0' alt='" . $graph["title"] . "'></a></td>\n";
New Code:

Code: Select all

print "<td align='center' width='" . (98 / read_graph_config_option("num_columns")) . "%'><a href='graph.php?rra_id=all&local_graph_id=" . $graph["local_graph_id"] . "'><img src='graph_image.php?local_graph_id=" . $graph["local_graph_id"] . "&rra_id=" . (empty($set_rra_id) ? read_graph_config_option("default_rra_id") : $set_rra_id) . "&graph_start=-" . (empty($set_rra_id) ? read_graph_config_option("timespan") : "0") . "&graph_end=" . time() . "&graph_height=" . read_graph_config_option("default_height") . "&graph_width=" . read_graph_config_option("default_width") . "&graph_nolegend=true' border='0' alt='" . $graph["title"] . "'></a></td>\n";
You also have to edit the tree_view_functions.php in the ./include directory line 210 as follows

Old Code:

Code: Select all

src='graph_image.php?local_graph_id=" . $leaf["local_graph_id"] . "&rra_id=" . read_graph_config_option("default_rra_id") . "&graph_start=-" . read_graph_config_option("timespan") . '&graph_height=' .
New Code:

Code: Select all

src='graph_image.php?local_graph_id=" . $leaf["local_graph_id"] . "&rra_id=" . read_graph_config_option("default_rra_id") . "&graph_start=-" . read_graph_config_option("timespan") . '&graph_end=' . time() . '&graph_height=' .
In both cases, the change was " '&graph_end=' . time() ."

NOTE: line #210 in tree_view_functions.php is a partial line. The line before it and the line after it all are one actual line of PHP code.
Bruno Prigent

Post by Bruno Prigent »

I think the line 374 in graph_view.php is doing he same job.
If there is a graph_end specified int the url, the use it. Else use time().
Thanks for the add of the SQL query
Bruno Prigent
Cacti User
Posts: 68
Joined: Tue Apr 22, 2003 5:51 am

Re: Cool zoom/history feature for cacti :)

Post by Bruno Prigent »

Bruno Prigent wrote:Hi

I wrote a few lines in order to add a zoom in cacti. It's usefull to see what append a month ago, just change the number of row in the daily rra (17280 is the value I use). I based my developpement on cacti-0.8-pre20030415.tar.gz.

I think decompress the archive in cacti dir should work. Click on a graph and select zoom.

Don't hesitate to send comments.

Bruno.

Here is the code :
cacti_dir/zoom_graph.php (new file) :

Code: Select all

<?php
/*
 This file is based on graph.php
*/

include_once ("include/rrd_functions.php");
include_once ("include/functions.php");
include_once ("include/form.php");
include ("include/top_graph_header.php");

if ($_GET["rra_id"] == "all") {
	$sql_where = " where id is not null";
}else{
	$sql_where = " where id=" . $_GET["rra_id"];
}

/* take graph permissions into account here, if the user does not have permission
give an "access denied" message */
if (read_config_option("global_auth") == "on") {
	$user_auth = db_fetch_row("select user_id from user_auth_graph where local_graph_id=" . $_GET["local_graph_id"] . " and user_id=" . $_SESSION["sess_user_id"]);
	
	$access_denied = false;
	
	if ($current_user["graph_policy"] == "1") {
		if (sizeof($user_auth) > 0) { $access_denied = true; }
	}elseif ($current_user["graph_policy"] == "2") {
		if (sizeof($user_auth) == 0) { $access_denied = true; }
	}
	
	if ($access_denied == true) {
		print "<strong><font size='+1' color='FF0000'>ACCESS DENIED</font></strong>"; exit;
	}
}

/* make sure the graph requested exists (sanity) */
if (!(db_fetch_cell("select local_graph_id from graph_templates_graph where local_graph_id=" . $_GET["local_graph_id"]))) {
	print "<strong><font size='+1' color='FF0000'>GRAPH DOES NOT EXIST</font></strong>"; exit;
}
$graph_param = "";

if ($start_year != "") {
        $graph_param .= "&graph_start=".mktime($start_hour, $start_min, $start_sec, $start_month, $start_day, $start_year)."&graph_end=".mktime($end_hour, $end_min, $end_sec, $end_month, $end_day, $end_year)."&graph_height=$graph_height"."&graph_width=$graph_width";
}
else {
        $start_year = date("Y");
        $start_month = date("m");
        $start_day = date("d", strtotime("-1 day"));
        $start_hour = date("H");
        $start_min = date("i");
        $start_sec = date("s");
        $end_year = date("Y");
        $end_month = date("m");
        $end_day = date("d");
        $end_hour = date("H");
        $end_min = date("i");
        $end_sec = date("s");
        $graph_height = 192;
        $graph_width = 800;
}

$graph_title = get_graph_title($_GET["local_graph_id"]);

print "<table width='98%' style='background-color: #f5f5f5; border: 1px solid #bbbbbb;' align='center' cellpadding='3'>";
print "<tr bgcolor='#" . $colors["header_panel"] . "'><td colspan='3' class='textHeaderDark'><strong>Viewing Graph '$graph_title'</strong></td></tr>";

	print "<tr><td>";
	
	print " <div align='center'><img src='graph_image.php?local_graph_id=" . $_GET["local_graph_id"] . "&rra_id=" . $rra_id . $graph_param . "' border='0' alt='$graph_title'></div>\n";
	print "</td></tr>";
	

print "</table>";
print "<br><br>";

print "<table width='98%' style='background-color: #f5f5f5; border: 1px solid #bbbbbb;' align='center' cellpadding='3'>";
	print "<tr bgcolor='#" . $colors["header"] . "'><td colspan='3' class='textHeaderDark'><strong>Zoom parameters</strong></td></tr>";
	print "<tr><td>";

	print "<form method='post'>";
        start_box("Start graph at", "100%", $colors["header_panel"],"3", "center","");
        print "<tr><td>&&&<select name='start_year'>";
        for ($i=$start_year-2 ; $i<=$end_year+2 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_year) {?> selected<?}?>><?printf("%04d", $i);?></option>
<?      } 
        print "</select> / ";
        print "<select name='start_month'>";

        for ($i=1 ; $i<=12 ; $i++)
        {
                ?> <option value="<?print $i;?>"<?if ($i==$start_month) {?> selected<?}?>><?print date("M", mktime($start_hour, $start_min, $start_sec, $i, $start_day, $start_year));?></option>
<?      } 
        print "</select> / ";
        print "<select name='start_day'>";

        for ($i=1 ; $i<=31 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_day) {?> selected<?}?>><?printf("%02d", $i);?></option>

<?      } 
        print "</select> at ";
        print "<select name='start_hour'>";

        for ($i=0 ; $i<=23 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_hour) {?> selected<?}?>><?printf("%02d", $i);?></option>

<?      } 
        print "</select> H ";
        print "<select name='start_min'>";

        for ($i=0 ; $i<=59 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_min) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> m ";
        print "<select name='start_sec'>";

        for ($i=0 ; $i<=59 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$start_sec) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> sec";
        print "</td></tr>";

	end_box();

        start_box("End graph at", "100%", $colors["header_panel"],"3", "center","");
        print "<tr><td>&&&<select name='end_year'>";

        for ($i=$start_year-2 ; $i<=$end_year+2 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_year) {?> selected<?}?>><?printf("%04d", $i);?></option>
<?      } 
        print "</select> / ";
        print "<select name='end_month'>";

        for ($i=1 ; $i<=12 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_month) {?> selected<?}?>><?print date("M", mktime($end_hour, $end_min, $end_sec, $i, $end_day, $end_year));?></option>
<?      } 
        print "</select> / ";
        print "<select name='end_day'>";

        for ($i=1 ; $i<=31 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_day) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> at ";
        print "<select name='end_hour'>";

        for ($i=0 ; $i<=23 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_hour) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> H ";
        print "<select name='end_min'>";

        for ($i=0 ; $i<=59 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_min) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> m ";
        print "<select name='end_sec'>";

        for ($i=0 ; $i<=59 ; $i++)
        {
                ?><option value="<?print $i;?>"<?if ($i==$end_sec) {?> selected<?}?>><?printf("%02d", $i);?></option>
<?      } 
        print "</select> sec";
        print "</td></tr>";
	end_box();

	start_box("Width", "100%", $colors["header_panel"],"3", "center","");
        print "<tr><td><input type='text' name='graph_width' size='20' value='" . $graph_width . "'></td></tr>";
	end_box();

	start_box("Height", "100%", $colors["header_panel"],"3", "center","");
        print "<tr><td><input type='text' name='graph_height' size='20' value='" . $graph_height . "'></td></tr>";
	end_box();
	print "<input type='image' src='images/button_view.gif' alt='Go' border='0' align='absm iddle' action='submit'>";
	print "</td></tr>";
	print "</table>";	
	print "</form>";
include_once ("include/bottom_footer.php");

?>


cacti_dir/graph.php :
<?php
/*
 +-------------------------------------------------------------------------+
 | Copyright (C) 2003 Ian Berry                                            |
 |                                                                         |
 | This program is free software; you can redistribute it and/or           |
 | modify it under the terms of the GNU General Public License             |
 | as published by the Free Software Foundation; either version 2          |
 | of the License, or (at your option) any later version.                  |
 |                                                                         |
 | This program is distributed in the hope that it will be useful,         |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
 | GNU General Public License for more details.                            |
 +-------------------------------------------------------------------------+
 | cacti: a php-based graphing solution                                    |
 +-------------------------------------------------------------------------+
 | Most of this code has been designed, written and is maintained by       |
 | Ian Berry. See about.php for specific developer credit. Any questions   |
 | or comments regarding this code should be directed to:                  |
 | - iberry@raxnet.net                                                     |
 +-------------------------------------------------------------------------+
 | - raXnet - http://www.raxnet.net/                                       |
 +-------------------------------------------------------------------------+
*/

include_once ("include/rrd_functions.php");
include_once ("include/functions.php");
include ("include/top_graph_header.php");

if ($_GET["rra_id"] == "all") {
	$sql_where = " where id is not null";
}else{
	$sql_where = " where id=" . $_GET["rra_id"];
}

/* take graph permissions into account here, if the user does not have permission
give an "access denied" message */
if (read_config_option("global_auth") == "on") {
	$user_auth = db_fetch_row("select user_id from user_auth_graph where local_graph_id=" . $_GET["local_graph_id"] . " and user_id=" . $_SESSION["sess_user_id"]);
	
	$access_denied = false;
	
	if ($current_user["graph_policy"] == "1") {
		if (sizeof($user_auth) > 0) { $access_denied = true; }
	}elseif ($current_user["graph_policy"] == "2") {
		if (sizeof($user_auth) == 0) { $access_denied = true; }
	}
	
	if ($access_denied == true) {
		print "<strong><font size='+1' color='FF0000'>ACCESS DENIED</font></strong>"; exit;
	}
}

/* make sure the graph requested exists (sanity) */
if (!(db_fetch_cell("select local_graph_id from graph_templates_graph where local_graph_id=" . $_GET["local_graph_id"]))) {
	print "<strong><font size='+1' color='FF0000'>GRAPH DOES NOT EXIST</font></strong>"; exit;
}

$rras = db_fetch_assoc("select id,name from rra $sql_where order by steps");

$graph_title = get_graph_title($_GET["local_graph_id"]);

print "<table width='98%' style='background-color: #f5f5f5; border: 1px solid #bbbbbb;' align='center' cellpadding='3'>";
print "<tr bgcolor='#" . $colors["header_panel"] . "'><td colspan='3' class='textHeaderDark'><strong>Viewing Graph '$graph_title'</strong></td></tr>";

$i = 0;
if (sizeof($rras) > 0) {
foreach ($rras as $rra) {
	print "<tr><td>";
	
	print "	<div align='center'><img src='graph_image.php?local_graph_id=" . $_GET["local_graph_id"] . "&rra_id=" . $rra["id"] . "' border='0' alt='$graph_title'></div>\n
                <div align='center'><strong>" . $rra["name"] . "</strong> [<a href='graph.php?local_graph_id=" . $_GET["local_graph_id"] . "&rra_id=" . $rra["id"] . "&show_source=true'>source</a>][<a href='zoom_graph.php?local_graph_id=" . $_GET["local_graph_id"]. "&rra_id=" . $rra["id"] . "'>zoom</a>]</div><br>\n";	
	print "</td></tr>";
	
	$i++;
}
}

print "</table>";
print "<br><br>";

include_once ("include/bottom_footer.php");

?>


cacti_dir/graph_image.php
<?php
/*
 +-------------------------------------------------------------------------+
 | Copyright (C) 2003 Ian Berry                                            |
 |                                                                         |
 | This program is free software; you can redistribute it and/or           |
 | modify it under the terms of the GNU General Public License             |
 | as published by the Free Software Foundation; either version 2          |
 | of the License, or (at your option) any later version.                  |
 |                                                                         |
 | This program is distributed in the hope that it will be useful,         |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
 | GNU General Public License for more details.                            |
 +-------------------------------------------------------------------------+
 | cacti: a php-based graphing solution                                    |
 +-------------------------------------------------------------------------+
 | Most of this code has been designed, written and is maintained by       |
 | Ian Berry. See about.php for specific developer credit. Any questions   |
 | or comments regarding this code should be directed to:                  |
 | - iberry@raxnet.net                                                     |
 +-------------------------------------------------------------------------+
 | - raXnet - http://www.raxnet.net/                                       |
 +-------------------------------------------------------------------------+
*/

/* since we'll have addition headers, tell php when to flush them */
ob_start();

$guest_account = true; include ('include/auth.php');
include_once ("include/rrd_functions.php");

header("Content-type: image/png");

/* flush the headers now */
ob_end_flush();

$graph_data_array = array();

/* check to see if there are user specified vars */
if (!empty($_GET["graph_start"])) {
	$graph_data_array["use"] = true;
	$graph_data_array["graph_start"] = $_GET["graph_start"];
        if ($graph_end !="") { $graph_data_array["graph_end"] = $graph_end;}
	$graph_data_array["graph_height"] = $_GET["graph_height"];
	$graph_data_array["graph_width"] = $_GET["graph_width"];
}

/* treat the legend separatly */
if (!empty($_GET["graph_nolegend"])) {
	$graph_data_array["graph_nolegend"] = $_GET["graph_nolegend"];
}

if (!empty($_GET["showsource"])) {
	$graph_data_array["print_source"] = $_GET["showsource"];
}

print rrdtool_function_graph($_GET["local_graph_id"], $_GET["rra_id"], $graph_data_array);

?>


cacti_dir/include/rrd_function.php
<?php
/*
 +-------------------------------------------------------------------------+
 | Copyright (C) 2003 Ian Berry                                            |
 |                                                                         |
 | This program is free software; you can redistribute it and/or           |
 | modify it under the terms of the GNU General Public License             |
 | as published by the Free Software Foundation; either version 2          |
 | of the License, or (at your option) any later version.                  |
 |                                                                         |
 | This program is distributed in the hope that it will be useful,         |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
 | GNU General Public License for more details.                            |
 +-------------------------------------------------------------------------+
 | cacti: a php-based graphing solution                                    |
 +-------------------------------------------------------------------------+
 | Most of this code has been designed, written and is maintained by       |
 | Ian Berry. See about.php for specific developer credit. Any questions   |
 | or comments regarding this code should be directed to:                  |
 | - iberry@raxnet.net                                                     |
 +-------------------------------------------------------------------------+
 | - raXnet - http://www.raxnet.net/                                       |
 +-------------------------------------------------------------------------+
*/

define("RRD_NL", " \\\n");

function escape_command($command) {
	return ereg_replace("(\\\$|`)", "", $command);
}

function rrdtool_execute($command_line, $log_command, $output_flag) {
	include ('config.php');
	include_once ('functions.php');
	
	if ($log_command == true) {
		LogData("CMD: " . read_config_option("path_rrdtool") . " $command_line");
	}
	
	if ($output_flag == "") { $output_flag = "1"; }
	
	/* WIN32: before sending this command off to rrdtool, get rid
	of all of the '\' characters. Unix does not care; win32 does. 
	Also make sure to replace all of the fancy \'s at the end of the line,
	but make sure not to get rid of the "\n"'s that are supposed to be
	in there (text format) */
	$command_line = str_replace("\\\n", " ", $command_line);
	
	/* if we want to see the error output from rrdtool; make sure to specify this */
	if ($output_flag == "2") {
		$command_line .= " 2>&1";
	}
	
	/* use popen to eliminate the zombie issue */
	if ($config["cacti_server_os"] == "unix") {
		$fp = popen(read_config_option("path_rrdtool") . escape_command(" $command_line"), "r");
	}elseif ($config["cacti_server_os"] == "win32") {
		$fp = popen(read_config_option("path_rrdtool") . escape_command(" $command_line"), "rb");
	}
	
	/* Return Flag:
	0: Null
	1: Pass output back
	2: Pass error output back */
	
	switch ($output_flag) {
		case '0':
			return; break;
		case '1':
			return fpassthru($fp); break;
		case '2':
			$output = fgets($fp, 1000000);
			
			if (substr($output, 0, 4) == "‰PNG") {
				return "OK";
			}
			
			if (substr($output, 0, 5) == "GIF87") {
				return "OK";
			}
			
			print $output;
			break;
	}
}

function rrdtool_function_create($local_data_id, $show_source) {
	include_once ("functions.php");
	include ("config_arrays.php");
	
	$data_source_path = get_data_source_path($local_data_id, true);
	
	/* ok, if that passes lets check to make sure an rra does not already
	exist, the last thing we want to do is overright data! */
	if ($show_source != true) {
		if (file_exists($data_source_path) == true) {
			return -1;
		}
	}
	
	/* the first thing we must do is make sure there is at least one
	rra associated with this data source... * 
	UPDATE: As of version 0.6.6, we are splitting this up into two
	SQL strings because of the multiple DS per RRD support. This is 
	not a big deal however since this function gets called once per
	data source */
	
	$rras = db_fetch_assoc("select 
		data_template_data.rrd_step,
		rra.x_files_factor,
		rra.steps,
		rra.rows,
		rra_cf.consolidation_function_id,
		(rra.rows*rra.steps) as rra_order
		from data_template_data
		left join data_template_data_rra on data_template_data.id=data_template_data_rra.data_template_data_id
		left join rra on data_template_data_rra.rra_id=rra.id
		left join rra_cf on rra.id=rra_cf.rra_id
		where data_template_data.local_data_id=$local_data_id
		order by rra_cf.consolidation_function_id,rra_order");
	
	/* if we find that this DS has no RRA associated; get out */
	if (sizeof($rras) <= 0) {
		LogData("There are no RRA's assigned to local_data_id: $local_data_id!");
		return -1;
	}
	
	/* create the "--step" line */
	$create_ds = RRD_NL . "--step ". $rras[0]["rrd_step"] . " " . RRD_NL;
	
	/* query the data sources to be used in this .rrd file */
	$data_sources = db_fetch_assoc("select
		data_template_rrd.id,
		data_template_rrd.rrd_heartbeat,
		data_template_rrd.rrd_minimum,
		data_template_rrd.rrd_maximum,
		data_template_rrd.data_source_type_id
		from data_template_rrd
		where data_template_rrd.local_data_id=$local_data_id");
	
	/* ONLY make a new DS entry if:
	- There is multiple data sources and this item is not the main one.
	- There is only one data source (then use it) */
	
	if (sizeof($data_sources) > 0) {
	foreach ($data_sources as $data_source) {
		/* use the cacti ds name by default or the user defined one, if entered */
		$data_source_name = get_data_source_name($data_source["id"]);
	
		$create_ds .= "DS:$data_source_name:" . $data_source_types{$data_source["data_source_type_id"]} . ":" . $data_source["rrd_heartbeat"] . ":" . $data_source["rrd_minimum"] . ":" . $data_source["rrd_maximum"] . RRD_NL;
	}
	}
	
	$create_rra = "";
	/* loop through each available RRA for this DS */
	foreach ($rras as $rra) {
		$create_rra .= "RRA:" . $consolidation_functions{$rra["consolidation_function_id"]} . ":" . $rra["x_files_factor"] . ":" . $rra["steps"] . ":" . $rra["rows"] . RRD_NL;
	}
	
	if ($show_source == true) {
		return read_config_option("path_rrdtool") . " create" . RRD_NL . "$data_source_path$create_ds$create_rra";
	}else{
		if (read_config_option("log_create") == "on") { $log_data = true; }
		rrdtool_execute("create $data_source_path $create_ds$create_rra",$log_data,1);
	}
}

function rrdtool_function_update($update_cache_array) {
	include_once ("functions.php");
	
	while (list($local_data_id, $update_array) = each($update_cache_array)) {
		$data_source_path = get_data_source_path($local_data_id, true);
		
		$i = 0; $rrd_update_template = ""; $rrd_update_values = "";
		while (list($field_name, $field_value) = each($update_array)) {
			$rrd_update_template .= $field_name;
			$rrd_update_values .= $field_value;
			
			if (($i+1) < count($update_array)) {
				$rrd_update_template .= ":";
				$rrd_update_values .= ":";
			}
			
			$i++;
		}
		
		if (read_config_option("log_update") == "on") {
			$log_data = true;
		}else{
			$log_data = false;
		}
		
		/* if we have "invalid data", give rrdtool an Unknown (U) */
		if ($rrd_update_values == "") {
			$rrd_update_values = "U";
		}
		
		print "update $data_source_path --template $rrd_update_template N:$rrd_update_values\n";
		rrdtool_execute("update $data_source_path --template $rrd_update_template N:$rrd_update_values",$log_data,1);
	}
}

function rrdtool_function_tune($rrd_tune_array) {
	include_once ('functions.php');
	include ('config_arrays.php');
	
	$data_source_name = get_data_source_name($rrd_tune_array["data_source_id"]);
	$data_source_type = $data_source_types{$rrd_tune_array["data-source-type"]};
	$data_source_path = get_data_source_path($rrd_tune_array["data_source_id"], true);
	
	if ($rrd_tune_array["heartbeat"] != "") {
		$rrd_tune .= " --heartbeat $data_source_name:" . $rrd_tune_array["heartbeat"];
	}
	
	if ($rrd_tune_array["minimum"] != "") {
		$rrd_tune .= " --minimum $data_source_name:" . $rrd_tune_array["minimum"];
	}
	
	if ($rrd_tune_array["maximum"] != "") {
		$rrd_tune .= " --maximum $data_source_name:" . $rrd_tune_array["maximum"];
	}
	
	if ($rrd_tune_array["data-source-type"] != "") {
		$rrd_tune .= " --data-source-type $data_source_name:" . $data_source_type;
	}
	
	if ($rrd_tune_array["data-source-rename"] != "") {
		$rrd_tune .= " --data-source-rename $data_source_name:" . $rrd_tune_array["data-source-rename"];
	}
	
	if ($rrd_tune != "") {
		if (file_exists($data_source_path) == true) {
			$fp = popen(read_config_option("path_rrdtool") . " tune $data_source_path $rrd_tune", "r");
			pclose($fp);
			
			LogData("CMD: " . read_config_option("path_rrdtool") . " tune $data_source_path $rrd_tune");
		}
	}
}

function rrdtool_function_graph($local_graph_id, $rra_id, $graph_data_array) {
	include_once ("functions.php");
	include_once ("cdef_functions.php");
	include ("config_arrays.php");
	
	/* before we do anything; make sure the user has permission to view this graph,
	if not then get out */
	if (read_config_option("global_auth") == "on") {
		$user_auth = db_fetch_row("select user_id from user_auth_graph where local_graph_id=$local_graph_id and user_id=" . $_SESSION["sess_user_id"]);
		$current_user = db_fetch_row("select * from user where id=" . $_SESSION["sess_user_id"]);
		
		$access_denied = false;
		
		if ($current_user["graph_policy"] == "1") {
			if (sizeof($user_auth) > 0) { $access_denied = true; }
		}elseif ($current_user["graph_policy"] == "2") {
			if (sizeof($user_auth) == 0) { $access_denied = true; }
		}
		
		if ($access_denied == true) {
			return "GRAPH ACCESS DENIED";
		}
	}
	
	/* define the time span, which decides which rra to use */
	$rra = db_fetch_row("select rows,steps from rra where id=$rra_id");
	
        switch ($rra_id) {
                case 1 : $timespan = - 3600 * 24; break;
                case 2 : $timespan = - 3600 * 24 * 7; break;
                case 3 : $timespan = - 3600 * 24 * 34; break;
                case 4 : $timespan = - 3600 * 24 * 365; break;
        }
	
	$graph = db_fetch_row("select
		graph_templates_graph.title,
		graph_templates_graph.vertical_label,
		graph_templates_graph.auto_scale,
		graph_templates_graph.auto_scale_opts,
		graph_templates_graph.auto_scale_log,
		graph_templates_graph.auto_scale_rigid,
		graph_templates_graph.auto_padding,
		graph_templates_graph.base_value,
		graph_templates_graph.upper_limit,
		graph_templates_graph.lower_limit,
		graph_templates_graph.height,
		graph_templates_graph.width,
		graph_templates_graph.image_format_id,
		graph_templates_graph.unit_value,
		graph_templates_graph.unit_exponent_value,
		graph_templates_graph.export
		from graph_templates_graph
		where graph_templates_graph.local_graph_id=$local_graph_id");
	
    	/* lets make that sql query... */
    	$graph_items = db_fetch_assoc("select
		graph_templates_item.id as graph_templates_item_id,
		graph_templates_item.cdef_id,
		graph_templates_item.text_format,
		graph_templates_item.value,
		graph_templates_item.hard_return,
		graph_templates_item.consolidation_function_id,
		graph_templates_item.graph_type_id,
		graph_templates_gprint.gprint_text,
		colors.hex,
		data_template_rrd.id as data_template_rrd_id,
		data_template_rrd.local_data_id,
		data_template_rrd.data_source_name
		from graph_templates_item
		left join data_template_rrd on graph_templates_item.task_item_id=data_template_rrd.id
		left join colors on graph_templates_item.color_id=colors.id
		left join graph_templates_gprint on graph_templates_item.gprint_id=graph_templates_gprint.id
		where graph_templates_item.local_graph_id=$local_graph_id
		order by graph_templates_item.sequence");
	
  	/* +++++++++++++++++++++++ GRAPH OPTIONS +++++++++++++++++++++++ */
	
	/* define some variables */
	$scale = "";
	$rigid = "";
	$graph_legend = "";
	$graph_defs = "";
	$txt_graph_items = "";
	$text_padding = "";
	
    	if ($graph["auto_scale"] == "on") {
		if ($graph["auto_scale_opts"] == "1") {
			$scale = "--alt-autoscale" . RRD_NL;
		}elseif ($graph["auto_scale_opts"] == "2") {
			$scale = "--alt-autoscale-max" . RRD_NL;
			$scale .= "--lower-limit=" . $graph["lower_limit"] . RRD_NL; 
		}
		
		if ($graph["auto_scale_log"] == "on") {
			$scale .= "--logarithmic" . RRD_NL;
		}
	}else{
		$scale =  "--upper-limit=" . $graph["upper_limit"] . RRD_NL;
		$scale .= "--lower-limit=" . $graph["lower_limit"] . RRD_NL;
	}
	
	if ($graph["auto_scale_rigid"] == "on") {
		$rigid = "--rigid" . RRD_NL;
	}
	
	if (!empty($graph["unit_value"])) {
		$unit_value = "--unit=" . $graph["unit_value"] . RRD_NL;
	}
	
	if (!empty($graph["unit_exponent_value"])) {
		$unit_exponent_value = "--units-exponent=" . $graph["unit_exponent_value"] . RRD_NL;
	}
	
	/* optionally you can specify and array that overrides some of the db's
	values, lets set that all up here */
	if (isset($graph_data_array["use"])) {
		if ($graph_data_array["graph_start"] == "0") {
			$graph_start = $timespan;
		}else{
			$graph_start = $graph_data_array["graph_start"];
			if ($graph_data_array["graph_end"] != "") {
                        	$graph_end = $graph_data_array["graph_end"];
                	}
                	else {
                        	$graph_end = time();
                	}
		}
		
		$graph_height = $graph_data_array["graph_height"];
		$graph_width = $graph_data_array["graph_width"];
	}else{
		$graph_start = $timespan;
                $graph_end = time();
		$graph_height = $graph["height"];
		$graph_width = $graph["width"];
	}
	
	if (isset($graph_data_array["graph_nolegend"])) {
		$graph_legend = "--no-legend" . RRD_NL;
	}else{
		$graph_legend = "";
	}
    
	/* export options */
	if (isset($graph_data_array["export"])) {
		$graph_opts = read_config_option("path_html_export") . "/" . $graph_data_array["export_filename"] . RRD_NL;
	}else{
		if (empty($graph_data_array["output_filename"])) {
	    		$graph_opts = "-" . RRD_NL;
		}else{
			$graph_opts = $graph_data_array["output_filename"] . RRD_NL;
		}
	}
    
	/* basic graph options */
	$graph_opts .= 
		"--imgformat=" . $image_types{$graph["image_format_id"]} . RRD_NL . 
		"--start=$graph_start" . RRD_NL .
                "--end="$graph_end"" . " \\\n" . 
		"--title="" . get_graph_title($local_graph_id) . """ . RRD_NL .
		"$rigid" .
		"--base=" . $graph["base_value"] . RRD_NL .
		"--height=$graph_height" . RRD_NL .
		"--width=$graph_width" . RRD_NL .
		"$scale" .
		"$graph_legend" .
		"--vertical-label="" . $graph["vertical_label"] . """ . RRD_NL;
    	
	$i = 0;
    	if (sizeof($graph_items > 0)) {
	foreach ($graph_items as $graph_item) {
		if ((ereg("(AREA|STACK|LINE[123])", $graph_item_types{$graph_item["graph_type_id"]})) && (!empty($graph_item["data_source_name"]))) {
			$data_source_name = $graph_item["data_source_name"];
			
			/* use a user-specified ds path if one is entered */
			$data_source_path = get_data_source_path($graph_item["local_data_id"], true);
			
			/* FOR WIN32: Ecsape all colon for drive letters (ex. D\:/path/to/rra) */
			$data_source_path = str_replace(":", "\:", $data_source_path);
			
			/* NOTE: (Update) Data source DEF names are created using the graph_item_id; then passed
			to a function that matches the digits with letters. rrdtool likes letters instead
			of numbers in DEF names; especially with CDEF's. cdef's are created
			the same way, except a 'cdef' is put on the beginning of the hash */
			$graph_defs .= "DEF:" . generate_graph_def_name(("$i")) . "="$data_source_path":$data_source_name:" . $consolidation_functions{$graph_item["consolidation_function_id"]} . RRD_NL;
			
			//print "ds: " . $graph_item["data_template_rrd_id"] . "<br>";
			$cf_ds_cache{$graph_item["data_template_rrd_id"]}{$graph_item["consolidation_function_id"]} = "$i";
			
			$i++;
		}
	}
	}
    
	/* if we are not displaying a legend there is no point in us even processing the auto padding,
	text format stuff. */
	if (!isset($graph_data_array["graph_nolegend"])) {
		/* use this loop to to setup all textformat data (hr, padding, subsitution, etc) */
		$greatest_text_format = 0;
		
		reset($graph_items);
		
		if (sizeof($graph_items) > 0) {
		foreach ($graph_items as $graph_item) {
			/* +++++++++++++++++++++++ LEGEND: TEXT SUBSITUTION (<>'s) +++++++++++++++++++++++ */
			
			/* note the current item_id for easy access */
			$graph_item_id = $graph_item["graph_templates_item_id"];
			
			/* format the textformat string, and add values where there are <>'s */
			$text_format[$graph_item_id] = $graph_item["text_format"];
			$value_format[$graph_item_id] = $graph_item["value"];
			
			/* set hard return variable if selected (\n) */
			if ($graph_item["hard_return"] == "on") { 
				$hardreturn[$graph_item_id] = "\\n"; 
			}else{
				$hardreturn[$graph_item_id] = "";
			}
	    		
			/* +++++++++++++++++++++++ LEGEND: AUTO PADDING (<>'s) +++++++++++++++++++++++ */
			
			/* PADDING: remember this is not perfect! its main use is for the basic graph setup of:
			AREA - GPRINT-CURRENT - GPRINT-AVERAGE - GPRINT-MAXIMUM \n
			of course it can be used in other situations, however may not work as intended.
			If you have any additions to this small peice of code, feel free to send them to me. */
			if ($graph["auto_padding"] == "on") {
				/* only applies to AREA and STACK */
				if (ereg("(AREA|STACK|LINE[123])", $graph_item_types{$graph_item["graph_type_id"]})) {
					$text_format_lengths{$graph_item["data_template_rrd_id"]} = strlen($text_format[$graph_item_id]);
					
					if ((strlen($text_format[$graph_item_id]) > $greatest_text_format) && ($graph_item_types{$graph_item["graph_type_id"]} != "COMMENT")) {
						$greatest_text_format = strlen($text_format[$graph_item_id]);
					}
				}
			}
		}
		}
    	}
	
    	/* +++++++++++++++++++++++ GRAPH ITEMS: CDEF's +++++++++++++++++++++++ */
    	
	$i = 0;
	reset($graph_items);
		
	if (sizeof($graph_items) > 0) {
	foreach ($graph_items as $graph_item) {
		/* CF rules: if we are using a CF because it's defined in the AREA, STACK, LINE[1-3] then
		it is ok to use it elsewhere on the graph. But it is not ok to use a CF DEF because
		its used in a GPRINT; so check that here */
		if ((isset($cf_ds_cache{$graph_item["data_template_rrd_id"]}{$graph_item["consolidation_function_id"]})) && ($graph_item_types{$graph_item["graph_type_id"]} != "GPRINT")) {
			$cf_id = $graph_item["consolidation_function_id"];
		}else{
			$cf_id = 1; /* CF: AVERAGE */
		}
		
		/* make cdef string here; a note about CDEF's in cacti. A CDEF is neither unique to a 
		data source of global cdef, but is unique when those two variables combine. */
		$cdef_graph_defs = ""; $cdef_total_ds = ""; $cdef_total = "";
		
		if ((!empty($graph_item["cdef_id"])) && (isset($cdef_cache{$graph_item["cdef_id"]}{$graph_item["data_template_rrd_id"]}) == false)) {
			$cdef_string = get_cdef($graph_item["cdef_id"]);
			
			/* create cdef string for "total all data sources" if requested */
			if (ereg("ALL_DATA_SOURCES_(NO)?DUPS", $cdef_string)) {
				$item_count = 0;
				for ($t=0;($t<count($graph_items));$t++) {
					if ((ereg("(AREA|STACK|LINE[123])", $graph_item_types{$graph_items[$t]["graph_type_id"]})) && (!empty($graph_items[$t]["data_template_rrd_id"]))) {
						/* if the user screws up CF settings, PHP will generate warnings if left unchecked */
						if (isset($cf_ds_cache{$graph_items[$t]["data_template_rrd_id"]}[$cf_id])) {
							$cdef_total_ds .= generate_graph_def_name($cf_ds_cache{$graph_items[$t]["data_template_rrd_id"]}[$cf_id]) . ",";
						}
						
						$item_count++;
					}
				}
				
				/* if there is only one item to total, don't even bother with the summation. otherwise
				cdef=a,b,c,+,+ is fine. */
				if ($item_count == 1) {
					$cdef_total = str_replace(",", "", $cdef_total_ds);
				}else{
					$cdef_total = $cdef_total_ds . str_repeat("+,", ($item_count - 2)) . "+";
				}
			}
			
			$cdef_string = str_replace("CURRENT_DATA_SOURCE", generate_graph_def_name((isset($cf_ds_cache{$graph_item["data_template_rrd_id"]}[$cf_id]) ? $cf_ds_cache{$graph_item["data_template_rrd_id"]}[$cf_id] : "0")), $cdef_string);
			$cdef_string = str_replace("ALL_DATA_SOURCES_NODUPS", $cdef_total, $cdef_string);
			
			/* make the initial "virtual" cdef name: 'cdef' + [a,b,c,d...] */
			$cdef_graph_defs .= "CDEF:cdef" . generate_graph_def_name("$i") . "=";
			$cdef_graph_defs .= $cdef_string;
			$cdef_graph_defs .= " \\\n";
			
			/* the CDEF cache is so we do not create duplicate CDEF's on a graph */
			$cdef_cache{$graph_item["cdef_id"]}{$graph_item["data_template_rrd_id"]} = "$i";
		}
		
		/* add the cdef string to the end of the def string */
		$graph_defs .= $cdef_graph_defs;
		
		/* note the current item_id for easy access */
		$graph_item_id = $graph_item["graph_templates_item_id"];
		
		/* if we are not displaying a legend there is no point in us even processing the auto padding,
		text format stuff. */
		if ((!isset($graph_data_array["graph_nolegend"])) && ($graph["auto_padding"] == "on")) {
			/* we are basing how much to pad on area and stack text format, 
			not gprint. but of course the padding has to be displayed in gprint,
			how fun! */
			
			$pad_number = ($greatest_text_format - $text_format_lengths{$graph_item["data_template_rrd_id"]});
			//LogData("MAX: $greatest_text_format, CURR: $text_format_lengths[$item_dsid], DSID: $item_dsid");
			$text_padding = str_pad("", $pad_number);
			
			/* two GPRINT's in a row screws up the padding, lets not do that */
			if (($graph_item_types{$graph_item["graph_type_id"]} == "GPRINT") && ($last_graph_type == "GPRINT")) {
				$text_padding = "";
			}
			
			$last_graph_type = $graph_item_types{$graph_item["graph_type_id"]};
		}
		
	
		/* we put this in a variable so it can be manipulated before mainly used
		if we want to skip it, like below */
		$current_graph_item_type = $graph_item_types{$graph_item["graph_type_id"]};
		
		/* IF this graph item has a data source... get a DEF name for it, or the cdef if that applies
		to this graph item */
		if ($graph_item["cdef_id"] == "0") {
			if (isset($cf_ds_cache{$graph_item["data_template_rrd_id"]}[$cf_id])) {
				$data_source_name = generate_graph_def_name($cf_ds_cache{$graph_item["data_template_rrd_id"]}[$cf_id]);
			}else{
				$data_source_name = "";
			}
		}else{
			$data_source_name = "cdef" . generate_graph_def_name($cdef_cache{$graph_item["cdef_id"]}{$graph_item["data_template_rrd_id"]});
		}
		
		/* to make things easier... if there is no text format set; set blank text */
		if (!isset($text_format[$graph_item_id])) {
			$text_format[$graph_item_id] = "";
		}
		
		if (!isset($hardreturn[$graph_item_id])) {
			$hardreturn[$graph_item_id] = "";
		}
		
		/* +++++++++++++++++++++++ GRAPH ITEMS +++++++++++++++++++++++ */
		
		/* this switch statement is basically used to grab all of the graph data above and
		print it out in an rrdtool-friendly fashion, not too much calculation done here. */
		
		switch ($graph_item_types{$graph_item["graph_type_id"]}) {
		case 'AREA':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" . 
			""$text_format[$graph_item_id]$hardreturn[$graph_item_id]" ";
			break;
		case 'STACK':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" .
			""$text_format[$graph_item_id]$hardreturn[$graph_item_id]" ";
			break;
		case 'LINE1':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" . 
			""$text_format[$graph_item_id]$hardreturn[$graph_item_id]" ";
			break;
		case 'LINE2':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" . 
			""$text_format[$graph_item_id]$hardreturn[$graph_item_id]" ";
			break;
		case 'LINE3':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" . 
			$data_source_name . "#" . 
			$graph_item["hex"] . ":" . 
			""$text_format[$graph_item_id]$hardreturn[$graph_item_id]" ";
			break;
		case 'COMMENT':
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":"" .
			"$text_format[$graph_item_id]$hardreturn[$graph_item_id]" ";
			break;
		case 'GPRINT':
			if (!isset($graph_data_array["graph_nolegend"])) {
				$gprint_text = $graph_item["gprint_text"];
				
				$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
				$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" .
				$data_source_name . ":" . $consolidation_functions{$graph_item["consolidation_function_id"]} .
				":"$text_padding$text_format[$graph_item_id]$gprint_text$hardreturn[$graph_item_id]" ";
			}
			
			break;
		case 'HRULE':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			
			if ($graph_data_array["graph_nolegend"] == true) {
				$value_format[$graph_item_id] = "0";
			}else{
				$value_format[$graph_item_id] = str_replace(":", "\:" ,$value_format[$graph_item_id]); /* escape colons */
			}
			
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" .
			$value_format[$graph_item_id] . "#" . $graph_item["hex"] . ":"" . 
			"$text_format[$graph_item_id]$hardreturn[$graph_item_id]" ";
			break;
		case 'VRULE':
			$text_format[$graph_item_id] = str_replace(":", "\:" ,$text_format[$graph_item_id]); /* escape colons */
			
			$value_array = explode(":", $graph_item["value"]);
			$value = date("U", mktime($value_array[0],$value_array[1],0));
			
			$txt_graph_items .= $graph_item_types{$graph_item["graph_type_id"]} . ":" .
			$value . "#" . $graph_item["hex"] . ":"" . 
			"$text_format[$graph_item_id]$hardreturn[$graph_item_id]" ";
			break;
		}
		
		$i++;
		
		if ($i < sizeof($graph_items)) {
			$txt_graph_items .= RRD_NL;
		}
	}
	}
    
	/* either print out the source or pass the source onto rrdtool to get us a nice PNG */
	if (isset($graph_data_array["print_source"])) {
		print "<PRE>" . read_config_option("path_rrdtool") . " graph $graph_opts$graph_defs$txt_graph_items</PRE>";
	}else{
		if (isset($graph_data_array["export"])) {
			rrdtool_execute("graph $graph_opts$graph_defs$graph_items", false, "0");
			return 0;
		}else{
			$log_data = false;
			if (read_config_option("log_graph") == "on") { $log_data = true; }
			if (!isset($graph_data_array["output_flag"])) { $graph_data_array["output_flag"] = 1; }
			
			return rrdtool_execute("graph $graph_opts$graph_defs$txt_graph_items",$log_data,$graph_data_array["output_flag"]);
		}
	}
}

?>
please use this query in your cacti database for it to allow you the zoom acces:

Code: Select all

INSERT INTO user_realm_filename VALUES ('7', 'zoom_graph.php');
Cyrille

Cool zoom/history feature for cacti doesn't work !! plz help

Post by Cyrille »

I tried putting this code too into the 0.8-pre20030427 version and it stopped displaying graphs too
I created a <cacti_dir>zoom_graph.php modified <cacti_dir>graph.php, <cacti_dir>graph_image.php and <cacti_dir>/include/rrd_fucntion.php.
I did "INSERT INTO user_realm_filename VALUES ('7', 'zoom_graph.php')" too but no graphs are displayed.

I just get the [zoom] feature and when I click on it i have the good page but no graph and a warning message :
Warning: Undefined variable: start_year in /var/www/html/cacti/zoom_graph.php on line 41


I have some message too in the header :

Warning: Cannot add header information - headers already sent by (output started at /var/www/html/cacti/include/rrd_functions.php:699) in /var/www/html/cacti/include/auth.php on line 28

Warning: Cannot add header information - headers already sent by (output started at /var/www/html/cacti/include/rrd_functions.php:699) in /var/www/html/cacti/include/auth.php on line 29

Warning: Cannot send session cache limiter - headers already sent (output started at /var/www/html/cacti/include/rrd_functions.php:699) in /var/www/html/cacti/include/auth.php on line 34


Can u help me please ?
thanx
Bruno Prigent
Cacti User
Posts: 68
Joined: Tue Apr 22, 2003 5:51 am

Post by Bruno Prigent »

Did you try with cacti-0.8-pre20030415.tar.gz ?

Can you send me your modified/created files at nono_99_fr@yahoo.fr. I'll compare them with my own files.
mlrtime

Post by mlrtime »

I tried this as well, when I try the new pages, no images are displayed.
I get this in my apache error log:

ERROR: for a logarithmic yaxis you must specify a lower-limit > 0

Are we changing the graphs to logaritmic? I currently have Lower Limit set to 0 for all my graph templates. Why does it need to be > 0?

Thanks,
mlr
Bruno Prigent
Cacti User
Posts: 68
Joined: Tue Apr 22, 2003 5:51 am

Post by Bruno Prigent »

We are not changing the graphs to logaritmic.
Cyrille
Posts: 2
Joined: Tue Apr 29, 2003 6:21 am
Location: Paris, France

Post by Cyrille »

I always a warning message when I click on the [zoom] link :(

Warning: Undefined variable: start_year in /var/www/html/cacti/zoom_graph.php on line 62

this message is printed at the top of the "Viewing Graph" window, just under the header.

I am using Red Hat 7.2, Apache 1.3.22, PHP 4.1.2, MySQL 3.23.41, rrdtool 1.0.41, ucd-snmp 4.2.1 and cacti-0.8-pre20030428

Thanx
:lol:
Bruno Prigent
Cacti User
Posts: 68
Joined: Tue Apr 22, 2003 5:51 am

Post by Bruno Prigent »

Take a look at your php configuration. You must have "display_errors = Off".
User avatar
TFC
Cacti Pro User
Posts: 739
Joined: Wed Apr 09, 2003 2:17 am
Location: Izmir/Turkey

Post by TFC »

Hi Bruno and others,
My Cacti configuration is like this:
Linux 7.2
Cacti 0.8

I installed your codes. FÝrst everything was ok. Then yesterday i looked at my cacti site. I saw that data collection was not work properly. Lines have been cut off.
I tried to run cmd.php manually:

Code: Select all

/usr/local/cactisetup/php4/php /www/htdocs/cacti8/cmd.php
And at the end of the terminal screen this message has been shown:

Code: Select all

<b>Fatal error</b>: Call to unfdefined function: Logdata () in <b>/www/htdocs/cacti8/include/rrd_functions.php</b> on line <b>38</b>
You can see the line 38 of rrd_functions.php below:

Code: Select all

LogData("CMD: " . read_config_option("path_rrdtool") . " $command_line"); 
I must notice that before, without zooming utility installation, cacti worked properly. But Morning 9:30 A.M all graph have been cut off.
My last day graph shown below:
Image
I need your helps.
Regards...
Bruno Prigent
Cacti User
Posts: 68
Joined: Tue Apr 22, 2003 5:51 am

Post by Bruno Prigent »

For me there is no relation between the zoom code and your problem.
I downloaded the 0.8 version and the line 38 is :
log_data("CMD: " . read_config_option("path_rrdtool") . " $command_line");
Someone has the same probleme than TFC ?
User avatar
TFC
Cacti Pro User
Posts: 739
Joined: Wed Apr 09, 2003 2:17 am
Location: Izmir/Turkey

Post by TFC »

Ok I solved this problem. I add include/ in the rrd_functions.php

But, another problems exists:
1.) Existing rrd files can collect data and i can see its graphs. But when I try to create new data sources, its rrd files can not be created.
2.) After installation of zoom script ( a couple of day later) graphing stops. So, rrd cant collect data. I tried two times and I saw that 9:35 am its stopping time.
Bruno Prigent
Cacti User
Posts: 68
Joined: Tue Apr 22, 2003 5:51 am

Post by Bruno Prigent »

Can you give the syntax used to create the rrd ?
Try to create the rrd by yourself. What is the error message ?
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests