luci/applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm

168 lines
4.2 KiB
HTML
Raw Normal View History

<%#
Copyright 2018 Rosy Song <rosysong@rosinson.com>
Licensed to the public under the Apache License 2.0.
-%>
<%+header%>
<script type="text/javascript">//<![CDATA[
var bwxhr = new XHR();
var RC = { };
var em = 0;
var ec = 1;
var rate_table_dl;
var rate_table_ul;
function init_bytes(rl, ra) {
var bytes_pre;
var obj = { };
obj.chain = rl.chain;
obj.ipaddr = rl.expr[em].match.right;
obj.bytes = rl.expr[ec].counter.bytes;
obj.packets = rl.expr[ec].counter.packets;
obj.rate = 0;
if (RC[obj.chain] && RC[obj.chain][obj.ipaddr])
bytes_pre = RC[obj.chain][obj.ipaddr];
else
bytes_pre = 0;
obj.rate = (bytes_pre > 0) ? (obj.bytes - bytes_pre) / 3: 0;
if (!RC[obj.chain])
RC[obj.chain] = { };
RC[obj.chain][obj.ipaddr] = obj.bytes;
if (!ra[obj.chain])
ra[obj.chain] = [ ];
ra[obj.chain].push(obj);
} /* function init_bytes(rl, ra) */
function bytes_label(bytes) {
var uby = '<%:kB%>';
var kby = (bytes / 1024);
if (kby > 1024) {
uby = '<%:MB%>';
kby = (kby / 1024);
}
return String.format("%f %s", kby.toFixed(2), uby);
}
function print_table(tbl, rs, ra) {
ra.sort(function(a, b) { return b.rate - a.rate });
for (var i = 0; i < ra.length; i++) {
rs.push([
ra[i].ipaddr,
bytes_label(ra[i].rate) + '/s',
bytes_label(ra[i].bytes),
'%s Pkts.'.format(ra[i].packets),
]);
}
cbi_update_table(tbl, rs, '<em><%:No information available%></em>');
} /* function print_table(tbl, ra) */
/* wait for SVG */
window.setTimeout(
function() {
if (!RC)
{
window.setTimeout(arguments.callee, 1000);
}
else
{
rate_table_dl = document.getElementById('rate_table_dl');
rate_table_ul = document.getElementById('rate_table_ul');
/* render datasets, start update interval */
XHR.poll(3, '<%=build_url("admin/status/realtime/rate_status")%>', null,
function(x, json)
{
var RA = {};
var rows_dl = [];
var rows_ul = [];
var rules = json.nftables;
for (var i = 0; i < rules.length; i++)
{
if (!rules[i].rule)
continue;
if (rules[i].rule.table != 'nft-qos-monitor')
continue;
var rl = rules[i].rule;
switch (rl.chain)
{
case 'download':
case 'upload': init_bytes(rl, RA); break;
}
} /* for (var i = 0; i < rules.length; i++) */
/* display the result */
if (RA.download) {
while (rate_table_dl.firstElementChild !== rate_table_dl.lastElementChild)
rate_table_dl.removeChild(rate_table_dl.lastElementChild);
print_table(rate_table_dl, rows_dl, RA.download);
}
if (RA.upload) {
while (rate_table_ul.firstElementChild !== rate_table_ul.lastElementChild)
rate_table_ul.removeChild(rate_table_ul.lastElementChild);
print_table(rate_table_ul, rows_ul, RA.upload);
}
} /* function(x, json) */
); /* XHR.poll() */
XHR.run();
}
}, 1000
);
//]]></script>
<h2 name="content"><%:Realtime Rate%></h2>
<div class="cbi-map-descr"><%:This page gives an overview over currently download/upload rate.%></div>
<fieldset class="cbi-section" id="cbi-table-table">
<legend><%:Realtime Download Rate%></legend>
<div class="cbi-section-node">
<div class="table" id="rate_table_dl">
<div class="tr table-titles">
<div class="th col-2 hide-xs"><%:IP Address%></div>
<div class="th col-2"><%:Download Rate%></div>
<div class="th col-7"><%:Bytes Total%></div>
<div class="th col-7"><%:Packets Total%></div>
</div>
<div class="tr placeholder">
<div class="td">
<em><%:Collecting data...%></em>
</div>
</div>
</div>
</div>
</fieldset>
<fieldset class="cbi-section" id="cbi-table-table">
<legend><%:Realtime Upload Rate%></legend>
<div class="cbi-section-node">
<div class="table" id="rate_table_ul">
<div class="tr table-titles">
<div class="th col-2 hide-xs"><%:IP Address%></div>
<div class="th col-2"><%:Upload Rate%></div>
<div class="th col-7"><%:Bytes Total%></div>
<div class="th col-7"><%:Packets Total%></div>
</div>
<div class="tr placeholder">
<div class="td">
<em><%:Collecting data...%></em>
</div>
</div>
</div>
</div>
</fieldset>
<%+footer%>