1. 程式人生 > >路由器的流量圖製作

路由器的流量圖製作

1.繪製svg 向量圖 bandwidth.svg


註釋:繪製流量圖的方法有三種,

1) :直接將 svg  嵌入的html 頁面中

2 ):通過使用embed/frame 等引用到頁面中去;

<div class="cbi-table">
<embed id="bwsvg" src="/JS/bandwidth.svg" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" type="image/svg+xml"   pluginspage="http://www.adobe.com/svg/viewer/install/"/>
<div style="text-align:right"><small id="scale">2 分鐘繪圖,1 秒重新整理</small></div>
<br />
</div>


3):在html 頁面中動態的建立

<div class="cbi-table">
<embed id="bwsvg" style="width:100%; height:320px; border:1px solid #000000; background-color:#FFFFFF" type="image/svg+xml"  pluginspage="http://www.adobe.com/svg/viewer/install/" src="/JS/bandwidth.svg" />
<div style="text-align:right"><small id="scale">2 分鐘繪圖,1 秒重新整理</small></div>
<br />

</div>

function LoadFrame()
{
<% if tcwebApi_get("WebCustom_Entry","isSVGSupported","h")  = "Yes" then %>
var svg = document.getElementById('bwsvg');
var line_25=document.createElementNS("http://www.w3.org/2000/svg","line");
 //水平線25%
if(line_25)
    {
    line_25.setAttribute('x1',0);
    line_25.setAttribute('y1',"25%");
    line_25.setAttribute('x2',"100%");
    line_25.setAttribute('y2',"25%");
    line_25.setAttribute("style","stroke:black;stroke-width:0.1");
    svg.appendChild(line_25);
    }
text_25=document.createElementNS("http://www.w3.org/2000/svg","text");
if(text_25)
{
text_25.setAttribute('x',15);
    text_25.setAttribute('y',"75%");
text_25.setAttribute("id","label_25");
text_25.setAttribute("style","fill:black; font-size:9pt");
svg.appendChild(text_25);

}
    //水平線50%
var line_50=document.createElementNS("http://www.w3.org/2000/svg","line");


if(line_50)
    {
    line_50.setAttribute('x1',0);
    line_50.setAttribute('y1',"50%");
    line_50.setAttribute('x2',"100%");
    line_50.setAttribute('y2',"50%");
    line_50.setAttribute("style","stroke:black;stroke-width:0.1");
    svg.appendChild(line_50);
    }
text_50=document.createElementNS("http://www.w3.org/2000/svg","text");
if(text_50)
{
text_50.setAttribute('x',15);
    text_50.setAttribute('y',"50%");
text_50.setAttribute("id","label_50");
text_50.setAttribute("style","fill:black; font-size:9pt");
svg.appendChild(text_50);

}
   //水平線75%
var line_75=document.createElementNS("http://www.w3.org/2000/svg","line");


if(line_75)
    {
    line_75.setAttribute('x1',0);
    line_75.setAttribute('y1',"75%");
    line_75.setAttribute('x2',"100%");
    line_75.setAttribute('y2',"75%");
    line_75.setAttribute("style","stroke:black;stroke-width:0.1");
    svg.appendChild(line_75);
    }


text_75=document.createElementNS("http://www.w3.org/2000/svg","text");
if(text_75)
{
text_75.setAttribute('x',15);
    text_75.setAttribute('y',"25%");
text_75.setAttribute("id","label_75");
text_75.setAttribute("style","fill:black; font-size:9pt");
svg.appendChild(text_75);

}
text_v=document.createElementNS("http://www.w3.org/2000/svg","text");
if(text_v)
{
//text_v.setAttribute("x",50);
//text_v.setAttribute("y","74%");
text_v.setAttribute("id","label_v");
text_v.setAttribute("style","fill:#FF0000; font-size:9pt");
svg.appendChild(text_v);

}

//折線
line_rx=document.createElementNS("http://www.w3.org/2000/svg","polyline");
if(line_rx)
{
line_rx.setAttribute("point","");
line_rx.setAttribute("id","rx");
line_rx.setAttribute("style","fill:red;fill-opacity:0.4;stroke:red;stroke-width:1");
svg.appendChild(line_rx);
}
line_tx=document.createElementNS("http://www.w3.org/2000/svg","polyline");
if(line_tx)
{
line_tx.setAttribute("point","");
line_tx.setAttribute("id","tx");
line_tx.setAttribute("style","fill:blue;fill-opacity:0.4;stroke:blue;stroke-width:1");
svg.appendChild(line_tx);
}
for (var i = step * 60; i < width; i += step * 60)
               {


var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');


line.setAttribute('x1', i-5);
line.setAttribute('y1', 0);
line.setAttribute('x2', i-5);
line.setAttribute('y2', '100%');
line.setAttribute('style', 'stroke:black;stroke-width:0.1');


var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
text.setAttribute('x', i + 5);
text.setAttribute('y', 15);
text.setAttribute('style', 'fill:#999999; font-size:9pt');
text.appendChild(document.createTextNode(Math.round(i / step / 60) + 'min'));


text_v.parentNode.appendChild(line);
text_v.parentNode.appendChild(text);


               }
label_rx_cur  = document.getElementById('rx_bw_cur');
label_rx_avg  = document.getElementById('rx_bw_avg');
label_rx_peak = document.getElementById('rx_bw_peak');


label_tx_cur  = document.getElementById('tx_bw_cur');
label_tx_avg  = document.getElementById('tx_bw_avg');
label_tx_peak = document.getElementById('tx_bw_peak');
             window.setTimeout(update_graph, 1000);
<% end if %>

}

