<%# 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%>