# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Library General Public License as published by # the Free Software Foundation; version 2 only # # 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 Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Copyright 2004, 2005 Red Hat, Inc. # # AUTHOR: Andreas Thienemann # require_once('phplot-5.0.5/phplot.php'); // Get the data from the table, format it and write it out to a file function chart_prepare($flowsrc, $starttime, $endtime, $timeframe = False) { global $date_fmt_str; global $dbh; if ($timeframe != False) { $starttime = (time() - $timeframe); $endtime = time(); } // Define the plot properties $style = 'Top Sources'; $chart_title = $style.' '.$flowsrc.' - '.strftime($date_fmt_str, $starttime).' to '.strftime($date_fmt_str, $endtime); $ytitle = 'Bytes'; $output = tempnam('tmp/', 'plot'); $data_colors = array('SkyBlue', 'green', 'orange', 'blue', 'purple', 'red', 'violet', 'azure1', 'yellow', 'DarkGreen'); // Grab the data from the database // get top-talkers for the timespan: top 9 hosts plus rest-traffic $q = $dbh->prepare('SELECT IPSrc, SUM(Bytes) AS TrafficSum FROM Flows WHERE TimeStop BETWEEN ? AND ? AND FlowSrc = ? GROUP BY IPSrc ORDER BY TrafficSum DESC LIMIT 0, 9'); $q->bindParam(1, $starttime, PDO::PARAM_INT); $q->bindParam(2, $endtime, PDO::PARAM_INT); $q->bindParam(3, sprintf('%u', ip2long($flowsrc)), PDO::PARAM_INT); $q->execute(); // Fill the legend build the WHERE limit $legend = $q->fetchAll(PDO::FETCH_COLUMN, 0); $limit = ''; for ($i = 0; $i < count($legend); $i++) { $limit .= @$legend[$i].', '; if (array_key_exists($i, $legend)) { $legend[$i] = long2ip($legend[$i]); } else { $legend[$i] = ''; } } $legend[] = 'rest'; $limit = substr($limit, 0, (strlen($limit) - 2)); // divide the timespan into 5min intervals // query the traffic per talker in 5min intervals // Initialize the data_table $data = array(); $steps = 0; $rest_table = array(); for ($time1 = $starttime; $time1 < $endtime; $time1 += (5 * 60)) { $time2 = ($time1 + (5 * 60)); $steps++; // Add the column header (time) to the data array $data[] = array(strftime('%H:%M', $time1)); $q = $dbh->prepare('SELECT IPSrc, SUM(Bytes) AS TrafficSum FROM Flows WHERE TimeStop BETWEEN ? AND ? AND IPSrc IN ('.$limit.') AND FlowSrc = ? GROUP BY IPSrc ORDER BY TrafficSum DESC LIMIT 0, 9'); $q->bindParam(1, $time1, PDO::PARAM_INT); $q->bindParam(2, $time2, PDO::PARAM_INT); $q->bindParam(3, sprintf('%u', ip2long($flowsrc)), PDO::PARAM_INT); $q->execute(); $r = $q->fetchAll(); $i = (count($data) - 1); foreach ($r as $row) { $tmpdata[$i][$row[0]] = $row[1]; } // Get the rest of the aggregated traffic to fill up the bars $q = $dbh->prepare('SELECT SUM(Bytes) AS TrafficSum FROM Flows WHERE TimeStop BETWEEN ? AND ? AND IPSrc NOT IN ('.$limit.') AND FlowSrc = ?'); $q->bindParam(1, $time1, PDO::PARAM_INT); $q->bindParam(2, $time2, PDO::PARAM_INT); $q->bindParam(3, sprintf('%u', ip2long($flowsrc)), PDO::PARAM_INT); $q->execute(); $rest_table[] = $q->fetch(); } // Iterate through the legend and fill the data array from the temporary data array // This function makes sure that each top talker is always at the same position // in the multidimensional data table. // This is necessary for phpplot to assign the same color to each host on // sequential columns // $ip is the key for the temp_data lookup foreach ($legend as $ip) { for($i = 0; $i < $steps; $i++) { if (array_key_exists($i, $tmpdata)) { // The "column" exists, let's sort the rows $key = sprintf('%u', ip2long($ip)); if (array_key_exists($key, $tmpdata[$i])) { $data[$i][] = $tmpdata[$i][$key]; } else { $data[$i][] = ''; } } else { $data[$i][] = ''; } } } // Append the data from the rest_table to the data array for($i = 0; $i < $steps; $i++) { $data[$i][(count($data[$i]) - 1)] = $rest_table[$i][0]; } // Create the chart, write it to tmp/output.png $plot = new PHPlot(900, 400); $plot->SetIsInline(True); //$plot->SetPrintImage(False); $plot->SetImageBorderType('plain'); $plot->SetDataColors($data_colors); $plot->SetPlotType('stackedbars'); $plot->SetDataType('text-data'); $plot->SetDataValues($data); $plot->SetTitle($chart_title); $plot->SetYTitle($ytitle); $plot->SetLegend($legend); $plot->SetXTickLabelPos('none'); $plot->SetXTickPos('none'); $plot->SetLegendPixels(760, 40); $plot->SetMarginsPixels(100, 150, 50, 50); $plot->SetNumberFormat(',', '.'); $plot->SetPrecisionY(0); $plot->SetYLabelType('data'); $plot->SetOutputFile($output); $plot->DrawGraph(); chmod($output, 0644); $target = dirname($output).'/'.basename($output).'.png'; if (rename($output, $target)) { return 'tmp/'.basename($target); } else { return False; } }