function update_graph()
{
console.log("...data_max="+data_max);
data_max=0;
bwxhr.get('/cgi-bin/traffic.cgi', null,
function(x, data)
{

var data_scale = 0;


var data_rx_avg = 0;
var data_tx_avg = 0;


var data_rx_peak = 0;
var data_tx_peak = 0;
for (var i = data_stamp ? 0 : 1; i < data.length; i++)
{


if (data[i][TIME] <= data_stamp)
continue;




//。兩個時間資料之間的差值
var time_delta = data[i][TIME] - data[i-1][TIME];
if (time_delta)
{
data_rx.push((data[i][RXB] - data[i-1][RXB]) / time_delta);
data_tx.push((data[i][TXB] - data[i-1][TXB]) / time_delta);
}
}




//從陣列中擷取data_rx.length 0~data_rx.length - data_wanted
data_rx = data_rx.slice(data_rx.length - data_wanted, data_rx.length);
data_tx = data_tx.slice(data_tx.length - data_wanted, data_tx.length);








//尋找這組資料的最大值
for (var i = 0; i < data_rx.length; i++)
{

data_max = Math.max(data_max, data_rx[i]);
//data_max = Math.max(data_max, data_tx[i]);

data_rx_peak = Math.max(data_rx_peak, data_rx[i]);
data_tx_peak = Math.max(data_tx_peak, data_tx[i]);


if (i > 0)
{
data_rx_avg = (data_rx_avg + data_rx[i]) / 2;
data_tx_avg = (data_tx_avg + data_tx[i]) / 2;
}
else
{
data_rx_avg = data_rx[i];
data_tx_avg = data_tx[i];
}
}




//最後一組時間資料
data_stamp = data[data.length-1][TIME];
data_scale = height / (data_max * 1.1);






var pt_rx = '0,' + height;
var pt_tx = '0,' + height;


var y_rx = 0;
var y_tx = 0;

for (var i = 0; i < data_rx.length; i++)
{


var x = i * step * 2;


y_rx = height - Math.floor(data_rx[i] * data_scale);
y_tx = height - Math.floor(data_tx[i] * data_scale);


pt_rx += ' ' + x + ',' + y_rx;
pt_tx += ' ' + x + ',' + y_tx;
}






pt_rx += ' ' + width + ',' + y_rx + ' ' + width + ',' + height;
pt_tx += ' ' + width + ',' + y_tx + ' ' + width + ',' + height;




line_rx.setAttribute('points', pt_rx);
line_tx.setAttribute('points', pt_tx);


var textNode=document.createTextNode( bandwidth_label(1.1 * 0.75 * data_max));
var L75Node=getElementById("label_75");
var childs75 = L75Node.childNodes;
for(var i=0;i<childs75.length;i++)
{
L75Node.removeChild(childs75[i]);
}
text_75.appendChild(textNode);

var textNode=document.createTextNode( bandwidth_label(1.1 * 0.5 * data_max));
var L50Node=getElementById("label_50");
var childs50 = L50Node.childNodes;
for(var i=0;i<childs50.length;i++)
{
L50Node.removeChild(childs50[i]);
}
text_50.appendChild(textNode);


var textNode=document.createTextNode( bandwidth_label(1.1 * 0.25 * data_max));
var L25Node=getElementById("label_25");
var childs25 = L25Node.childNodes;
for(var i=0;i<childs25.length;i++)
{
L25Node.removeChild(childs25[i]);
}
text_25.appendChild(textNode);


//顯示下面資料值

label_rx_cur.innerHTML = bandwidth_label(data_rx[data_rx.length-1], true);
label_tx_cur.innerHTML = bandwidth_label(data_tx[data_tx.length-1], true);


label_rx_avg.innerHTML = bandwidth_label(data_rx_avg, true);
label_tx_avg.innerHTML = bandwidth_label(data_tx_avg, true);

   label_rx_peak.innerHTML = bandwidth_label(data_rx_peak, true);
label_tx_peak.innerHTML = bandwidth_label(data_tx_peak, true);

window.setTimeout(update_graph, 1000);


}
)
}

3.頁面顯示程式碼實現:


4:頁面程式碼的資料處理

<script type="text/javascript">//<![CDATA[
    var bwxhr = new XHR();
    var G;
    var TIME = 0;
    var RXB  = 1;
    var RXP  = 2;
    var TXB  = 3;
    var TXP  = 4;
    var width  = 460;
    var height = 300;
    var step   = 3;
    var data_wanted = Math.floor(width / step);
    var data_fill   = 0;
    var data_stamp  = 0;
    var data_rx = [ ];
    var data_tx = [ ];
    var line_rx;
    var line_tx;
    var label_25;
    var label_50;
    var label_75;
    var label_rx_cur;
    var label_rx_avg;
    var label_rx_peak;
    var label_tx_cur;
    var label_tx_avg;
    var label_tx_peak;
    var label_scale;
var objstring=new String();


    function bandwidth_label(bytes, br)
    {


    var uby = 'KByte';
    var kby = (bytes / 1024);


    if (kby >= 1024)
    {
    uby = 'MByte';
    kby = kby / 1024;
    }
    var ubi = 'KBit';
    var kbi = (bytes * 8 / 1024);
    if (kbi >= 1024)
    {
    ubi = 'MBit';
    kbi = kbi / 1024;
    }
        var tmp=objstring.concat(kbi.toFixed(2), ubi,"/s",(br ? '<br />' : ' '),"(",kby.toFixed(2), uby,"/s)");
    //return String.format("%f %s/s%s(%f %s/s)",kbi.toFixed(2), ubi,br ? '<br />' : ' ',kby.toFixed(2), uby);
    return tmp;

    }

