Merge pull request #35 from clobrother/peeras

Store & create graph for peer-as
This commit is contained in:
Manuel Kasper 2014-06-26 13:45:52 +02:00
commit de372482bb
9 changed files with 166 additions and 75 deletions

View File

@ -39,18 +39,20 @@ my $v10_templates = {};
my $sflow_server_port = 6343;
use vars qw/ %opt /;
getopts('r:p:P:k:a:', \%opt);
getopts('r:p:P:k:a:n', \%opt);
my $usage = "$0 [-rpPka]\n".
"\t-r <path to RRD files>\n".
"\t(-p <NetFlow UDP listen port - default $server_port, use 0 to disable NetFlow)\n".
"\t(-P <sFlow UDP listen port - default $sflow_server_port, use 0 to disable sFlow)\n".
"\t-k <path to known links file>\n".
"\t-a <your own AS number> - only required for sFlow\n";
"\t-a <your own AS number> - only required for sFlow\n".
"\t-n - enable peer-as statistics\n";
my $rrdpath = $opt{'r'};
my $knownlinksfile = $opt{'k'};
my $myas = $opt{'a'};
my $peerasstats = $opt{'n'};
die("$usage") if (!defined($rrdpath) || !defined($knownlinksfile));
@ -89,6 +91,7 @@ sub REAPER {
sub TERM {
print "SIGTERM received\n";
flush_cache(1);
while (wait() != -1) {}
exit 0;
}
@ -563,12 +566,40 @@ sub parse_sflow {
$vlanout = $sFlowSample->{'SwitchDestVlan'};
}
# srcpeeras is the one who sent me data
# dstpeeras is the first one to which you'll send the data
# so, dstpeeras is the first entry in array
# if the array is now empty (poped before), then take $dstas
my $srcpeeras = ($sFlowSample->{'GatewayAsSourcePeer'}) ? $sFlowSample->{'GatewayAsSourcePeer'} : 0;
my $dstpeeras = 0;
if ($sFlowSample->{'GatewayDestAsPaths'}) {
$dstpeeras = @{$sFlowSample->{'GatewayDestAsPaths'}->[0]->{'AsPath'}}[0];
if (!$dstpeeras) {
$dstpeeras = 0;
}
}
if($dstpeeras == 0 && $dstas != 0){
$dstpeeras = $dstas;
}
if ($srcpeeras == $myas) {
$srcpeeras = 0;
}
if ($dstpeeras== $myas) {
$dstpeeras = 0;
}
handleflow($ipaddr, $noctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, 'sflow', $vlanin, $vlanout);
if($peerasstats && ($srcpeeras != 0 || $dstpeeras != 0)){
handleflow($ipaddr, $noctets, $srcpeeras, $dstpeeras, $snmpin, $snmpout, $ipversion, 'sflow', $vlanin, $vlanout, 1);
}
}
}
sub handleflow {
my ($routerip, $noctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, $type, $vlanin, $vlanout) = @_;
my ($routerip, $noctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, $type, $vlanin, $vlanout, $peeras) = @_;
if ($srcas == 0 && $dstas == 0) {
# don't care about internal traffic
@ -593,8 +624,8 @@ sub handleflow {
$ifalias = $knownlinks{inet_ntoa($routerip) . '_' . $snmpin . '/' . $vlanin} if defined($vlanin);
$ifalias //= $knownlinks{inet_ntoa($routerip) . '_' . $snmpin};
} else {
handleflow($routerip, $noctets, $srcas, 0, $snmpin, $snmpout, $ipversion, $vlanin, $vlanout);
handleflow($routerip, $noctets, 0, $dstas, $snmpin, $snmpout, $ipversion, $vlanin, $vlanout);
handleflow($routerip, $noctets, $srcas, 0, $snmpin, $snmpout, $ipversion, $type, $vlanin, $vlanout, $peeras);
handleflow($routerip, $noctets, 0, $dstas, $snmpin, $snmpout, $ipversion, $type, $vlanin, $vlanout, $peeras);
return;
}
@ -611,16 +642,17 @@ sub handleflow {
}
# put it into the cache
if (!$ascache->{$as}) {
$ascache->{$as} = {createts => time};
my $name = ($peeras) ? "${as}_peer" : $as;
if (!$ascache->{$name}) {
$ascache->{$name} = {createts => time};
}
$ascache->{$as}->{$dsname} += $noctets;
$ascache->{$as}->{updatets} = time;
$ascache->{$name}->{$dsname} += $noctets;
$ascache->{$name}->{updatets} = time;
if ($ascache->{$as}->{updatets} == $ascache_lastflush) {
if ($ascache->{$name}->{updatets} == $ascache_lastflush) {
# cheat a bit here
$ascache->{$as}->{updatets}++;
$ascache->{$name}->{updatets}++;
}
# now flush the cache, if necessary
@ -645,8 +677,11 @@ sub flush_cache {
$ascache_lastflush = time;
if(!defined($force)){
for (keys %$ascache) {
if ($_ % 10 == $ascache_flush_number % 10) {
delete $ascache->{$_};
my $as= $_;
$as =~ s/_peer//;
if ($as % 10 == $ascache_flush_number % 10) {
delete $ascache->{$as};
delete $ascache->{"${as}_peer"};
}
}
}else{
@ -656,11 +691,15 @@ sub flush_cache {
return;
}
while (my ($as, $cacheent) = each(%$ascache)) {
while (my ($entry, $cacheent) = each(%$ascache)) {
my $as = $entry;
$as =~ s/_peer//;
if (defined($force) || $as % 10 == $ascache_flush_number % 10) {
#print "$$: flushing data for AS $as ($cacheent->{updatets})\n";
my $rrdfile = getrrdfile($as, $cacheent->{updatets});
my $peeras = ($entry eq $as) ? 0 : 1;
my $rrdfile = getrrdfile($as, $cacheent->{updatets}, $peeras);
my @templatearg;
my @args;
@ -692,11 +731,17 @@ sub flush_cache {
sub getrrdfile {
my $as = shift;
my $startts = shift;
my $peeras = shift;
$startts--;
if(! -d "$rrdpath/peeras"){
mkdir("$rrdpath/peeras");
}
my $prefix = ($peeras) ? "$rrdpath/peeras" : $rrdpath;
# we create 256 directories and store RRD files based on the lower
# 8 bytes of the AS number
my $dirname = "$rrdpath/" . sprintf("%02x", $as % 256);
my $dirname = "$prefix/" . sprintf("%02x", $as % 256);
if (! -d $dirname) {
# need to create directory
mkdir($dirname);

View File

@ -8,6 +8,7 @@
use strict;
use RRDs;
use File::Find;
use File::Find::Rule;
if ($#ARGV != 2) {
die("Usage: $0 <path to RRD file directory> <path to known links file> outfile\n");
@ -26,12 +27,7 @@ my @links = values %knownlinks;
# walk through all RRD files in the given path and extract stats for all links
# from them; write the stats to a text file, sorted by total traffic
my @rrdfiles;
find(sub {
if (-f $_) {
push(@rrdfiles, $File::Find::name);
}
}, $rrdpath);
my @rrdfiles = File::Find::Rule->maxdepth(2)->file->in($rrdpath);
my $astraffic = {};

View File

@ -6,6 +6,9 @@ $rrdpath = "/data/as-stats/rrd";
$daystatsfile = "/data/as-stats/asstats_day.txt";
$rrdtool = "/usr/bin/rrdtool";
$daypeerstatsfile = "/data/as-stats/peerasstats_day.txt";
$showpeeras = true;
$asinfofile = "asinfo.txt";
$knownlinksfile = "/data/as-stats/conf/knownlinks";
$outispositive = true;

View File

@ -95,11 +95,17 @@ function getknownlinks() {
return $knownlinks;
}
function getasstats_top($ntop) {
function getasstats_top($ntop, $peer = 0) {
if($peer == 0){
global $daystatsfile;
$statfile = $daystatsfile;
}else{
global $daypeerstatsfile;
$statfile = $daypeerstatsfile;
}
/* first step: walk the data for all ASes to determine the top 5 for the given link */
$fd = fopen($daystatsfile, "r");
$fd = fopen($statfile, "r");
if (!$fd)
return array();
$cols = explode("\t", trim(fgets($fd)));
@ -152,9 +158,10 @@ function format_bytes($bytes) {
return "$bytes bytes";
}
function getRRDFileForAS($as) {
function getRRDFileForAS($as, $peer = 0) {
global $rrdpath;
return "$rrdpath/" . sprintf("%02x", $as % 256) . "/$as.rrd";
$prefix = ($peer == 1) ? "$rrdpath/peeras" : "$rrdpath";
return "$prefix/" . sprintf("%02x", $as % 256) . "/$as.rrd";
}
function getASSET($asset) {
@ -219,3 +226,28 @@ function clearCacheFileASSET($asset) {
unlink($file);
}
}
# return the html used in top.php : <a href=blabla><img src=blabla/></url>
function getHTMLUrl($as, $ipversion, $desc, $start, $end, $peerusage){
$img = getHTMLImg($as, $ipversion, $desc, $start, $end, $peerusage, '', '', false);
$result = "<a href='history.php?as=$as&peerusage=$peerusage&v=$ipversion' target='_blank'>$img</a>";
return($result);
}
# return the html used in history.php (for example) : <img src=blabla/>
function getHTMLImg($as, $ipversion, $desc, $start, $end, $peerusage, $alt, $class, $history = false){
global $top_graph_width;
global $top_graph_height;
$dname = rawurlencode("AS$as - $desc - IPV$ipversion");
$result = "<img alt='$alt' class='$class' src='gengraph.php?v=$ipversion&as=$as&peerusage=$peerusage&dname=$dname&start=$start&end=$end";
if(!$history)
$result .= "&width=$top_graph_width&height=$top_graph_height&nolegend=1";
$result .= "'";
if(!$history)
$result .= " width='$top_graph_width' height='$top_graph_height' border='0'";
$result .= "/>";
return($result);
}

View File

@ -23,8 +23,13 @@ $v6_el = "";
if (@$_GET['v'] == 6)
$v6_el = "v6_";
if(isset($_GET['peerusage']) && $_GET['peerusage'] == '1')
$peerusage = 1;
else
$peerusage = 0;
$knownlinks = getknownlinks();
$rrdfile = getRRDFileForAS($as);
$rrdfile = getRRDFileForAS($as, $peerusage);
if ($compat_rrdtool12) {
/* cannot use full-size-mode - must estimate height/width */

View File

@ -7,6 +7,14 @@ else:
?><a href="top.php">Top AS</a> | <?php
endif;
if($showpeeras == true){
if ($dpagename == "peerusage"):
?><a href="peerusage.php" class="selected">Top Peer AS</a> | <?php
else:
?><a href="peerusage.php">Top AS Peer<a> | <?php
endif;
}
if ($dpagename == "top" && @$_GET['numhours'] == 4):
?><a href="top.php?numhours=4" class="selected">4 Hour</a> | <?php
@ -35,7 +43,6 @@ else:
?><a href="asset.php">View an AS-SET</a> | <?php
endif;
if ($dpagename == "linkusage"):
?><a href="linkusage.php" class="selected">Link usage</a><?php
else:

View File

@ -13,7 +13,12 @@ $as = str_replace('as','',str_replace(' ','',strtolower($_GET['as'])));
if ($as)
$asinfo = getASInfo($as);
$rrdfile = getRRDFileForAS($as);
if(isset($_GET['peerusage']) && $_GET['peerusage'] == '1')
$peerusage = 1;
else
$peerusage = 0;
$rrdfile = getRRDFileForAS($as, $peerusage);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
@ -31,7 +36,7 @@ $rrdfile = getRRDFileForAS($as);
<div id="nav"><?php include('headermenu.inc'); ?></div>
<?php if ($as): ?>
<div class="pgtitle">History for AS<?php echo $as; ?>: <?php echo $asinfo['descr']; ?>
<div class="pgtitle">History for <?php if($peerusage == 1) echo "peer "; ?>AS<?php echo $as; ?>: <?php echo $asinfo['descr']; ?>
<?php if (!empty($customlinks)): ?>
<div class="customlinks">
<?php
@ -50,44 +55,40 @@ $rrdfile = getRRDFileForAS($as);
<p>No data found for AS <?php echo $as; ?></p>
<?php else: ?>
<div class="title">4 Hourly</div>
<?php if ($showv6): ?>
<img class="detailgraph" src="gengraph.php?v=4&amp;as=<?php echo $as; ?>&amp;start=<?php echo (time() - 4*3600);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV4"); ?>" alt="weekly graph" />
<img class="detailgraph2" src="gengraph.php?v=6&amp;as=<?php echo $as; ?>&amp;start=<?php echo (time() - 4*3600);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV6"); ?>" alt="weekly graph" />
<?php else: ?>
<img class="detailgraph" src="gengraph.php?as=<?php echo $as; ?>&amp;start=<?php echo (time() - 4*3600);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . ""); ?>" alt="weekly graph" />
<?php endif; ?>
<?php
echo getHTMLImg($as, 4, $asinfo['descr'], time() - 4 * 3600, time(), $peerusage, 'hourly graph', 'detailgraph', true);
if ($showv6)
echo getHTMLImg($as, 6, $asinfo['descr'], time() - 4 * 3600, time(), $peerusage, 'hourly graph', 'detailgraph2', true);
?>
<div class="title">Daily</div>
<?php if ($showv6): ?>
<img class="detailgraph" src="gengraph.php?v=4&amp;as=<?php echo $as; ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV4"); ?>" alt="daily graph" />
<img class="detailgraph2" src="gengraph.php?v=6&amp;as=<?php echo $as; ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV6"); ?>" alt="daily graph" />
<?php else: ?>
<img class="detailgraph" src="gengraph.php?as=<?php echo $as; ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . ""); ?>" alt="daily graph" />
<?php endif; ?>
<?php
echo getHTMLImg($as, 4, $asinfo['descr'], time() - 24 * 3600, time(), $peerusage, 'daily graph', 'detailgraph', true);
if ($showv6)
echo getHTMLImg($as, 6, $asinfo['descr'], time() - 24 * 3600, time(), $peerusage, 'daily graph', 'detailgraph2', true);
?>
<div class="title">Weekly</div>
<?php if ($showv6): ?>
<img class="detailgraph" src="gengraph.php?v=4&amp;as=<?php echo $as; ?>&amp;start=<?php echo (time() - 7*86400);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV4"); ?>" alt="weekly graph" />
<img class="detailgraph2" src="gengraph.php?v=6&amp;as=<?php echo $as; ?>&amp;start=<?php echo (time() - 7*86400);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV6"); ?>" alt="weekly graph" />
<?php else: ?>
<img class="detailgraph" src="gengraph.php?as=<?php echo $as; ?>&amp;start=<?php echo (time() - 7*86400);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . ""); ?>" alt="weekly graph" />
<?php endif; ?>
<?php
echo getHTMLImg($as, 4, $asinfo['descr'], time() - 7 * 86400, time(), $peerusage, 'weekly graph', 'detailgraph', true);
if ($showv6)
echo getHTMLImg($as, 6, $asinfo['descr'], time() - 7 * 86400, time(), $peerusage, 'weekly graph', 'detailgraph2', true);
?>
<div class="title">Monthly</div>
<?php if ($showv6): ?>
<img class="detailgraph" src="gengraph.php?v=4&amp;as=<?php echo $as; ?>&amp;start=<?php echo (time() - 30*86400);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV4"); ?>" alt="monthly graph" />
<img class="detailgraph2" src="gengraph.php?v=6&amp;as=<?php echo $as; ?>&amp;start=<?php echo (time() - 30*86400);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV6"); ?>" alt="monthly graph" />
<?php else: ?>
<img class="detailgraph" src="gengraph.php?as=<?php echo $as; ?>&amp;start=<?php echo (time() - 30*86400);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . ""); ?>" alt="monthly graph" />
<?php endif; ?>
<?php
echo getHTMLImg($as, 4, $asinfo['descr'], time() - 30 * 86400, time(), $peerusage, 'monthly graph', 'detailgraph', true);
if ($showv6)
echo getHTMLImg($as, 6, $asinfo['descr'], time() - 30 * 86400, time(), $peerusage, 'monthly graph', 'detailgraph2', true);
?>
<div class="title">Yearly</div>
<?php if ($showv6): ?>
<img class="detailgraph" src="gengraph.php?v=4&amp;as=<?php echo $as; ?>&amp;start=<?php echo (time() - 365*86400);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV4"); ?>" alt="yearly graph" />
<img class="detailgraph2" src="gengraph.php?v=6&amp;as=<?php echo $as; ?>&amp;start=<?php echo (time() - 365*86400);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV6"); ?>" alt="yearly graph" />
<?php else: ?>
<img class="detailgraph" src="gengraph.php?as=<?php echo $as; ?>&amp;start=<?php echo (time() - 365*86400);?>&amp;end=<?php echo time(); ?>&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . ""); ?>" alt="yearly graph" />
<?php endif; ?>
<?php
echo getHTMLImg($as, 4, $asinfo['descr'], time() - 365 * 86400, time(), $peerusage, 'yearly graph', 'detailgraph', true);
if ($showv6)
echo getHTMLImg($as, 6, $asinfo['descr'], time() - 365 * 86400, time(), $peerusage, 'yearly graph', 'detailgraph2', true);
?>
<?php endif; ?>
<?php else: ?>

View File

@ -41,7 +41,7 @@ $class = (($i % 2) == 0) ? "even" : "odd";
<td>
<?php if ($showv6): ?>
<img alt="link graph" src="linkgraph.php?link=<?php echo $link['tag']; ?>&amp;width=<?php echo $linkusage_graph_width ?>&amp;height=<?php echo $linkusage_graph_height ?>&amp;v=4&amp;dname=<?php echo rawurlencode($link['descr'] . " - IPV4"); ?>" width="<?php echo $linkusage_graph_width ?>" height="<?php echo $linkusage_graph_height ?>" border="0" />
<img alt="link graph" src="linkgraph.php?link=<?php echo $link['tag']; ?>&amp;width=<?php echo $linkusage_graph_width ?>&amp;height=<?php echo $linkusage_graph_height ?>&amp;v=6&amp;dname=<?php echo rawurlencode($link['descr'] . " - IPV4"); ?>" width="<?php echo $linkusage_graph_width ?>" height="<?php echo $linkusage_graph_height ?>" border="0" />
<img alt="link graph" src="linkgraph.php?link=<?php echo $link['tag']; ?>&amp;width=<?php echo $linkusage_graph_width ?>&amp;height=<?php echo $linkusage_graph_height ?>&amp;v=6&amp;dname=<?php echo rawurlencode($link['descr'] . " - IPV6"); ?>" width="<?php echo $linkusage_graph_width ?>" height="<?php echo $linkusage_graph_height ?>" border="0" />
<?php else: ?>
<img alt="link graph" src="linkgraph.php?link=<?php echo $link['tag']; ?>&amp;width=<?php echo $linkusage_graph_width ?>&amp;height=<?php echo $linkusage_graph_height ?>&amp;dname=<?php echo rawurlencode($link['descr'] . ""); ?>" width="<?php echo $linkusage_graph_width ?>" height="<?php echo $linkusage_graph_height ?>" border="0" />
<?php endif; ?>

View File

@ -7,12 +7,15 @@
require_once('func.inc');
if(!isset($peerusage))
$peerusage = 0;
if (isset($_GET['n']))
$ntop = (int)$_GET['n'];
if ($ntop > 200)
$ntop = 200;
$topas = getasstats_top($ntop);
$topas = getasstats_top($ntop, $peerusage);
if (@$_GET['numhours']) {
$start = time() - $_GET['numhours']*3600;
@ -29,7 +32,7 @@ if (@$_GET['numhours']) {
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Refresh" content="300" />
<title>Top <?php echo $ntop; ?> AS</title>
<title>Top <?php echo $ntop; ?> AS<?php if($peerusage) echo " peer"; ?></title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
@ -43,7 +46,7 @@ Number of AS:
<?php include('headermenu.inc'); ?>
</form>
</div>
<div class="pgtitle">Top <?php echo $ntop; ?> AS</div>
<div class="pgtitle">Top <?php echo $ntop; ?> AS<?php if($peerusage) echo " peer"; ?></div>
<table class="astable">
@ -88,12 +91,11 @@ echo join(" | ", $htmllinks);
</div>
</th>
<td>
<?php if ($showv6): ?>
<a href="history.php?v=4&amp;as=<?php echo $as; ?>" target="_blank"><img alt="AS graph" src="gengraph.php?as=<?php echo $as; ?>&amp;width=<?php echo $top_graph_width ?>&amp;height=<?php echo $top_graph_height ?>&amp;v=4&amp;nolegend=1&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV4"); ?>&amp;start=<?php echo $start; ?>&amp;end=<?php echo $end; ?>" width="<?php echo $top_graph_width ?>" height="<?php echo $top_graph_height ?>" border="0" /></a>
<a href="history.php?v=6&amp;as=<?php echo $as; ?>" target="_blank"><img alt="AS graph" src="gengraph.php?as=<?php echo $as; ?>&amp;width=<?php echo $top_graph_width ?>&amp;height=<?php echo $top_graph_height ?>&amp;v=6&amp;nolegend=1&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . " - IPV6"); ?>&amp;start=<?php echo $start; ?>&amp;end=<?php echo $end; ?>" width="<?php echo $top_graph_width ?>" height="<?php echo $top_graph_height ?>" border="0" /></a>
<?php else: ?>
<a href="history.php?as=<?php echo $as; ?>" target="_blank"><img alt="AS graph" src="gengraph.php?as=<?php echo $as; ?>&amp;width=<?php echo $top_graph_width ?>&amp;height=<?php echo $top_graph_height ?>&amp;nolegend=1&amp;dname=<?php echo rawurlencode("AS" . $as . " - " . $asinfo['descr'] . ""); ?>&amp;start=<?php echo $start; ?>&amp;end=<?php echo $end; ?>" width="<?php echo $top_graph_width ?>" height="<?php echo $top_graph_height ?>" border="0" /></a>
<?php endif; ?>
<?php
echo getHTMLUrl($as, 4, $asinfo['descr'], $start, $end, $peerusage);
if ($showv6)
echo getHTMLUrl($as, 6, $asinfo['descr'], $start, $end, $peerusage);
?>
</td>
</tr>
<?php $i++; endforeach; ?>