api: Added Billing Graphs & Data (#8245)

* Move Billing/Bandwidth Graphs to common format, extract data generation to central function

* Add API functions to access billing graphs and graph data

* Scrutinizer fixes

* Fix transfer graphs with from/to

* Scrutinizer Fix

* Fix docs, transfer page and missing from API param

* Document and fix reducefactor, Add Graph Stats to Graph Data

* Standardise times in graphdata

* Fixed renamed function for History GraphData
This commit is contained in:
Richard Lawley
2018-02-20 14:57:56 +00:00
committed by Neil Lathwood
parent 1c5b9d3524
commit 10829893ec
13 changed files with 920 additions and 530 deletions

View File

@@ -132,6 +132,84 @@ Output:
}
```
### `get_bill_graph`
Retrieve a graph image associated with a bill.
NB: The graphs returned from this will always be png as they do not come from rrdtool, even if you have SVG set.
Route: `/api/v0/bills/:id/graphs/:graph_type
Example:
```curl
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/bits
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/bits?from=1517443200
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/bits?from=1517443200&to=1517788800
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/monthly
```
Output:
Graph Image
### `get_bill_graphdata`
Retrieve the data used to draw a graph so it can be rendered in an external system
Route: `/api/v0/bills/:id/graphdata/:graph_type`
Input:
The `reducefactor` parameter is used to reduce the number of data points. Billing data has 5 minute granularity, so
requesting a graph for a long time period will result in many data points. If not supplied, it will be automatically
calculated. A reducefactor of 1 means return all items, 2 means half of the items etc.
Example:
```curl
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits?from=1517443200
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits?from=1517443200&to=1517788800
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits?from=1517443200&to=1517788800&reducefactor=5
```
Output:
{
"status": "ok",
"graph_data": {
"from": "1517443200",
"to": 1518196161,
"last": "1518195901",
"in_data": [
103190525.20999999,
104949255.81
],
"out_data": [
1102059.1299999999,
1079216.46
],
"tot_data": [
104292584.33999999,
106028472.27
],
"ticks": [
"1517750401",
"1517756101"
],
"rate_95th": "251880417",
"rate_average": "146575554",
"bill_type": "cdr",
"max_in": 9888289942,
"max_out": 75848756,
"ave_in": 18029660.242105871,
"ave_out": 196447.38060137472,
"last_in": 3790227.9500000002,
"last_out": 122731.63333333333
}
}
### `get_bill_history`
Retrieve the history of specific bill
@@ -176,4 +254,44 @@ Output:
],
"count": 1,
}
```
```
### `get_bill_history_graph`
Retrieve a graph of a previous period of a bill
NB: The graphs returned from this will always be png as they do not come from rrdtool, even if you have SVG set.
Route: `/api/v0/bills/:id/history/:bill_hist_id/graphs/:graph_type`
Input:
Example:
```curl
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphs/bits
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphs/hour
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphs/day
```
Output:
(image)
### `get_bill_history_graphdata`
Retrieve the data for a graph of a previous period of a bill, to be rendered in an external system
Route: `/api/v0/bills/:id/history/:bill_hist_id/graphdata/:graph_type`
Input:
Example:
```curl
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphdata/bits
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphdata/hour
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphdata/day
```
Output:

View File

@@ -113,7 +113,11 @@ $app->group(
function () use ($app) {
$app->get('/:bill_id', 'authToken', 'list_bills')->name('get_bill');
// api/v0/bills/$bill_id
$app->get('/:bill_id/graphs/:graph_type', 'authToken', 'get_bill_graph')->name('get_bill_graph');
$app->get('/:bill_id/graphdata/:graph_type', 'authToken', 'get_bill_graphdata')->name('get_bill_graphdata');
$app->get('/:bill_id/history', 'authToken', 'get_bill_history')->name('get_bill_history');
$app->get('/:bill_id/history/:bill_hist_id/graphs/:graph_type', 'authToken', 'get_bill_history_graph')->name('get_bill_history_graph');
$app->get('/:bill_id/history/:bill_hist_id/graphdata/:graph_type', 'authToken', 'get_bill_history_graphdata')->name('get_bill_history_graphdata');
}
);
$app->get('/bills', 'authToken', 'list_bills')->name('list_bills');

View File