/*********頁面流量圖資料的重新整理處理********/

    function update_graph()
    {
    bwxhr.get('/cgi-bin/traffic.cgi', null,
    function(x, data)
    {
    var data_max   = 0;
    var data_scale = 0;


    var data_rx_avg = 0;
    var data_tx_avg = 0;


    var data_rx_peak = 0;
    var data_tx_peak = 0;
    for (var i = data_stamp ? 0 : 1; i < data.length; i++)
    {
    /* skip overlapping entries */
    if (data[i][TIME] <= data_stamp)
    continue;


    /* normalize difference against time interval */
    //。兩個時間資料之間的差值
    var time_delta = data[i][TIME] - data[i-1][TIME];
    if (time_delta)
    {
    //像data_rx陣列中新增一個單位時間收發的資料量
    data_rx.push((data[i][RXB] - data[i-1][RXB]) / time_delta);
    data_tx.push((data[i][TXB] - data[i-1][TXB]) / time_delta);
    }
    }




    //從陣列中擷取data_rx.length 0~data_rx.length - data_wanted
    data_rx = data_rx.slice(data_rx.length - data_wanted, data_rx.length);
    data_tx = data_tx.slice(data_tx.length - data_wanted, data_tx.length);
    //尋找這組資料的最大值
    for (var i = 0; i < data_rx.length; i++)
    {
    data_max = Math.max(data_max, data_rx[i]);
    data_max = Math.max(data_max, data_tx[i]);


    data_rx_peak = Math.max(data_rx_peak, data_rx[i]);
    data_tx_peak = Math.max(data_tx_peak, data_tx[i]);


    if (i > 0)
    {
    data_rx_avg = (data_rx_avg + data_rx[i]) / 2;
    data_tx_avg = (data_tx_avg + data_tx[i]) / 2;
    }
    else
    {
    data_rx_avg = data_rx[i];
    data_tx_avg = data_tx[i];
    }
    }


    /* remember current timestamp, calculate horizontal scale */
    //最後一組時間資料
    data_stamp = data[data.length-1][TIME];
    data_scale = height / (data_max * 1.1);




    /* plot data */
    var pt_rx = '0,' + height;
    var pt_tx = '0,' + height;


    var y_rx = 0;
    var y_tx = 0;
    for (var i = 0; i < data_rx.length; i++)
    {
    var x = i * step;
    y_rx = height - Math.floor(data_rx[i] * data_scale);
    y_tx = height - Math.floor(data_tx[i] * data_scale);
    pt_rx += ' ' + x + ',' + y_rx;
    pt_tx += ' ' + x + ',' + y_tx;
    }
    pt_rx += ' ' + width + ',' + y_rx + ' ' + width + ',' + height;
    pt_tx += ' ' + width + ',' + y_tx + ' ' + width + ',' + height;
    line_rx.setAttribute('points', pt_rx);
    line_tx.setAttribute('points', pt_tx);
    label_25.firstChild.data = bandwidth_label(1.1 * 0.25 * data_max);
    label_50.firstChild.data = bandwidth_label(1.1 * 0.50 * data_max);
    label_75.firstChild.data = bandwidth_label(1.1 * 0.75 * data_max);
    label_rx_cur.innerHTML = bandwidth_label(data_rx[data_rx.length-1], true);
    label_tx_cur.innerHTML = bandwidth_label(data_tx[data_tx.length-1], true);
    label_rx_avg.innerHTML = bandwidth_label(data_rx_avg, true);
    label_tx_avg.innerHTML = bandwidth_label(data_tx_avg, true);
    label_rx_peak.innerHTML = bandwidth_label(data_rx_peak, true);
    label_tx_peak.innerHTML = bandwidth_label(data_tx_peak, true);
    }
    )

    }

/* wait for SVG */
    window.setTimeout(
    function() {
    //先獲取頁面元素物件
    var svg = document.getElementById('bwsvg');
//獲取SVG 物件
    try {
    G = svg.getSVGDocument
    ? svg.getSVGDocument() : svg.contentDocument;
    }
    catch(e) {
    G = document.embeds['bwsvg'].getSVGDocument();
    }
    if (!G)
    {
    window.setTimeout(arguments.callee, 1000);
    }
    else
    {
    /* find sizes */
    width       = svg.offsetWidth  - 2;
    height      = svg.offsetHeight - 2;
    data_wanted = Math.ceil(width / step);
    //初始化data_rx tx
    for (var i = 0; i < data_wanted; i++)
    {
    data_rx[i] = 0;
    data_tx[i] = 0;
    }
    /* find svg elements */
    line_rx = G.getElementById('rx');//polyline rx
    line_tx = G.getElementById('tx');//polyline tx
    label_25 = G.getElementById('label_25');
    label_50 = G.getElementById('label_50');
    label_75 = G.getElementById('label_75');
    label_rx_cur  = document.getElementById('rx_bw_cur');
    label_rx_avg  = document.getElementById('rx_bw_avg');
    label_rx_peak = document.getElementById('rx_bw_peak');
    label_tx_cur  = document.getElementById('tx_bw_cur');
    label_tx_avg  = document.getElementById('tx_bw_avg');
    label_tx_peak = document.getElementById('tx_bw_peak');
    label_scale   = document.getElementById('scale');
    /* plot horizontal time interval lines */
    for (var i = step * 60; i < width; i += step * 60)
    {
    var line = G.createElementNS('http://www.w3.org/2000/svg', 'line');
            line.setAttribute('x1', i-5);
    line.setAttribute('y1', 0);
    line.setAttribute('x2', i-5);
    line.setAttribute('y2', '100%');
    line.setAttribute('style', 'stroke:black;stroke-width:0.1');
    var text = G.createElementNS('http://www.w3.org/2000/svg', 'text');
    //text.setAttribute('x', i + 5);
    text.setAttribute('x', i-5);
    text.setAttribute('y', 15);
    text.setAttribute('style', 'fill:#999999; font-size:9pt');
    text.appendChild(G.createTextNode(Math.round(i / step / 60) + 'min'));
             label_25.parentNode.appendChild(line);
           label_25.parentNode.appendChild(text);
    }
    //label_scale.innerHTML = String.format('( %d 分鐘繪圖,%d 秒重新整理)', data_wanted / 60, 1);
    /* render datasets, start update interval */
    update_graph();
    }
    }, 1000
    );

    //]]></script>

頁面的引用xhr.js

/*
 * xhr.js - XMLHttpRequest helper class
 * (c) 2008-2010 Jo-Philipp Wich
 */


XHR = function()
{


this.reinit = function()
{
if( window.XMLHttpRequest ) {
this._xmlHttp = new XMLHttpRequest();
}
else if( window.ActiveXObject ) {
this._xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else {
alert("xhr.js: XMLHttpRequest is not supported by this browser!");
}
}


this.busy = function() {
switch( this._xmlHttp.readyState )
{
case 1:
case 2:
case 3:
return true;


default:
return false;
}
}


this.abort = function() {
if( this.busy() )
this._xmlHttp.abort();
}


this.get = function(url,data,callback)
{
this.reinit();


var xhr  = this._xmlHttp;
var code = this._encode( data );


url = location.protocol + '//' + location.hostname +
( location.port ? ':' + location.port : '' ) + url;


if( code )
if( url.substr(url.length-1,1) == '&' )
url += code;
else
url += '?' + code;


xhr.open( 'GET', url, true );


xhr.onreadystatechange = function()
{
if( xhr.readyState == 4 ) {
var json = null;


if( xhr.getResponseHeader("Content-Type") == "application/json" ) {
try {
json = eval('(' + xhr.responseText + ')');
}
catch(e) {
json = null;
}
}
callback( xhr, json );
}
}


xhr.send( null );
}


this.post = function(url,data,callback)
{
this.reinit();


var xhr  = this._xmlHttp;
var code = this._encode( data );


xhr.onreadystatechange = function()
{
if( xhr.readyState == 4 )
callback( xhr );
}


xhr.open( 'POST', url, true );
xhr.setRequestHeader( 'Content-type', 'application/x-www-form-urlencoded' );
xhr.setRequestHeader( 'Content-length', code.length );
xhr.setRequestHeader( 'Connection', 'close' );
xhr.send( code );
}


this.cancel = function()
{
this._xmlHttp.onreadystatechange = function(){};
this._xmlHttp.abort();
}


this.send_form = function(form,callback,extra_values)
{
var code = '';


for( var i = 0; i < form.elements.length; i++ )
{
var e = form.elements[i];


if( e.options )
{
code += ( code ? '&' : '' ) +
form.elements[i].name + '=' + encodeURIComponent(
e.options[e.selectedIndex].value
);
}
else if( e.length )
{
for( var j = 0; j < e.length; j++ )
if( e[j].name ) {
code += ( code ? '&' : '' ) +
e[j].name + '=' + encodeURIComponent( e[j].value );
}
}
else
{
code += ( code ? '&' : '' ) +
e.name + '=' + encodeURIComponent( e.value );
}
}


if( typeof extra_values == 'object' )
for( var key in extra_values )
code += ( code ? '&' : '' ) +
key + '=' + encodeURIComponent( extra_values[key] );


return(
( form.method == 'get' )
? this.get( form.getAttribute('action'), code, callback )
: this.post( form.getAttribute('action'), code, callback )
);
}


this._encode = function(obj)
{
obj = obj ? obj : { };
obj['_'] = Math.random();


if( typeof obj == 'object' )
{
var code = '';
var self = this;


for( var k in obj )
code += ( code ? '&' : '' ) +
k + '=' + encodeURIComponent( obj[k] );


return code;
}


return obj;
}
}

5.資料獲取的處理函式

 /* Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef _BWC_H__
#define _BWC_H__
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>


#include <sys/stat.h>
#include <sys/mman.h>
#include <arpa/inet.h>
#include <sys/types.h>




#define STEP_COUNT60
#define STEP_TIME1


#define DB_PATH"/var/lib/bwc"
#define DB_IF_FILEDB_PATH "/if/%s"
#define DB_CN_FILEDB_PATH "/connections"
#define DB_LD_FILEDB_PATH "/load"


#define IF_SCAN_PATTERN \
" %[^ :]:%" SCNu64 " %" SCNu64 \
" %*d %*d %*d %*d %*d %*d" \
" %" SCNu64 " %" SCNu64


#define LD_SCAN_PATTERN \
"%f %f %f"
//typedef unsigned  long long uint64_t;




struct file_map {
int fd;
int size;
char *mmap;
};


struct traffic_entry {
uint64_t time;
uint64_t rxb;
uint64_t rxp;
uint64_t txb;
uint64_t txp;
};

#endif 

檔案bwc.c

#include "bwc.h"
#define ntohll htonll
static uint64_t htonll(uint64_t value)
{
int num = 1;


if (*(char *)&num == 1)
return htonl((uint32_t)(value & 0xFFFFFFFF)) |
      htonl((uint32_t)(value >> 32));


return value;
}








static int init_directory(char *path)
{
char *p = path;


for (p = &path[1]; *p; p++)
{
if (*p == '/')
{
*p = 0;


if (mkdir(path, 0700) && (errno != EEXIST))
return -1;


*p = '/';
}
}


return 0;
}


static int init_file(char *path, int esize)
{
int i, file;
char buf[sizeof(struct traffic_entry)] = { 0 };


if (init_directory(path))
return -1;


if ((file = open(path, O_WRONLY | O_CREAT, 0600)) >= 0)
{
for (i = 0; i < STEP_COUNT; i++)
{
if (write(file, buf, esize) < 0)
break;
}


close(file);


return 0;
}


return -1;
}


static int update_file(const char *path, void *entry, int esize)
{
int rv = -1;
int file;
char *map;


if ((file = open(path, O_RDWR)) >= 0)
{
map = mmap(NULL, esize * STEP_COUNT, PROT_READ | PROT_WRITE,
  MAP_SHARED | MAP_LOCKED, file, 0);


if ((map != NULL) && (map != MAP_FAILED))
{
memmove(map, map + esize, esize * (STEP_COUNT-1));
//拷貝
memcpy(map + esize * (STEP_COUNT-1), entry, esize);


munmap(map, esize * STEP_COUNT);


rv = 0;
}


close(file);
}


return rv;
}
#if 0
static int mmap_file(const char *path, int esize, struct file_map *m)
{
m->fd   = -1;
m->size = -1;
m->mmap = NULL;


if ((m->fd = open(path, O_RDONLY)) >= 0)
{
m->size = STEP_COUNT * esize;
m->mmap = mmap(NULL, m->size, PROT_READ,
  MAP_SHARED | MAP_LOCKED, m->fd, 0);


if ((m->mmap != NULL) && (m->mmap != MAP_FAILED))
return 0;
}


return -1;
}


static void umap_file(struct file_map *m)
{
if ((m->mmap != NULL) && (m->mmap != MAP_FAILED))
munmap(m->mmap, m->size);


if (m->fd > -1)
close(m->fd);
}
#endif
/**/
static int update_ifstat(
const char *ifname, uint64_t rxb, uint64_t rxp, uint64_t txb, uint64_t txp
) {
char path[1024];


struct stat s;
struct traffic_entry e;


snprintf(path, sizeof(path), DB_IF_FILE, ifname);


if (stat(path, &s))
{
if (init_file(path, sizeof(struct traffic_entry)))
{
fprintf(stderr, "Failed to init %s: %s\n",
path, strerror(errno));


return -1;
}
}


e.time = htonll(time(NULL));
e.rxb  = htonll(rxb);
e.rxp  = htonll(rxp);
e.txb  = htonll(txb);
e.txp  = htonll(txp);


return update_file(path, &e, sizeof(struct traffic_entry));
}


 int svg_writedata()
{
FILE *info;
uint64_t rxb, txb, rxp, txp;
uint32_t udp, tcp, other;
float lf1, lf5, lf15;
char line[1024];
char ifname[16];


struct stat s;




if ((info = fopen("/proc/net/dev", "r")) != NULL)
{
while (fgets(line, sizeof(line), info))
{
if (strchr(line, '|'))
continue;


if (sscanf(line, IF_SCAN_PATTERN, ifname, &rxb, &rxp, &txb, &txp))
{

if (strncmp(ifname, "lo", sizeof(ifname)))
update_ifstat(ifname, rxb, rxp, txb, txp);
}
}


fclose(info);
}



}
檔案luci-bwc.c
/*
 * luci-bwc - Very simple bandwidth collector cache for LuCI realtime graphs
 *
 *   Copyright (C) 2010 Jo-Philipp Wich <[email protected]>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and

 * limitations under the License.

 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>


#include <sys/stat.h>
#include <sys/mman.h>
#include <arpa/inet.h>




#define STEP_COUNT60
#define STEP_TIME1


#define DB_PATH"/var/lib/bwc"
#define DB_IF_FILEDB_PATH "/if/%s"
#define DB_CN_FILEDB_PATH "/connections"
#define DB_LD_FILEDB_PATH "/load"


#define IF_SCAN_PATTERN \
" %[^ :]:%" SCNu64 " %" SCNu64 \
" %*d %*d %*d %*d %*d %*d" \
" %" SCNu64 " %" SCNu64


#define LD_SCAN_PATTERN \
"%f %f %f"




struct file_map {
int fd;
int size;
char *mmap;
};


struct traffic_entry {
uint64_t time;
uint64_t rxb;
uint64_t rxp;
uint64_t txb;
uint64_t txp;
};


struct conn_entry {
uint64_t time;
uint32_t udp;
uint32_t tcp;
uint32_t other;
};


struct load_entry {
uint64_t time;
uint16_t load1;
uint16_t load5;
uint16_t load15;
};




static uint64_t htonll(uint64_t value)
{
int num = 1;


if (*(char *)&num == 1)
return htonl((uint32_t)(value & 0xFFFFFFFF)) |
      htonl((uint32_t)(value >> 32));


return value;
}


#define ntohll htonll




static int init_directory(char *path)
{
char *p = path;


for (p = &path[1]; *p; p++)
{
if (*p == '/')
{
*p = 0;


if (mkdir(path, 0700) && (errno != EEXIST))
return -1;


*p = '/';
}
}


return 0;
}


static int init_file(char *path, int esize)
{
int i, file;
char buf[sizeof(struct traffic_entry)] = { 0 };


if (init_directory(path))
return -1;


if ((file = open(path, O_WRONLY | O_CREAT, 0600)) >= 0)
{
for (i = 0; i < STEP_COUNT; i++)
{
if (write(file, buf, esize) < 0)
break;
}


close(file);


return 0;
}


return -1;
}


static int update_file(const char *path, void *entry, int esize)
{
int rv = -1;
int file;
char *map;


if ((file = open(path, O_RDWR)) >= 0)
{
map = mmap(NULL, esize * STEP_COUNT, PROT_READ | PROT_WRITE,
  MAP_SHARED | MAP_LOCKED, file, 0);


if ((map != NULL) && (map != MAP_FAILED))
{
memmove(map, map + esize, esize * (STEP_COUNT-1));
//拷貝
memcpy(map + esize * (STEP_COUNT-1), entry, esize);


munmap(map, esize * STEP_COUNT);


rv = 0;
}


close(file);
}


return rv;
}


static int mmap_file(const char *path, int esize, struct file_map *m)
{
m->fd   = -1;
m->size = -1;
m->mmap = NULL;


if ((m->fd = open(path, O_RDONLY)) >= 0)
{
m->size = STEP_COUNT * esize;
m->mmap = mmap(NULL, m->size, PROT_READ,
  MAP_SHARED | MAP_LOCKED, m->fd, 0);


if ((m->mmap != NULL) && (m->mmap != MAP_FAILED))
return 0;
}


return -1;
}


static void umap_file(struct file_map *m)
{
if ((m->mmap != NULL) && (m->mmap != MAP_FAILED))
munmap(m->mmap, m->size);


if (m->fd > -1)
close(m->fd);
}




static int update_ifstat(
const char *ifname, uint64_t rxb, uint64_t rxp, uint64_t txb, uint64_t txp
) {
char path[1024];


struct stat s;
struct traffic_entry e;


snprintf(path, sizeof(path), DB_IF_FILE, ifname);


if (stat(path, &s))
{
if (init_file(path, sizeof(struct traffic_entry)))
{
fprintf(stderr, "Failed to init %s: %s\n",
path, strerror(errno));


return -1;
}
}


e.time = htonll(time(NULL));
e.rxb  = htonll(rxb);
e.rxp  = htonll(rxp);
e.txb  = htonll(txb);
e.txp  = htonll(txp);


return update_file(path, &e, sizeof(struct traffic_entry));
}


static int update_cnstat(uint32_t udp, uint32_t tcp, uint32_t other)
{
char path[1024];


struct stat s;
struct conn_entry e;


snprintf(path, sizeof(path), DB_CN_FILE);


if (stat(path, &s))
{
if (init_file(path, sizeof(struct conn_entry)))
{
fprintf(stderr, "Failed to init %s: %s\n",
path, strerror(errno));


return -1;
}
}


e.time  = htonll(time(NULL));
e.udp   = htonl(udp);
e.tcp   = htonl(tcp);
e.other = htonl(other);


return update_file(path, &e, sizeof(struct conn_entry));
}


static int update_ldstat(uint16_t load1, uint16_t load5, uint16_t load15)
{
char path[1024];


struct stat s;
struct load_entry e;


snprintf(path, sizeof(path), DB_LD_FILE);


if (stat(path, &s))
{
if (init_file(path, sizeof(struct load_entry)))
{
fprintf(stderr, "Failed to init %s: %s\n",
path, strerror(errno));


return -1;
}
}


e.time   = htonll(time(NULL));
e.load1  = htons(load1);
e.load5  = htons(load5);
e.load15 = htons(load15);


return update_file(path, &e, sizeof(struct load_entry));
}


static int run_daemon(int nofork)
{
FILE *info;
uint64_t rxb, txb, rxp, txp;
uint32_t udp, tcp, other;
float lf1, lf5, lf15;
char line[1024];
char ifname[16];


struct stat s;
const char *ipc = stat("/proc/net/nf_conntrack", &s)
? "/proc/net/ip_conntrack" : "/proc/net/nf_conntrack";


if (!nofork)
{
switch (fork())
{
case -1:
perror("fork()");
return -1;


case 0:
if (chdir("/") < 0)
{
perror("chdir()");
exit(1);
}


close(0);
close(1);
close(2);
break;


default:
exit(0);
}
}




/* go */
while (1)
{
if ((info = fopen("/proc/net/dev", "r")) != NULL)
{
while (fgets(line, sizeof(line), info))
{
if (strchr(line, '|'))
continue;


if (sscanf(line, IF_SCAN_PATTERN, ifname, &rxb, &rxp, &txb, &txp))
{

if (strncmp(ifname, "lo", sizeof(ifname)))
update_ifstat(ifname, rxb, rxp, txb, txp);
}
}


fclose(info);
}


if ((info = fopen(ipc, "r")) != NULL)
{
udp   = 0;
tcp   = 0;
other = 0;


while (fgets(line, sizeof(line), info))
{
if (strstr(line, "TIME_WAIT"))
continue;


if (sscanf(line, "%*s %*d %s", ifname) || sscanf(line, "%s %*d", ifname))
{
if (!strcmp(ifname, "tcp"))
tcp++;
else if (!strcmp(ifname, "udp"))
udp++;
else
other++;
}
}


update_cnstat(udp, tcp, other);


fclose(info);
}


if ((info = fopen("/proc/loadavg", "r")) != NULL)
{
if (fscanf(info, LD_SCAN_PATTERN, &lf1, &lf5, &lf15))
{
update_ldstat((uint16_t)(lf1  * 100),
 (uint16_t)(lf5  * 100),
 (uint16_t)(lf15 * 100));
}


fclose(info);
}


sleep(STEP_TIME);
}
}