@@ -9,257 +9,33 @@
* @copyright (C) 2006 - 2012 Adam Armstrong
*/
use Amenadiel\JpGraph\Graph\Graph;
use Amenadiel\JpGraph\Plot\BarPlot;
use Amenadiel\JpGraph\Plot\GroupBarPlot;
use Amenadiel\JpGraph\Plot\LinePlot;
ini_set('allow_url_fopen', 0);
ini_set('display_errors', 0);
if (strpos($_SERVER['REQUEST_URI'], 'debug')) {
$debug = '1';
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('log_errors', 1);
ini_set('error_reporting', E_ALL);
} else {
$debug = false;
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
ini_set('log_errors', 0);
ini_set('error_reporting', 0);
}
$init_modules = array('web', 'auth');
require realpath(__DIR__ . '/..') . '/includes/init.php';
$auth = is_client_authorized($_SERVER['REMOTE_ADDR']);
if (get_client_ip() != $_SERVER['SERVER_ADDR']) {
if ($auth === false && !$_SESSION['authenticated']) {
echo 'unauthenticated';
exit;
}
$urlargs = array(
'type' => 'bill_historictransfer',
'id' => $_GET['bill_id'],
'width' => $_GET['x'],
'height' => $_GET['y'],
'imgtype' => $_GET['type']
);
if (is_numeric($_GET['bill_hist_id'])) {
$urlargs['bill_hist_id'] = $_GET['bill_hist_id'];
} else if (is_numeric($_GET['from']) && is_numeric($_GET['to'])) {
$urlargs['from'] = $_GET['from'];
$urlargs['to'] = $_GET['to'];
}
if (is_numeric($_GET['bill_id'])) {
if (get_client_ip() != $_SERVER['SERVER_ADDR']) {
if ($auth === true || bill_permitted($_GET['bill_id'])) {
$bill_id = $_GET['bill_id'];
} else {
echo 'Unauthorised Access Prohibited.';
exit;
}
} else {
$bill_id = $_GET['bill_id'];
$url = "{$config['base_url']}graph.php?";
$i = 0;
foreach ($urlargs as $name => $value) {
if ($i++ > 0) {
$url .= '&';
}
} else {
echo 'Unauthorised Access Prohibited.';
exit;
$url .= "$name=$value";
}
if (is_numeric($_GET['bill_id']) && is_numeric($_GET['bill_hist_id'])) {
$histrow = dbFetchRow('SELECT UNIX_TIMESTAMP(bill_datefrom) as `from`, UNIX_TIMESTAMP(bill_dateto) AS `to` FROM bill_history WHERE bill_id = ? AND bill_hist_id = ?', array($_GET['bill_id'], $_GET['bill_hist_id']));
if (is_null($histrow)) {
header("HTTP/1.0 404 Not Found");
exit();
}
$start = $histrow['from'];
$end = $histrow['to'];
} else {
$start = $_GET['from'];
$end = $_GET['to'];
}
$xsize = (is_numeric($_GET['x']) ? $_GET['x'] : '800' );
$ysize = (is_numeric($_GET['y']) ? $_GET['y'] : '250' );
// $count = (is_numeric($_GET['count']) ? $_GET['count'] : "0" );
// $type = (isset($_GET['type']) ? $_GET['type'] : "date" );
// $dur = $end - $start;
// $datefrom = date('Ymthis', $start);
// $dateto = date('Ymthis', $end);
$imgtype = (isset($_GET['type']) ? $_GET['type'] : 'historical' );
$imgbill = (isset($_GET['imgbill']) ? $_GET['imgbill'] : false);
$yaxistitle = 'Bytes';
$in_data = array();
$out_data = array();
$tot_data = array();
$allow_data = array();
$ave_data = array();
$overuse_data = array();
$ticklabels = array();
if ($imgtype == 'historical') {
$i = '0';
foreach (dbFetchRows('SELECT * FROM `bill_history` WHERE `bill_id` = ? ORDER BY `bill_datefrom` DESC LIMIT 12', array($bill_id)) as $data) {
$datefrom = strftime('%e %b %Y', strtotime($data['bill_datefrom']));
$dateto = strftime('%e %b %Y', strtotime($data['bill_dateto']));
$datelabel = $datefrom."\n".$dateto;
$traf['in'] = $data['traf_in'];
$traf['out'] = $data['traf_out'];
$traf['total'] = $data['traf_total'];
if ($data['bill_type'] == 'Quota') {
$traf['allowed'] = $data['bill_allowed'];
$traf['overuse'] = $data['bill_overuse'];
} else {
$traf['allowed'] = '0';
$traf['overuse'] = '0';
}
array_push($ticklabels, $datelabel);
array_push($in_data, $traf['in']);
array_push($out_data, $traf['out']);
array_push($tot_data, $traf['total']);
array_push($allow_data, $traf['allowed']);
array_push($overuse_data, $traf['overuse']);
$i++;
// print_r($data);
}//end foreach
if ($i < 12) {
$y = (12 - $i);
for ($x = 0; $x < $y; $x++) {
$allowed = (($x == '0') ? $traf['allowed'] : '0' );
array_push($in_data, '0');
array_push($out_data, '0');
array_push($tot_data, '0');
array_push($allow_data, $allowed);
array_push($overuse_data, '0');
array_push($ticklabels, '');
}
}
$yaxistitle = 'Gigabytes';
$graph_name = 'Historical bandwidth over the last 12 billing periods';
} else {
$data = array();
$average = 0;
if ($imgtype == 'day') {
foreach (dbFetch('SELECT DISTINCT UNIX_TIMESTAMP(timestamp) as timestamp, SUM(delta) as traf_total, SUM(in_delta) as traf_in, SUM(out_delta) as traf_out FROM bill_data WHERE `bill_id` = ? AND `timestamp` >= FROM_UNIXTIME(?) AND `timestamp` <= FROM_UNIXTIME(?) GROUP BY DATE(timestamp) ORDER BY timestamp ASC', array($bill_id, $start, $end)) as $data) {
$traf['in'] = (isset($data['traf_in']) ? $data['traf_in'] : 0);
$traf['out'] = (isset($data['traf_out']) ? $data['traf_out'] : 0);
$traf['total'] = (isset($data['traf_total']) ? $data['traf_total'] : 0);
$datelabel = strftime("%e\n%b", $data['timestamp']);
array_push($ticklabels, $datelabel);
array_push($in_data, $traf['in']);
array_push($out_data, $traf['out']);
array_push($tot_data, $traf['total']);
$average += $data['traf_total'];
}
$ave_count = count($tot_data);
if ($imgbill != false) {
$days = (strftime('%e', date($end - $start)) - $ave_count - 1);
for ($x = 0; $x < $days; $x++) {
array_push($ticklabels, '');
array_push($in_data, 0);
array_push($out_data, 0);
array_push($tot_data, 0);
}
}
} elseif ($imgtype == 'hour') {
foreach (dbFetch('SELECT DISTINCT UNIX_TIMESTAMP(timestamp) as timestamp, SUM(delta) as traf_total, SUM(in_delta) as traf_in, SUM(out_delta) as traf_out FROM bill_data WHERE `bill_id` = ? AND `timestamp` >= FROM_UNIXTIME(?) AND `timestamp` <= FROM_UNIXTIME(?) GROUP BY HOUR(timestamp) ORDER BY timestamp ASC', array($bill_id, $start, $end)) as $data) {
$traf['in'] = (isset($data['traf_in']) ? $data['traf_in'] : 0);
$traf['out'] = (isset($data['traf_out']) ? $data['traf_out'] : 0);
$traf['total'] = (isset($data['traf_total']) ? $data['traf_total'] : 0);
$datelabel = strftime('%H:%M', $data['timestamp']);
array_push($ticklabels, $datelabel);
array_push($in_data, $traf['in']);
array_push($out_data, $traf['out']);
array_push($tot_data, $traf['total']);
$average += $data['traf_total'];
}
$ave_count = count($tot_data);
}//end if
$decimal = 0;
$average = ($average / $ave_count);
for ($x = 0; $x <= count($tot_data); $x++) {
array_push($ave_data, $average);
}
$graph_name = date('M j g:ia', $start).' - '.date('M j g:ia', $end);
}//end if
// Create the graph. These two calls are always required
$graph = new Graph($xsize, $ysize, $graph_name);
$graph->img->SetImgFormat('png');
// $graph->SetScale("textlin",0,0,$start,$end);
$graph->SetScale('textlin');
// $graph->title->Set("$graph_name");
$graph->title->SetFont(FF_FONT2, FS_BOLD, 10);
$graph->SetMarginColor('white');
$graph->SetFrame(false);
$graph->SetMargin('75', '30', '30', '65');
$graph->legend->SetFont(FF_FONT1, FS_NORMAL);
$graph->legend->SetLayout(LEGEND_HOR);
$graph->legend->Pos('0.52', '0.91', 'center');
$graph->xaxis->SetFont(FF_FONT1, FS_BOLD);
$graph->xaxis->SetPos('min');
$graph->xaxis->SetTitleMargin(30);
$graph->xaxis->SetTickLabels($ticklabels);
$graph->xgrid->Show(true, true);
$graph->xgrid->SetColor('#e0e0e0', '#efefef');
$graph->yaxis->SetFont(FF_FONT1);
$graph->yaxis->SetTitleMargin(50);
$graph->yaxis->title->SetFont(FF_FONT1, FS_NORMAL, 10);
$graph->yaxis->title->Set('Bytes Transferred');
$graph->yaxis->SetLabelFormatCallback('format_bytes_billing');
$graph->ygrid->SetFill(true, '#EFEFEF@0.5', '#FFFFFF@0.5');
// Create the bar plots
$barplot_tot = new BarPlot($tot_data);
$barplot_tot->SetLegend('Traffic total');
$barplot_tot->SetColor('darkgray');
$barplot_tot->SetFillColor('lightgray@0.4');
$barplot_tot->value->Show();
$barplot_tot->value->SetFormatCallback('format_bytes_billing_short');
$barplot_in = new BarPlot($in_data);
$barplot_in->SetLegend('Traffic In');
$barplot_in->SetColor('darkgreen');
$barplot_in->SetFillColor('lightgreen@0.4');
$barplot_in->SetWeight(1);
$barplot_out = new BarPlot($out_data);
$barplot_out->SetLegend('Traffic Out');
$barplot_out->SetColor('darkblue');
$barplot_out->SetFillColor('lightblue@0.4');
$barplot_out->SetWeight(1);
if ($imgtype == 'historical') {
$barplot_over = new BarPlot($overuse_data);
$barplot_over->SetLegend('Traffic Overusage');
$barplot_over->SetColor('darkred');
$barplot_over->SetFillColor('lightred@0.4');
$barplot_over->SetWeight(1);
$lineplot_allow = new LinePlot($allow_data);
$lineplot_allow->SetLegend('Traffic Allowed');
$lineplot_allow->SetColor('black');
$lineplot_allow->SetWeight(1);
$gbplot = new GroupBarPlot(array($barplot_in, $barplot_tot, $barplot_out, $barplot_over));
} else {
$lineplot_allow = new LinePlot($ave_data);
// $lineplot_allow->SetLegend("Average per ".$imgtype);
$lineplot_allow->SetLegend('Average');
$lineplot_allow->SetColor('black');
$lineplot_allow->SetWeight(1);
$gbplot = new GroupBarPlot(array($barplot_in, $barplot_tot, $barplot_out));
}//end if
$graph->Add($gbplot);
$graph->Add($lineplot_allow);
// Display the graph
$graph->Stroke();
header("Location: $url", false, 301);
exit;

View File

@@ -9,251 +9,41 @@
* @copyright (C) 2006 - 2012 Adam Armstrong
*/
use Amenadiel\JpGraph\Graph\Graph;
use Amenadiel\JpGraph\Plot\LinePlot;
ini_set('allow_url_fopen', 0);
if (strpos($_SERVER['REQUEST_URI'], 'debug')) {
$debug = '1';
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('log_errors', 1);
ini_set('error_reporting', E_ALL);
} else {
$debug = false;
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
ini_set('log_errors', 0);
ini_set('error_reporting', 0);
}
$init_modules = array('web', 'auth');
require realpath(__DIR__ . '/..') . '/includes/init.php';
$auth = is_client_authorized($_SERVER['REMOTE_ADDR']);
if (get_client_ip() != $_SERVER['SERVER_ADDR']) {
if ($auth === false && !$_SESSION['authenticated']) {
echo 'unauthenticated';
exit;
}
}
if (is_numeric($_GET['bill_id'])) {
if (get_client_ip() != $_SERVER['SERVER_ADDR']) {
if ($auth === true || bill_permitted($_GET['bill_id'])) {
$bill_id = $_GET['bill_id'];
} else {
echo 'Unauthorised Access Prohibited.';
exit;
}
} else {
$bill_id = $_GET['bill_id'];
}
$urlargs = array(
'type' => 'bill_historicbits',
'id' => $_GET['bill_id'],
'width' => $_GET['x'],
'height' => $_GET['y']
);
if (isset($_GET['bill_hist_id'])) {
$urlargs['bill_hist_id'] = $_GET['bill_hist_id'];
} else {
echo 'Unauthorised Access Prohibited.';
exit;
$urlargs['from'] = $_GET['from'];
$urlargs['to'] = $_GET['to'];
}
$rate_data = dbFetchRow('SELECT * from `bills` WHERE `bill_id`= ? LIMIT 1', array($bill_id));
$bill_name = $rate_data['bill_name'];
if (is_numeric($_GET['bill_id']) && is_numeric($_GET['bill_hist_id'])) {
$histrow = dbFetchRow('SELECT UNIX_TIMESTAMP(bill_datefrom) as `from`, UNIX_TIMESTAMP(bill_dateto) AS `to`, rate_95th, rate_average FROM bill_history WHERE bill_id = ? AND bill_hist_id = ?', array($_GET['bill_id'], $_GET['bill_hist_id']));
if (is_null($histrow)) {
header("HTTP/1.0 404 Not Found");
exit();
}
$start = $histrow['from'];
$end = $histrow['to'];
$rate_95th = $histrow['rate_95th'];
$rate_average = $histrow['rate_average'];
} else {
$start = $_GET['from'];
$end = $_GET['to'];
$rate_95th = $rate_data['rate_95th'];
$rate_average = $rate_data['rate_average'];
if (isset($_GET['count'])) {
$urlargs['reducefactor'] = $_GET['count'];
}
$xsize = $_GET['x'];
$ysize = $_GET['y'];
$count = $_GET['count'];
$count = ($count + 0);
$iter = 1;
if ($_GET['type']) {
$type = $_GET['type'];
} else {
$type = 'date';
}
$dur = ($end - $start);
$datefrom = date('Ymthis', $start);
$dateto = date('Ymthis', $end);
$dur = ($end - $start);
$counttot = dbFetchCell('SELECT count(`delta`) FROM `bill_data` WHERE `bill_id` = ? AND `timestamp` >= FROM_UNIXTIME( ? ) AND `timestamp` <= FROM_UNIXTIME( ? )', array($bill_id, $start, $end));
$count = round(($dur / 300 / (($ysize - 100) * 3)), 0);
if ($count <= 1) {
$count = 2;
}
// $count = round($counttot / 260, 0);
// if ($count <= 1) { $count = 2; }
// $max = dbFetchCell("SELECT delta FROM bill_data WHERE bill_id = ? AND `timestamp` >= FROM_UNIXTIME( ? ) AND `timestamp` <= FROM_UNIXTIME( ? ) ORDER BY delta DESC LIMIT 0,1", array($bill_id, $start, $end));
// if ($max > 1000000) { $div = "1000000"; $yaxis = "Mbit/sec"; } else { $div = "1000"; $yaxis = "Kbit/sec"; }
$i = '0';
foreach (dbFetch('SELECT *, UNIX_TIMESTAMP(timestamp) AS formatted_date FROM bill_data WHERE bill_id = ? AND `timestamp` >= FROM_UNIXTIME( ? ) AND `timestamp` <= FROM_UNIXTIME( ? ) ORDER BY timestamp ASC', array($bill_id, $start, $end)) as $row) {
$timestamp = $row['formatted_date'];
if (!$first) {
$first = $timestamp;
}
$delta = $row['delta'];
$period = $row['period'];
$in_delta = $row['in_delta'];
$out_delta = $row['out_delta'];
$in_value = delta_to_bits($in_delta, $period);
$out_value = delta_to_bits($out_delta, $period);
$last = $timestamp;
$iter_in += $in_delta;
$iter_out += $out_delta;
$iter_period += $period;
if ($iter == $count) {
$out_data[$i] = round(($iter_out * 8 / $iter_period), 2);
$out_data_inv[$i] = ($out_data[$i] * -1);
$in_data[$i] = round(($iter_in * 8 / $iter_period), 2);
$tot_data[$i] = ($out_data[$i] + $in_data[$i]);
$tot_data_inv[$i] = ($tot_data[$i] * -1);
if ($tot_data[$i] > $max_value) {
$max_value = $tot_data[$i];
}
$ticks[$i] = $timestamp;
$per_data[$i] = $rate_95th;
$ave_data[$i] = $rate_average;
$iter = '1';
$i++;
unset($iter_out, $iter_in, $iter_period);
}
$iter++;
}//end foreach
$graph_name = date('M j g:ia', $start).' - '.date('M j g:ia', $last);
$n = count($ticks);
$xmin = $ticks[0];
$xmax = $ticks[($n - 1)];
$graph_name = date('M j g:ia', $xmin).' - '.date('M j g:ia', $xmax);
$graph = new Graph($xsize, $ysize, $graph_name);
$graph->img->SetImgFormat('png');
$graph->SetScale('datlin', 0, 0, $start, $end);
// $graph->title->Set("$graph_name");
$graph->title->SetFont(FF_FONT2, FS_BOLD, 10);
$graph->xaxis->SetFont(FF_FONT1, FS_BOLD);
$graph->xaxis->SetTextLabelInterval(2);
$graph->xaxis->SetPos('min');
// $graph->xaxis->SetLabelAngle(15);
$graph->yaxis->HideZeroLabel(1);
$graph->yaxis->SetFont(FF_FONT1);
$graph->yaxis->SetLabelAngle(0);
$graph->xaxis->title->SetFont(FF_FONT1, FS_NORMAL, 10);
$graph->yaxis->title->SetFont(FF_FONT1, FS_NORMAL, 10);
$graph->yaxis->SetTitleMargin(50);
$graph->xaxis->SetTitleMargin(30);
// $graph->xaxis->HideLastTickLabel();
// $graph->xaxis->HideFirstTickLabel();
// $graph->yaxis->scale->SetAutoMin(1);
$graph->xaxis->title->Set($type);
$graph->yaxis->title->Set('Bits per second');
$graph->yaxis->SetLabelFormatCallback('format_si');
function TimeCallback($aVal)
{
global $dur;
if ($dur < 172800) {
return date('H:i', $aVal);
} elseif ($dur < 604800) {
return date('D', $aVal);
} else {
return date('j M', $aVal);
}
}//end TimeCallback()
$graph->xaxis->SetLabelFormatCallback('TimeCallBack');
$graph->ygrid->SetFill(true, '#EFEFEF@0.5', '#FFFFFF@0.5');
$graph->xgrid->Show(true, true);
$graph->xgrid->SetColor('#e0e0e0', '#efefef');
$graph->SetMarginColor('white');
$graph->SetFrame(false);
$graph->SetMargin(75, 30, 30, 45);
$graph->legend->SetFont(FF_FONT1, FS_NORMAL);
$lineplot = new LinePlot($tot_data, $ticks);
$lineplot->SetLegend('Traffic total');
$lineplot->SetColor('#d5d5d5');
$lineplot->SetFillColor('#d5d5d5@0.5');
// $lineplot2 = new LinePlot($tot_data_inv, $ticks);
// $lineplot2->SetColor("#d5d5d5");
// $lineplot2->SetFillColor("#d5d5d5@0.5");
$lineplot_in = new LinePlot($in_data, $ticks);
$lineplot_in->SetLegend('Traffic In');
$lineplot_in->SetColor('darkgreen');
$lineplot_in->SetFillColor('lightgreen@0.4');
$lineplot_in->SetWeight(1);
$lineplot_out = new LinePlot($out_data_inv, $ticks);
$lineplot_out->SetLegend('Traffic Out');
$lineplot_out->SetColor('darkblue');
$lineplot_out->SetFillColor('lightblue@0.4');
$lineplot_out->SetWeight(1);
if (isset($_GET['95th'])) {
$lineplot_95th = new LinePlot($per_data, $ticks);
$lineplot_95th->SetColor('red');
$urlargs['95th'] = $_GET['95th'];
}
if (isset($_GET['ave'])) {
$lineplot_ave = new LinePlot($ave_data, $ticks);
$lineplot_ave->SetColor('red');
$urlargs['ave'] = $_GET['ave'];
}
$graph->legend->SetLayout(LEGEND_HOR);
$graph->legend->Pos(0.52, 0.90, 'center');
$graph->Add($lineplot);
// $graph->Add($lineplot2);
$graph->Add($lineplot_in);
$graph->Add($lineplot_out);
if (isset($_GET['95th'])) {
$graph->Add($lineplot_95th);
$url = "{$config['base_url']}graph.php?";
$i = 0;
foreach ($urlargs as $name => $value) {
if ($i++ > 0) {
$url .= '&';
}
$url .= "$name=$value";
}
if (isset($_GET['ave'])) {
$graph->Add($lineplot_ave);
}
$graph->stroke();
header("Location: $url", false, 301);
exit;

View File

@@ -1320,25 +1320,157 @@ function list_bills()
api_success($bills, 'bills');
}
function get_bill_graph()
{
global $config;
$app = \Slim\Slim::getInstance();
$router = $app->router()->getCurrentRoute()->getParams();
$bill_id = mres($router['bill_id']);
$graph_type = $router['graph_type'];
if (!is_admin() && !is_read()) {
check_bill_permission($bill_id);
}
if ($graph_type == 'monthly') {
$graph_type = 'historicmonthly';
}
$vars = array();
$vars['type'] = "bill_$graph_type";
$vars['id'] = $bill_id;
$vars['width'] = $_GET['width'] ?: 1075;
$vars['height'] = $_GET['height'] ?: 300;
$app->response->headers->set('Content-Type', 'image/png');
include 'includes/graphs/graph.inc.php';
}
function get_bill_graphdata()
{
global $config;
$app = \Slim\Slim::getInstance();
$router = $app->router()->getCurrentRoute()->getParams();
$bill_id = mres($router['bill_id']);
$graph_type = $router['graph_type'];
if (!is_admin() && !is_read()) {
check_bill_permission($bill_id);
}
if ($graph_type == 'bits') {
$from = (isset($_GET['from']) ? $_GET['from'] : time() - 60 * 60 * 24);
$to = (isset($_GET['to']) ? $_GET['to'] : time());
$reducefactor = $_GET['reducefactor'];
$graph_data = getBillingBitsGraphData($bill_id, $from, $to, $reducefactor);
} else if ($graph_type == 'monthly') {
$graph_data = getHistoricTransferGraphData($bill_id);
}
if (!isset($graph_data)) {
api_error(400, "Unsupported graph type $graph_type");
} else {
api_success($graph_data, 'graph_data');
}
}
function get_bill_history()
{
global $config;
$app = \Slim\Slim::getInstance();
$router = $app->router()->getCurrentRoute()->getParams();
$bill_id = mres($router['bill_id']);
if (!is_admin() && !is_read()) {
check_bill_permission($bill_id);
}
$result = [];
foreach (dbFetchRows('SELECT * FROM `bill_history` WHERE `bill_id` = ? ORDER BY `bill_datefrom` DESC LIMIT 24', array($bill_id)) as $history) {
$result[] = $history;
}
api_success($result, 'bill_history');
}
function get_bill_history_graph()
{
global $config;
$app = \Slim\Slim::getInstance();
$router = $app->router()->getCurrentRoute()->getParams();
$bill_id = mres($router['bill_id']);
$bill_hist_id = mres($router['bill_hist_id']);
$graph_type = $router['graph_type'];
if (!is_admin() && !is_read()) {
check_bill_permission($bill_id);
}
$vars = array();
switch ($graph_type) {
case 'bits':
$graph_type = 'historicbits';
$vars['reducefactor'] = $_GET['reducefactor'];
break;
case 'day':
case 'hour':
$vars['imgtype'] = $graph_type;
$graph_type = 'historictransfer';
break;
default:
api_error(400, "Unknown Graph Type $graph_type");
break;
}
global $dur; // Needed for callback within graph code
$vars['type'] = "bill_$graph_type";
$vars['id'] = $bill_id;
$vars['bill_hist_id'] = $bill_hist_id;
$vars['width'] = $_GET['width'] ?: 1075;
$vars['height'] = $_GET['height'] ?: 300;
$app->response->headers->set('Content-Type', 'image/png');
include 'includes/graphs/graph.inc.php';
}
function get_bill_history_graphdata()
{
global $config;
$app = \Slim\Slim::getInstance();
$router = $app->router()->getCurrentRoute()->getParams();
$bill_id = mres($router['bill_id']);
$bill_hist_id = mres($router['bill_hist_id']);
$graph_type = $router['graph_type'];
if (!is_admin() && !is_read()) {
check_bill_permission($bill_id);
}
switch ($graph_type) {
case 'bits':
$reducefactor = $_GET['reducefactor'];
$graph_data = getBillingHistoryBitsGraphData($bill_id, $bill_hist_id, $reducefactor);
break;
case 'day':
case 'hour':
$graph_data = getBillingBandwidthGraphData($bill_id, $bill_hist_id, null, null, $graph_type);
break;
}
if (!isset($graph_data)) {
api_error(400, "Unsupported graph type $graph_type");
} else {
api_success($graph_data, 'graph_data');
}
}
function update_device()
{
check_is_admin();

View File

@@ -1,16 +1,8 @@
<?php
// Authorises bill viewing and sets $ports as reference to mysql query containing ports for this bill
if (is_numeric($_GET['id']) && ($auth || bill_permitted($_GET['id']))) {
$bill = dbFetchRow('SELECT * FROM `bills` WHERE bill_id = ?', array($_GET['id']));
$datefrom = date('YmdHis', $_GET['from']);
$dateto = date('YmdHis', $_GET['to']);
$rates = getRates($_GET['id'], $datefrom, $dateto);
$ports = dbFetchRows('SELECT * FROM `bill_ports` AS B, `ports` AS P, `devices` AS D WHERE B.bill_id = ? AND P.port_id = B.port_id AND D.device_id = P.device_id', array($_GET['id']));
// Authorises bill viewing
if (is_numeric($vars['id']) && ($auth || bill_permitted($vars['id']))) {
$bill_id = mres($vars['id']);
$bill = dbFetchRow('SELECT * FROM `bills` WHERE bill_id = ?', array($bill_id));
$auth = true;
}

View File

@@ -1,5 +1,12 @@
<?php
$datefrom = date('YmdHis', $vars['from']);
$dateto = date('YmdHis', $vars['to']);
$rates = getRates($vars['id'], $datefrom, $dateto);
$ports = dbFetchRows('SELECT * FROM `bill_ports` AS B, `ports` AS P, `devices` AS D WHERE B.bill_id = ? AND P.port_id = B.port_id AND D.device_id = P.device_id', array($vars['id']));
// Generate a list of ports and then call the multi_bits grapher to generate from the list
$i = 0;

View File

@@ -0,0 +1,132 @@
<?php
use Amenadiel\JpGraph\Graph\Graph;
use Amenadiel\JpGraph\Plot\LinePlot;
$bill_hist_id = mres($vars['bill_hist_id']);
$reducefactor = mres($vars['reducefactor']);
if (is_numeric($bill_hist_id)) {
if ($reducefactor < 2) {
$extents = dbFetchRow('SELECT UNIX_TIMESTAMP(bill_datefrom) as `from`, UNIX_TIMESTAMP(bill_dateto) AS `to`FROM bill_history WHERE bill_id = ? AND bill_hist_id = ?', array($bill_id, $bill_hist_id));
$dur = $extents['to'] - $extents['from'];
$reducefactor = round(($dur / 300 / (($vars['height'] - 100) * 3)), 0);
if ($reducefactor < 2) {
$reducefactor = 2;
}
}
$graph_data = getBillingHistoryBitsGraphData($bill_id, $bill_hist_id, $reducefactor);
} else {
if ($reducefactor < 2) {
$dur = $vars['to'] - $vars['from'];
$reducefactor = round(($dur / 300 / (($vars['height'] - 100) * 3)), 0);
if ($reducefactor < 2) {
$reducefactor = 2;
}
}
$graph_data = getBillingBitsGraphData($bill_id, $vars['from'], $vars['to'], $reducefactor);
}
// header('Content-Type: application/json');
// print_r(json_encode($graph_data));
// exit();
$n = count($graph_data['ticks']);
$xmin = $graph_data['ticks'][0];
$xmax = $graph_data['ticks'][($n - 1)];
function TimeCallback($aVal)
{
global $dur;
if ($dur < 172800) {
return date('H:i', $aVal);
} elseif ($dur < 604800) {
return date('D', $aVal);
} else {
return date('j M', $aVal);
}
}//end TimeCallback()
function InvertCallback($x)
{
return $x * -1;
}//end InvertCallback
function YCallback($y)
{
return format_si($y, 2, 0);
}
$graph = new Graph($vars['width'], $vars['height'], $graph_data['graph_name']);
$graph->img->SetImgFormat('png');
$graph->SetScale('datlin', 0, 0, $graph_data['from'], $graph_data['to']);
$graph->SetMarginColor('white');
$graph->SetFrame(false);
$graph->SetMargin('75', '30', '30', '65');
$graph->legend->SetFont(FF_FONT1, FS_NORMAL);
$graph->legend->SetLayout(LEGEND_HOR);
$graph->legend->Pos('0.52', '0.91', 'center');
$graph->xaxis->SetFont(FF_FONT1, FS_BOLD);
$graph->xaxis->SetPos('min');
$graph->xaxis->SetTitleMargin(30);
$graph->xaxis->SetTextLabelInterval(2);
$graph->xaxis->SetLabelFormatCallback('TimeCallBack');
$graph->yaxis->SetFont(FF_FONT1);
$graph->yaxis->SetTitleMargin(50);
$graph->yaxis->SetLabelFormatCallback('YCallback');
$graph->yaxis->HideZeroLabel(1);
$graph->yaxis->title->SetFont(FF_FONT1, FS_NORMAL, 10);
$graph->yaxis->title->Set('Bits per second');
$graph->xgrid->Show(true, true);
$graph->xgrid->SetColor('#e0e0e0', '#efefef');
$graph->ygrid->SetFill(true, '#EFEFEF@0.5', '#FFFFFF@0.5');
// Graph Series
$lineplot = new LinePlot($graph_data['tot_data'], $graph_data['ticks']);
$lineplot->SetLegend('Traffic total');
$lineplot->SetColor('#d5d5d5');
$lineplot->SetFillColor('#d5d5d5@0.5');
$lineplot_in = new LinePlot($graph_data['in_data'], $graph_data['ticks']);
$lineplot_in->SetLegend('Traffic In');
$lineplot_in->SetColor('darkgreen');
$lineplot_in->SetFillColor('lightgreen@0.4');
$lineplot_in->SetWeight(1);
$lineplot_out = new LinePlot(array_map('InvertCallback', $graph_data['out_data']), $graph_data['ticks']);
$lineplot_out->SetLegend('Traffic Out');
$lineplot_out->SetColor('darkblue');
$lineplot_out->SetFillColor('lightblue@0.4');
$lineplot_out->SetWeight(1);
if (strtolower($graph_data['bill_type']) == 'cdr') {
$lineplot_95th = new LinePlot(array($graph_data['rate_95th'], $graph_data['rate_95th']), array($xmin, $xmax));
$lineplot_95th->SetColor('red');
} else if (strtolower($graph_data['bill_type']) == 'quota') {
$lineplot_ave = new LinePlot(array($graph_data['rate_average'], $graph_data['rate_average']), array($xmin, $xmax));
$lineplot_ave->SetColor('red');
}
$graph->legend->SetLayout(LEGEND_HOR);
$graph->legend->Pos(0.52, 0.90, 'center');
$graph->Add($lineplot);
$graph->Add($lineplot_in);
$graph->Add($lineplot_out);
if (strtolower($graph_data['bill_type']) == 'cdr') {
$graph->Add($lineplot_95th);
} else if (strtolower($graph_data['bill_type']) == 'quota') {
$graph->Add($lineplot_ave);
}
$graph->stroke();

View File

@@ -0,0 +1,100 @@
<?php
use Amenadiel\JpGraph\Graph\Graph;
use Amenadiel\JpGraph\Plot\BarPlot;
use Amenadiel\JpGraph\Plot\GroupBarPlot;
use Amenadiel\JpGraph\Plot\LinePlot;
$graph_data = getHistoricTransferGraphData($vars['id']);
// Reformat date labels
for ($i = 0; $i < count($graph_data['ticklabels']); $i++) {
if ($graph_data['ticklabels'][$i]) {
$parts = explode(' - ', $graph_data['ticklabels'][$i]);
$start = strtotime($parts[0]);
$end = strtotime($parts[1]);
if (date('m', $start) == date('m', $end) && date('d', $start == 1)) {
// Calendar months, omit the date and the end!
$graph_data['ticklabels'][$i] = strftime("%b %Y", $start);
} else {
$graph_data['ticklabels'][$i] = strftime("%e %b %Y", $start) . "\n" . strftime("%e %b %Y", $end);
}
}
}
// Create the graph. These two calls are always required
$graph = new Graph($vars['width'], $vars['height'], $graph_data['graph_name']);
$graph->img->SetImgFormat('png');
$graph->SetScale('textlin');
// $graph->title->Set("$graph_name");
$graph->title->SetFont(FF_FONT2, FS_BOLD, 10);
$graph->SetMarginColor('white');
$graph->SetFrame(false);
$graph->SetMargin('75', '30', '30', '65');
$graph->legend->SetFont(FF_FONT1, FS_NORMAL);
$graph->legend->SetLayout(LEGEND_HOR);
$graph->legend->Pos('0.52', '0.91', 'center');
$graph->xaxis->SetFont(FF_FONT1, FS_BOLD);
$graph->xaxis->SetPos('min');
$graph->xaxis->SetTitleMargin(30);
$graph->xaxis->SetTickLabels($graph_data['ticklabels']);
$graph->xgrid->Show(true, true);
$graph->xgrid->SetColor('#e0e0e0', '#efefef');
function YCallback($value)
{
global $config;
return format_number($value, $config['billing']['base'], 2, 1).'B';
}
$graph->yaxis->SetFont(FF_FONT1);
$graph->yaxis->SetTitleMargin(50);
$graph->yaxis->title->SetFont(FF_FONT1, FS_NORMAL, 10);
$graph->yaxis->title->Set('Bytes Transferred');
$graph->yaxis->SetLabelFormatCallback('YCallback');
$graph->ygrid->SetFill(true, '#EFEFEF@0.5', '#FFFFFF@0.5');
// Create the bar plots
$barplot_tot = new BarPlot($graph_data['tot_data']);
$barplot_tot->SetLegend('Traffic total');
$barplot_tot->SetColor('darkgray');
$barplot_tot->SetFillColor('lightgray@0.4');
$barplot_tot->value->Show();
$barplot_tot->value->SetFormatCallback('format_bytes_billing_short');
$barplot_in = new BarPlot($graph_data['in_data']);
$barplot_in->SetLegend('Traffic In');
$barplot_in->SetColor('darkgreen');
$barplot_in->SetFillColor('lightgreen@0.4');
$barplot_in->SetWeight(1);
$barplot_out = new BarPlot($graph_data['out_data']);
$barplot_out->SetLegend('Traffic Out');
$barplot_out->SetColor('darkblue');
$barplot_out->SetFillColor('lightblue@0.4');
$barplot_out->SetWeight(1);
$barplot_over = new BarPlot($graph_data['overuse_data']);
$barplot_over->SetLegend('Traffic Overusage');
$barplot_over->SetColor('darkred');
$barplot_over->SetFillColor('lightred@0.4');
$barplot_over->SetWeight(1);
$lineplot_allow = new LinePlot($graph_data['allow_data']);
$lineplot_allow->SetLegend('Traffic Allowed');
$lineplot_allow->SetColor('black');
$lineplot_allow->SetWeight(1);
$gbplot = new GroupBarPlot(array($barplot_in, $barplot_tot, $barplot_out, $barplot_over));
$graph->Add($gbplot);
$graph->Add($lineplot_allow);
// Display the graph
$graph->Stroke();

View File

@@ -0,0 +1,97 @@
<?php
use Amenadiel\JpGraph\Graph\Graph;
use Amenadiel\JpGraph\Plot\BarPlot;
use Amenadiel\JpGraph\Plot\GroupBarPlot;
use Amenadiel\JpGraph\Plot\LinePlot;
if (is_numeric($vars['bill_hist_id'])) {
$graph_data = getBillingBandwidthGraphData($vars['id'], $vars['bill_hist_id'], null, null, $vars['imgtype']);
} else if (is_numeric($vars['from'])) {
$graph_data = getBillingBandwidthGraphData($vars['id'], null, $vars['from'], $vars['to'], $vars['imgtype']);
} else {
$graph_data = getHistoricTransferGraphData($vars['id']);
$vars['imgtype'] = 'historical';
}
// Reformat date labels
for ($i = 0; $i < count($graph_data['ticklabels']); $i++) {
if ($graph_data['ticklabels'][$i]) {
$date = strtotime($graph_data['ticklabels'][$i]);
if ($vars['imgtype'] === 'day') {
$graph_data['ticklabels'][$i] = strftime("%e\n%b", $date);
}
}
}
// Create the graph. These two calls are always required
$graph = new Graph($vars['width'], $vars['height'], $graph_data['graph_name']);
$graph->img->SetImgFormat('png');
$graph->SetScale('textlin');
$graph->title->SetFont(FF_FONT2, FS_BOLD, 10);
$graph->SetMarginColor('white');
$graph->SetFrame(false);
$graph->SetMargin('75', '30', '30', '65');
$graph->legend->SetFont(FF_FONT1, FS_NORMAL);
$graph->legend->SetLayout(LEGEND_HOR);
$graph->legend->Pos('0.52', '0.91', 'center');
$graph->xaxis->SetFont(FF_FONT1, FS_BOLD);
$graph->xaxis->SetPos('min');
$graph->xaxis->SetTitleMargin(30);
$graph->xaxis->SetTickLabels($graph_data['ticklabels']);
$graph->xgrid->Show(true, true);
$graph->xgrid->SetColor('#e0e0e0', '#efefef');
function YCallback($value)
{
global $config;
return format_number($value, $config['billing']['base'], 2, 1).'B';
}
$graph->yaxis->SetFont(FF_FONT1);
$graph->yaxis->SetTitleMargin(50);
$graph->yaxis->title->SetFont(FF_FONT1, FS_NORMAL, 10);
$graph->yaxis->title->Set('Bytes Transferred');
$graph->yaxis->SetLabelFormatCallback('YCallback');
$graph->ygrid->SetFill(true, '#EFEFEF@0.5', '#FFFFFF@0.5');
// Create the bar plots
$barplot_tot = new BarPlot($graph_data['tot_data']);
$barplot_tot->SetLegend('Traffic total');
$barplot_tot->SetColor('darkgray');
$barplot_tot->SetFillColor('lightgray@0.4');
$barplot_tot->value->Show();
$barplot_tot->value->SetFormatCallback('format_bytes_billing_short');
$barplot_in = new BarPlot($graph_data['in_data']);
$barplot_in->SetLegend('Traffic In');
$barplot_in->SetColor('darkgreen');
$barplot_in->SetFillColor('lightgreen@0.4');
$barplot_in->SetWeight(1);
$barplot_out = new BarPlot($graph_data['out_data']);
$barplot_out->SetLegend('Traffic Out');
$barplot_out->SetColor('darkblue');
$barplot_out->SetFillColor('lightblue@0.4');
$barplot_out->SetWeight(1);
$lineplot_allow = new LinePlot($graph_data['ave_data']);
// $lineplot_allow->SetLegend("Average per ".$imgtype);
$lineplot_allow->SetLegend('Average');
$lineplot_allow->SetColor('black');
$lineplot_allow->SetWeight(1);
$gbplot = new GroupBarPlot(array($barplot_in, $barplot_tot, $barplot_out));
$graph->Add($gbplot);
$graph->Add($lineplot_allow);
// Display the graph
$graph->Stroke();

View File

@@ -5,9 +5,9 @@ $pagetitle[] = 'Historical Usage';
// $url = $PHP_SELF."/bill/".$bill_id."/history/";
$i = 0;
$img['his'] = '<img src="bandwidth-graph.php?bill_id='.$bill_id;
$img['his'] .= '&amp;type=historical';
$img['his'] .= '&amp;x=1190&amp;y=250';
$img['his'] = '<img src="graph.php?id='.$bill_id;
$img['his'] .= '&amp;type=bill_historicmonthly';
$img['his'] .= '&amp;width=1190&amp;height=250';
$img['his'] .= '" style="margin: 15px 5px 25px 5px;" />';
?>
@@ -22,23 +22,20 @@ $img['his'] .= '" style="margin: 15px 5px 25px 5px;" />';
<?php
function showDetails($bill_id, $imgtype, $bill_hist_id, $bittype = 'Quota')
function showDetails($bill_id, $imgtype, $bill_hist_id)
{
if ($imgtype == 'bitrate') {
$res = '<img src="billing-graph.php?bill_id='.$bill_id;
if ($bittype == 'Quota') {
$res .= '&amp;ave=yes';
} elseif ($bittype == 'CDR') {
$res .= '&amp;95th=yes';
}
} else {
$res = '<img src="bandwidth-graph.php?bill_id='.$bill_id;
}
$res = '<img src="graph.php?id='.$bill_id;
// $res .= "&amp;type=".$type;
$res .= '&amp;type='.$imgtype;
$res .= '&amp;x=1190&amp;y=250';
$res .= '&amp;bill_hist_id='.$bill_hist_id;
if ($imgtype == 'bitrate') {
$res .= '&amp;type=bill_historicbits';
} else {
$res .= '&amp;type=bill_historictransfer';
$res .= '&amp;imgtype='.$imgtype;
}
$res .= '&amp;width=1190&amp;height=250';
if (is_numeric($bill_hist_id)) {
$res .= '&amp;bill_hist_id='.$bill_hist_id;
}
$res .= '" style="margin: 15px 5px 25px 5px;" />';
return $res;
}//end showDetails()
@@ -116,7 +113,7 @@ foreach (dbFetchRows('SELECT * FROM `bill_history` WHERE `bill_id` = ? ORDER BY
</tr>';
if ($vars['detail'] == $history['bill_hist_id'] || $vars['detail'] == 'all') {
$img['bitrate'] = showDetails($bill_id, 'bitrate', $history['bill_hist_id'], $type);
$img['bitrate'] = showDetails($bill_id, 'bitrate', $history['bill_hist_id']);
$img['bw_day'] = showDetails($bill_id, 'day', $history['bill_hist_id']);
$img['bw_hour'] = showDetails($bill_id, 'hour', $history['bill_hist_id']);
echo '

View File

@@ -152,29 +152,23 @@ function showPercent($per)
<?php
$bi = "<img src='bandwidth-graph.php?bill_id=".$bill_id.'&amp;bill_code='.$_GET['bill_code'];
$bi = "<img src='graph.php?type=bill_historictransfer&id=".$bill_id;
$bi .= '&amp;from='.$unixfrom.'&amp;to='.$unixto;
$bi .= '&amp;type=day&imgbill=1';
$bi .= '&amp;x=1190&amp;y=250';
$bi .= "$type'>";
$bi .= '&amp;imgtype=day';
$bi .= '&amp;width=1190&amp;height=250';
$bi .= "'>";
$li = "<img src='bandwidth-graph.php?bill_id=".$bill_id.'&amp;bill_code='.$_GET['bill_code'];
$li .= '&amp;from='.$unix_prev_from.'&amp;to='.$unix_prev_to;
$li .= '&amp;type=day';
$li .= '&amp;x=1190&amp;y=250';
$li .= "$type'>";
$di = "<img src='bandwidth-graph.php?bill_id=".$bill_id.'&amp;bill_code='.$_GET['bill_code'];
$di = "<img src='graph.php?type=bill_historictransfer&id=".$bill_id;
$di .= '&amp;from='.$config['time']['day'].'&amp;to='.$config['time']['now'];
$di .= '&amp;type=hour';
$di .= '&amp;x=1190&amp;y=250';
$di .= "$type'>";
$di .= '&amp;imgtype=hour';
$di .= '&amp;width=1190&amp;height=250';
$di .= "'>";
$mi = "<img src='bandwidth-graph.php?bill_id=".$bill_id.'&amp;bill_code='.$_GET['bill_code'];
$mi = "<img src='graph.php?type=bill_historictransfer&id=".$bill_id;
$mi .= '&amp;from='.$lastmonth.'&amp;to='.$rightnow;
$mi .= '&amp;&type=day';
$mi .= '&amp;x=1190&amp;y=250';
$mi .= "$type'>";
$mi .= '&amp;&imgtype=day';
$mi .= '&amp;width=1190&amp;height=250';
$mi .= "'>";
?>
<div class="panel panel-default">

View File

@@ -220,3 +220,254 @@ function getPeriod($bill_id, $datefrom, $dateto)
$ptot = dbFetchCell("SELECT SUM(period) FROM bill_data WHERE bill_id = '".mres($bill_id)."' AND timestamp > '".mres($datefrom)."' AND timestamp <= '".mres($dateto)."'");
return ($ptot);
}//end getPeriod()
function getBillingHistoryBitsGraphData($bill_id, $bill_hist_id, $reducefactor)
{
$histrow = dbFetchRow('SELECT UNIX_TIMESTAMP(bill_datefrom) as `from`, UNIX_TIMESTAMP(bill_dateto) AS `to`, rate_95th, rate_average, bill_type FROM bill_history WHERE bill_id = ? AND bill_hist_id = ?', array($bill_id, $bill_hist_id));
if (is_null($histrow)) {
return null;
}
$graph_data = getBillingBitsGraphData($bill_id, $histrow['from'], $histrow['to'], $reducefactor);
// Overwrite the rate data with the historical version
$graph_data['rate_95th'] = $histrow['rate_95th'];
$graph_data['rate_average'] = $histrow['rate_average'];
$graph_data['bill_type'] = $histrow['bill_type'];
return $graph_data;
}
function getBillingBitsGraphData($bill_id, $from, $to, $reducefactor)
{
$i = '0';
$iter = 0;
$first = null;
$last = null;
$iter_in = 0;
$iter_out = 0;
$iter_period = 0;
$max_in = 0;
$max_out = 0;
$tot_in = 0;
$tot_out = 0;
$tot_period = 0;
$in_delta = null;
$out_delta = null;
$period = null;
$in_data = array();
$out_data = array();
$tot_data = array();
$ticks = array();
if (!isset($reducefactor) || !is_numeric($reducefactor) || $reducefactor < 1) {
// Auto calculate reduce factor
$expectedpoints = ceil(($to - $from) / 300);
$desiredpoints = 400;
$reducefactor = max(1, floor($expectedpoints / $desiredpoints));
}
$bill_data = dbFetchRow('SELECT * from `bills` WHERE `bill_id`= ? LIMIT 1', array($bill_id));
foreach (dbFetch('SELECT *, UNIX_TIMESTAMP(timestamp) AS formatted_date FROM bill_data WHERE bill_id = ? AND `timestamp` >= FROM_UNIXTIME( ? ) AND `timestamp` <= FROM_UNIXTIME( ? ) ORDER BY timestamp ASC', array($bill_id, $from, $to)) as $row) {
$timestamp = $row['formatted_date'];
if (!$first) {
$first = $timestamp;
}
$period = $row['period'];
$in_delta = $row['in_delta'];
$out_delta = $row['out_delta'];
$last = $timestamp;
$iter_in += $in_delta;
$iter_out += $out_delta;
$iter_period += $period;
if ($period > 0) {
$max_in = max($max_in, $in_delta / $period);
$max_out = max($max_out, $out_delta / $period);
$tot_in += $in_delta;
$tot_out += $out_delta;
$tot_period+= $period;
if (++$iter >= $reducefactor) {
$out_data[$i] = round(($iter_out * 8 / $iter_period), 2);
$in_data[$i] = round(($iter_in * 8 / $iter_period), 2);
$tot_data[$i] = ($out_data[$i] + $in_data[$i]);
$ticks[$i] = $timestamp;
$i++;
$iter = 0;
unset($iter_out, $iter_in, $iter_period);
}
}
}//end foreach
if (isset($iter_in)) { // Write last element
$out_data[$i] = round(($iter_out * 8 / $iter_period), 2);
$in_data[$i] = round(($iter_in * 8 / $iter_period), 2);
$tot_data[$i] = ($out_data[$i] + $in_data[$i]);
$ticks[$i] = $timestamp;
$i++;
}
$result = array(
'from' => $from,
'to' => $to,
'first' => $first,
'last' => $last,
'in_data' => $in_data,
'out_data' => $out_data,
'tot_data' => $tot_data,
'ticks' => $ticks,
'rate_95th' => $bill_data['rate_95th'],
'rate_average' => $bill_data['rate_average'],
'bill_type' => $bill_data['bill_type']
);
if ($period) {
$result['max_in'] = $max_in;
$result['max_out'] = $max_out;
$result['ave_in'] = $tot_in / $tot_period;
$result['ave_out'] = $tot_out / $tot_period;
$result['last_in'] = $in_delta / $period;
$result['last_out'] = $out_delta / $period;
}
return $result;
}//end getBillingBitsGraphData
function getHistoricTransferGraphData($bill_id)
{
$i = '0';
$in_data = array();
$out_data = array();
$tot_data = array();
$allow_data = array();
$ave_data = array();
$overuse_data = array();
$ticklabels = array();
$allowed_val = null;
foreach (dbFetchRows('SELECT * FROM `bill_history` WHERE `bill_id` = ? ORDER BY `bill_datefrom` DESC LIMIT 12', array($bill_id)) as $data) {
$datefrom = strftime('%Y-%m-%d', strtotime($data['bill_datefrom']));
$dateto = strftime('%Y-%m-%d', strtotime($data['bill_dateto']));
$datelabel = $datefrom." - ".$dateto;
array_push($ticklabels, $datelabel);
array_push($in_data, $data['traf_in']);
array_push($out_data, $data['traf_out']);
array_push($tot_data, $data['traf_total']);
array_push($allow_data, $allowed_val = ($data['bill_type'] == 'Quota' ? $data['bill_allowed'] : 0));
array_push($overuse_data, $data['bill_type'] == 'Quota' ? $data['bill_overuse'] : 0);
$i++;
}//end foreach
if ($i < 12) {
$y = (12 - $i);
for ($x = 0; $x < $y; $x++) {
$allowed = (($x == '0') ? $allowed_val : '0' );
array_push($in_data, '0');
array_push($out_data, '0');
array_push($tot_data, '0');
array_push($allow_data, $allowed);
array_push($overuse_data, '0');
array_push($ticklabels, '');
}
}
$graph_name = 'Historical bandwidth over the last 12 billing periods';
return array(
'graph_name' => $graph_name,
'in_data' => $in_data,
'out_data' => $out_data,
'tot_data' => $tot_data,
'allow_data' => $allow_data,
'ave_data' => $ave_data,
'overuse_data' => $overuse_data,
'ticklabels' => $ticklabels
);
}
function getBillingBandwidthGraphData($bill_id, $bill_hist_id, $from, $to, $imgtype)
{
if (is_numeric($bill_hist_id)) {
$histrow = dbFetchRow('SELECT UNIX_TIMESTAMP(bill_datefrom) as `from`, UNIX_TIMESTAMP(bill_dateto) AS `to`, rate_95th, rate_average FROM bill_history WHERE bill_id = ? AND bill_hist_id = ?', array($bill_id, $bill_hist_id));
if (is_null($histrow)) {
return null;
}
$from = $histrow['from'];
$to = $histrow['to'];
} else {
if (!is_numeric($from) || !is_numeric($to)) {
die('Must supply from and to if bill_hist_id is not supplied');
}
}
$in_data = array();
$out_data = array();
$tot_data = array();
$allow_data = array();
$ave_data = array();
$overuse_data = array();
$ticklabels = array();
$data = array();
$average = 0;
if ($imgtype == 'day') {
foreach (dbFetch('SELECT DISTINCT UNIX_TIMESTAMP(timestamp) as timestamp, SUM(delta) as traf_total, SUM(in_delta) as traf_in, SUM(out_delta) as traf_out FROM bill_data WHERE `bill_id` = ? AND `timestamp` >= FROM_UNIXTIME(?) AND `timestamp` <= FROM_UNIXTIME(?) GROUP BY DATE(timestamp) ORDER BY timestamp ASC', array($bill_id, $from, $to)) as $data) {
array_push($ticklabels, strftime("%Y-%m-%d", $data['timestamp']));
array_push($in_data, isset($data['traf_in']) ? $data['traf_in'] : 0);
array_push($out_data, isset($data['traf_out']) ? $data['traf_out'] : 0);
array_push($tot_data, isset($data['traf_total']) ? $data['traf_total'] : 0);
$average += $data['traf_total'];
}
$ave_count = count($tot_data);
// Add empty items for the days not yet passed
$days = (strftime('%e', date($to - $from)) - $ave_count - 1);
for ($x = 0; $x < $days; $x++) {
array_push($ticklabels, '');
array_push($in_data, 0);
array_push($out_data, 0);
array_push($tot_data, 0);
}
} elseif ($imgtype == 'hour') {
foreach (dbFetch('SELECT DISTINCT HOUR(timestamp) as hour, SUM(delta) as traf_total, SUM(in_delta) as traf_in, SUM(out_delta) as traf_out FROM bill_data WHERE `bill_id` = ? AND `timestamp` >= FROM_UNIXTIME(?) AND `timestamp` <= FROM_UNIXTIME(?) GROUP BY HOUR(timestamp) ORDER BY HOUR(timestamp) ASC', array($bill_id, $from, $to)) as $data) {
array_push($ticklabels, sprintf('%02d', $data['hour']) . ":00");
array_push($in_data, isset($data['traf_in']) ? $data['traf_in'] : 0);
array_push($out_data, isset($data['traf_out']) ? $data['traf_out'] : 0);
array_push($tot_data, isset($data['traf_total']) ? $data['traf_total'] : 0);
$average += $data['traf_total'];
}
$ave_count = count($tot_data);
} else {
die("Unknown graph type $imgtype");
}//end if
$average = ($average / $ave_count);
$tot_data_size = count($tot_data);
for ($x = 0; $x <= $tot_data_size; $x++) {
array_push($ave_data, $average);
}
$graph_name = date('M j g:ia', $from).' - '.date('M j g:ia', $to);
return array(
'graph_name' => $graph_name,
'in_data' => $in_data,
'out_data' => $out_data,
'tot_data' => $tot_data,
'allow_data' => $allow_data,
'ave_data' => $ave_data,
'overuse_data' => $overuse_data,
'ticklabels' => $ticklabels
);
}
//end getBillingBandwidthGraphData