static int run_dump_ifname(const char *ifname)
{
int i;
char path[1024];
struct file_map m;
struct traffic_entry *e;


snprintf(path, sizeof(path), DB_IF_FILE, ifname);


if (mmap_file(path, sizeof(struct traffic_entry), &m))
{
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
return 1;
}


for (i = 0; i < m.size; i += sizeof(struct traffic_entry))
{
e = (struct traffic_entry *) &m.mmap[i];


if (!e->time)
continue;


printf("[ %" PRIu64 ", %" PRIu64 ", %" PRIu64
  ", %" PRIu64 ", %" PRIu64 " ]%s\n",
ntohll(e->time),
ntohll(e->rxb), ntohll(e->rxp),
ntohll(e->txb), ntohll(e->txp),
((i + sizeof(struct traffic_entry)) < m.size) ? "," : "");
}


umap_file(&m);


return 0;
}


static int run_dump_conns(void)
{
int i;
char path[1024];
struct file_map m;
struct conn_entry *e;


snprintf(path, sizeof(path), DB_CN_FILE);


if (mmap_file(path, sizeof(struct conn_entry), &m))
{
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
return 1;
}


for (i = 0; i < m.size; i += sizeof(struct conn_entry))
{
e = (struct conn_entry *) &m.mmap[i];


if (!e->time)
continue;


printf("[ %" PRIu64 ", %u, %u, %u ]%s\n",
ntohll(e->time), ntohl(e->udp),
ntohl(e->tcp), ntohl(e->other),
((i + sizeof(struct conn_entry)) < m.size) ? "," : "");
}


umap_file(&m);


return 0;
}


static int run_dump_load(void)
{
int i;
char path[1024];
struct file_map m;
struct load_entry *e;


snprintf(path, sizeof(path), DB_LD_FILE);


if (mmap_file(path, sizeof(struct load_entry), &m))
{
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
return 1;
}


for (i = 0; i < m.size; i += sizeof(struct load_entry))
{
e = (struct load_entry *) &m.mmap[i];


if (!e->time)
continue;


printf("[ %" PRIu64 ", %u, %u, %u ]%s\n",
ntohll(e->time),
ntohs(e->load1), ntohs(e->load5), ntohs(e->load15),
((i + sizeof(struct load_entry)) < m.size) ? "," : "");
}


umap_file(&m);


return 0;
}




int main(int argc, char *argv[])
{
int opt;
int daemon = 0;
int nofork = 0;


while ((opt = getopt(argc, argv, "dfi:cl")) > -1)
{
switch (opt)
{
case 'd':
daemon = 1;
break;


case 'f':
nofork = 1;
break;


case 'i':
if (optarg)
return run_dump_ifname(optarg);
break;


case 'c':
return run_dump_conns();


case 'l':
return run_dump_load();


default:
break;
}
}


if (daemon)
return run_daemon(nofork);


else
fprintf(stderr,
"Usage:\n"
"%s -d [-f]\n"
"%s -i ifname\n"
"%s -c\n"
"%s -l\n",
argv[0], argv[0], argv[0], argv[0]
);


return 1;
}

trafiic.cgi 檔案


獲取到的資料:



timerxb(bytes)rxp(packets)  txbtxp
[
[ 1525791505, 2713473997, 2076240, 1082240, 5642 ], 
[ 1525791506, 2713766199, 2076461, 1082240, 5642 ], 
[ 1525791507, 2714048619, 2076674, 1082240, 5642 ], 
[ 1525791508, 2714310395, 2076870, 1082240, 5642 ], 
[ 1525791509, 2714655101, 2077125, 1082240, 5642 ], 
[ 1525791510, 2715002651, 2077384, 1082240, 5642 ], 
[ 1525791511, 2715264395, 2077580, 1082240, 5642 ], 
[ 1525791512, 2715496235, 2077755, 1082240, 5642 ], 
[ 1525791513, 2715728233, 2077930, 1082240, 5642 ], 
[ 1525791514, 2716014869, 2078148, 1082240, 5642 ], 
[ 1525791515, 2716303733, 2078362, 1082240, 5642 ], 
[ 1525791516, 2716549073, 2078545, 1082240, 5642 ], 
[ 1525791517, 2716714265, 2078671, 1082240, 5642 ], 
[ 1525791518, 2716898467, 2078811, 1082240, 5642 ], 
[ 1525791520, 2717081247, 2078949, 1082240, 5642 ], 
[ 1525791521, 2717283245, 2079102, 1082240, 5642 ], 
[ 1525791522, 2717538151, 2079292, 1082240, 5642 ], 
[ 1525791523, 2717835431, 2079515, 1082240, 5642 ], 
[ 1525791524, 2718148935, 2079749, 1082240, 5642 ], 
[ 1525791525, 2718557715, 2080052, 1082240, 5642 ], 
[ 1525791526, 2718854871, 2080274, 1082240, 5642 ], 
[ 1525791527, 2719098849, 2080456, 1082240, 5642 ], 
[ 1525791528, 2719252995, 2080573, 1082240, 5642 ], 
[ 1525791529, 2719416675, 2080697, 1082240, 5642 ], 
[ 1525791530, 2719565463, 2080810, 1082240, 5642 ], 
[ 1525791531, 2719747209, 2080953, 1082240, 5642 ], 
[ 1525791532, 2719929837, 2081089, 1082240, 5642 ], 
[ 1525791533, 2720096544, 2081217, 1082240, 5642 ], 
[ 1525791534, 2720257560, 2081340, 1082240, 5642 ], 
[ 1525791535, 2720417094, 2081460, 1082240, 5642 ], 
[ 1525791536, 2720556322, 2081567, 1082240, 5642 ], 
[ 1525791537, 2720808532, 2081756, 1082240, 5642 ], 
[ 1525791538, 2721011862, 2081911, 1082240, 5642 ], 
[ 1525791540, 2721217824, 2082069, 1082240, 5642 ], 
[ 1525791541, 2721445610, 2082241, 1082240, 5642 ], 
[ 1525791542, 2721581994, 2082351, 1082240, 5642 ], 
[ 1525791543, 2721725453, 2082462, 1082240, 5642 ], 
[ 1525791544, 2721859109, 2082563, 1082240, 5642 ], 
[ 1525791545, 2722011833, 2082678, 1082240, 5642 ], 
[ 1525791546, 2722170215, 2082799, 1082240, 5642 ], 
[ 1525791547, 2722317551, 2082911, 1082240, 5642 ], 
[ 1525791548, 2722475723, 2083030, 1082240, 5642 ], 
[ 1525791549, 2722649027, 2083161, 1082240, 5642 ], 
[ 1525791550, 2722914857, 2083360, 1082240, 5642 ], 
[ 1525791551, 2723114013, 2083511, 1082240, 5642 ], 
[ 1525791552, 2723278935, 2083634, 1082240, 5642 ], 
[ 1525791553, 2723441253, 2083757, 1082240, 5642 ], 
[ 1525791554, 2723588529, 2083868, 1082240, 5642 ], 
[ 1525791555, 2723722185, 2083969, 1082240, 5642 ], 
[ 1525791556, 2723903721, 2084107, 1082240, 5642 ], 
[ 1525791557, 2724194067, 2084324, 1082240, 5642 ], 
[ 1525791558, 2724461387, 2084525, 1082240, 5642 ], 
[ 1525791560, 2724644511, 2084667, 1082240, 5642 ], 
[ 1525791561, 2724845055, 2084818, 1082240, 5642 ], 
[ 1525791562, 2725013485, 2084955, 1082240, 5642 ], 
[ 1525791563, 2725171809, 2085076, 1082240, 5642 ], 
[ 1525791564, 2725428045, 2085267, 1082240, 5642 ], 
[ 1525791565, 2725590243, 2085388, 1082240, 5642 ], 
[ 1525791566, 2725726743, 2085493, 1082240, 5642 ], 
[ 1525791567, 2725879531, 2085609, 1082240, 5642 ]
]



相關推薦

路由器流量製作

1.繪製svg 向量圖 bandwidth.svg註釋:繪製流量圖的方法有三種,1) :直接將 svg  嵌入的html 頁面中2 ):通過使用embed/frame 等引用到頁面中去;<div class="cbi-table"><embed id="bw

路由器流量控制機制

所有 分享 性能 gravity 應該 策略 機制 技術分享 nag 高端路由器的流量控制機制 1. 概述 一些高端路由器上均具備流量控制機制,本篇文檔主要介紹3個應用於高端路由器的流量控制機制:反壓機制、隊列機制、流量監管。wn及擴展 2. 流量控制機制 2.1 反

百分百原創cacti跨主機跨設備拼接流量

tro mar png 屬於 包括 數據源 引用 roc 基礎 前言 日常工作中經常會遇到機房搬遷,或者IP更換什麽的。那就會引起原來的流量圖就斷掉了,再重新增加的流量圖和原來的又續不上,導致核對流量時,會遇到不少麻煩。另外本教程屬於進階使用教程,一些比較基礎的我不會在這

zblog2.3版本的asp系統是否可以超越盧松松博客的流量[]

OS http 為我 堅持 是我 客流量 size 階段 nag 最近訪問zblog官網,發現zlbog-asp2.3版本已經進入測試階段了,雖然正式版還沒有發布,想必也不久了。那麽作為aps縱橫江湖十多年的今天,blog2.2版本應該已經成熟了,為什麽還要發布這個2.3版

MT7621設計的無線路由器原理pcb和源代碼

standard 內存 圖片 truct 成本 cmp 技術分享 打開 evm MT7621設計的無線路由器原理圖pcb和源代碼 這裏有更多MT7612的資料下載 簡介:MT7612是一款高度整合式Wi-Fi單芯片,支持866 Mbps PHY速率。它完全符合IEEE 80

cacti中個別流量超過80M不顯示解決辦法

tool cti .html process -o alt tex bin 問題解決 修改前 #/usr/bin/rrdtool info /var/www/html/rra/_5328_traffic_in_792.rrd ds[traffic_in].min = 0.0

網站效能優化之雪碧製作

雪碧圖製作及使用 製作目的:由於網站上有需要小的icon且每次載入的時候都會有許多類似的請求,影響了網站的效能。所以將小圖示合併成一張雪碧圖,從而減少圖片的請求數,優化網站效能。 製作方法: 1、刀耕火種法 利用photoshop把一張張小圖合成一張雪碧圖(工作效率太低不建議使

opencv之gif動製作

import cv2 import imageio img1=cv2.imread('./yang1.jpg',1) img2=cv2.imread("./yang2.jpg",1) img3=cv2.imread("./yang3.jpg",1) img1 = cv2.resize(img1, (

supermap專題製作及釋出服務

開啟軟體。右擊工作空間中的的資料來源,點選新建資料來源,新建一個名為gulou的資料來源。右擊該資料來源,點選匯入資料集,選擇相應的影像圖匯入即可。(匯入資料集以後選擇右鍵新增到當前地圖。由於,下載器自動過濾了邊界以外的圖片,沒有圖的地圖會是黑色的,解決方法是在圖層管理器中,選擇影像引數,

IC數字前端設計開發25 (rtl時序製作工具)

timing editor http://timingeditor.sourceforge.net/     timingdesigner9.2 http://bbs.eetop.cn/thread-611436-1-1.html   &

語音波形,截斷的頻域輸出以及語譜製作

語音視覺化 參考連結1 參考連結2 參考連結3 今天我想復現一下,文中語譜圖提取部分的程式碼 由於輸入的語音有單通道和雙通道之分,處理方式是單通道不變,雙通道只取一個通道的資訊。附上程式碼: import wave as we import numpy as np

Axure學習筆記-輪播製作(包括自動輪播及點選)

覺得下面這個分享挺好,我就不重複做了。 如何製作輪播圖: (1)實現圖片輪播; (2)將圓點與輪播圖片一一對應; (3)實現前一張、後一張圖片切換。 1、所需元件 首先我們需要準備以下元件: 動態面板(1000*400)、圓(3個,15*15)、

Axure學習筆記整理2-Banner輪播製作(包括自動輪播及手動輪播)

覺得下面這個分享挺好,我就不重複做了。 另外,我在原文中添加了一個小點,關於輪播導致的圓點顏色變化的設定。請看第3章第2部分的紅色字型。   謝謝原作者的分享。以下為原文連結。 轉載至:https://www.jianshu.com/p/628a22c1f653 &nb

H5Css3動畫 背景 製作幀動畫

<span class="css-class" style="color: rgb(255, 0, 255);"><span class="before"> </span></span><span class="css-

使用TexturePacker打包遊戲貼製作幀動畫

TexturePacker是個非常好用的貼圖打包工具,最近我在學習cocos2d-x,正巧聽說了這個工具,試用了一下,非常不錯.分享給大家 比如我有一些動畫幀,為了讓動畫更加流暢,我們將所有的動畫幀合成一張圖,然後通過每次展示一部分圖片來達到動畫效果 如果是美工來拼接,他

使用超製作室內導航地圖資料

只要按照參考文件的步驟,一步一步來,就一定能夠做好室內導航地圖 1.匯入資料集 這裡需要注意的事匯入資料時,超圖桌面端會把shp和dbf檔案一起呈現出來,如圖 我們只要選擇shp檔案就可以了,不要全選,不然會冗餘 2.建立圖層組,按組匯入資料   這裡需要注意

菜雞的ShaderForge3-利用UV貼製作卡通風格材質

       說到卡通渲染,這兩年的遊戲想起的必然是崩崩崩了:                                               

【轉載】“思維導製作注意問題

“思維導圖”製作注意的問題我們學校的“思維導圖”逐漸被師生認可並自覺開始使用,但部分師生對思維導圖的製作方式並不明確,現借鑑部分專著的做法,讓大家更深入地瞭解“思維導圖”製作時應注意的問題。(我利用思維

使用SVG路徑製作線追蹤特效

近期看了幾篇三精-大精wing的“互動炸了”系列文章,收穫頗多,這裡學習記錄一下。 本文知識點一覽: 專案地址在最下面。 本篇主要記錄如何動態繪製曲線,從而形成很精緻的特性,先上圖: SVG簡介 SVG 意為可縮放向量圖形(Scalabl

幾款線上腦製作工具

在來不及開啟思維導圖的專業軟體是,採用線上工具也是很好的選項。 介紹:介紹百度腦圖是由百度公司開發的一款線上思維導圖編輯器,百度使用者可以直接通過百度腦圖網頁版本,介面還是相對比較好看的,百度家產品,向來風格簡約大方,受人喜愛。 介紹:Proce