转:基于web的资源视图(cpu、内存、流量)显示方案
基于web的资源视图(cpu、内存、流量)显示方案 2012-08-08 12:35:55
标签:web
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://speakingbaicai.blog.51cto.com/5667326/958314
本人第一次写blog,努力中。
言归正传。这篇博客完成的工作是在网页上以图表的方式,显示cpu、内存、流量等资源信息。先上一副效果图:
使用工具与环境:
web架构:基于python的django
画图工具:基于js的画图工具 highcharts 链接http://www.highcharts.com/
页面的基本显示由html代码负责,没啥可说的。html代码如下:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <title>计算机资源视图</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <link rel="stylesheet" type="text/css" href="/media/css/basic.css"/>
- <script type="text/javascript" src="/media/js/jquery-1.4.2.min.js" ></script>
- <script type="text/javascript" src="/media/jschart/highcharts.js"></script>
- <script type="text/javascript" src="/media/jschart/modules/exporting.js"></script>
- <script type="text/javascript" src="/media/mjs/physical.js"></script>
- </head>
- <body>
- <!-- #charts -->
- <charts>
- <div class="charts">
- <div class="chartshead"><span>主控节点 资源视图</span></div>
- <div id="cpu"></div>
- <div id="mem"></div>
- <div id="rx"></div>
- <div id="tx"></div>
- <br style="clear:both"/>
- </div>
- </charts>
- </body>
- </html>
画图主要是使用js代码,使用ajax机制定时异步获得数据,然后在图上添加数据点。每5秒添加一个新点。js代码如下:
- var chart_cpu;
- var chart_mem;
- var chart_rx;
- var chart_tx;
- var maxmem;
- var mem;
- var pre_cpu = 0
- var pre_cpu_total = 0
- var pre_rb = 0
- var pre_tb = 0
- var flag = 1
- var timeout = 5000
- //var para = window.location.search;
- //更新
- function requestData() {
- var stime = new Date();
- $.ajax({
- //async: false,
- url:'/ajax/jsonmgt',
- success: function(point) {
- // add 4 points
- var x = (new Date()).getTime() + 8*3600*1000; // 当前时间
- var out = eval("(" + point + ")")
- //var out = eval( point )
- maxmem = out[0]
- mem = out[1]
- cpu_use = out[2]
- cpu_total = out[3]
- rb = out[4]
- tb = out[5]
- memrate = mem/maxmem * 100
- //cpu
- d_cpu = cpu_use - pre_cpu
- d_cpu_total = cpu_total - pre_cpu_total
- pre_cpu = cpu_use
- pre_cpu_total = cpu_total
- cpurate = d_cpu/d_cpu_total *100
- if(cpurate == 100)
- cpurate = 99.9
- //rb tb
- d_rb = rb - pre_rb
- d_tb = tb - pre_tb
- pre_rb = rb
- pre_tb = tb
- rkb = d_rb/1024
- tkb = d_tb/1024
- if(flag == 1){
- rkb = 0
- tkb = 0
- cpurate = 0
- memrate = 0
- flag =0
- }
- //add points
- chart_cpu.series[0].addPoint([x,cpurate], true, true);
- chart_mem.series[0].addPoint([x,memrate], true, true);
- chart_rx.series[0].addPoint([x,rkb], true, true);
- chart_tx.series[0].addPoint([x,tkb], true, true);
- var etime = new Date();
- d_date=etime.getTime()-stime.getTime();
- setTimeout(requestData, timeout - d_date);
- },
- cache: false
- });
- }
- //cpu
- $(document).ready(function(){
- chart_cpu = new Highcharts.Chart({
- chart: {
- renderTo: 'cpu', //图表放置的容器,DIV
- defaultSeriesType: 'spline', //图表类型为曲线图
- backgroundColor:'#DFFDFD',
- events: {
- //load: requestData
- }
- },
- title: {
- text: 'CPU负载' //图表标题
- },
- xAxis: { //设置X轴
- title: { text: '时间' },
- type: 'datetime', //X轴为日期时间类型
- tickPixelInterval: 150 //X轴标签间隔
- },
- yAxis: { //设置Y轴
- title: { text: 'CPU使用率' },
- labels: {
- formatter: function() {
- return this.value +'%';
- }
- },
- max: 100, //Y轴最大值
- min: 0 //Y轴最小值
- },
- tooltip: {//当鼠标悬置数据点时的提示框
- formatter: function() { //格式化提示信息
- return Highcharts.dateFormat('%H:%M:%S', this.x) +' '+
- Highcharts.numberFormat(this.y, 2)+'%';
- }
- },
- legend: {
- enabled: false //设置图例不可见
- },
- exporting: {
- enabled: false //设置导出按钮不可用
- },
- series: [{
- data: (function() { //设置默认数据,
- var data = [],
- time = (new Date()).getTime() + 8*3600*1000,
- i;
- for (i = -19; i < 0; i++) {
- data.push({
- x: time + i * timeout,
- y: 0 * 100
- });
- }
- return data;
- })()
- }]
- });
- });
- //mem
- $(function() {
- chart_mem = new Highcharts.Chart({
- chart: {
- renderTo: 'mem', //图表放置的容器,DIV
- defaultSeriesType: 'spline', //图表类型为曲线图
- backgroundColor:'#DFFDFD',
- events: {
- }
- },
- title: {
- text: '内存负载' //图表标题
- },
- xAxis: { //设置X轴
- title: { text: '时间' },
- type: 'datetime', //X轴为日期时间类型
- tickPixelInterval: 150 //X轴标签间隔
- },
- yAxis: { //设置Y轴
- title: { text: '内存使用记录' },
- labels: {
- formatter: function() {
- return this.value + '%';
- }
- },
- max: 100, //Y轴最大值
- min: 0 //Y轴最小值
- },
- tooltip: {//当鼠标悬置数据点时的提示框
- formatter: function() { //格式化提示信息
- return Highcharts.dateFormat('%H:%M:%S', this.x) +' '+
- Highcharts.numberFormat(this.y, 2) + '%' + ' ' +
- Highcharts.numberFormat(mem,0) + 'MB';
- }
- },
- legend: {
- enabled: false //设置图例不可见
- },
- exporting: {
- enabled: false //设置导出按钮不可用
- },
- series: [{
- data: (function() { //设置默认数据,
- var data = [],
- time = (new Date()).getTime()+8*3600*1000,
- i;
- for (i = -19; i < 0; i++) {
- data.push({
- x: time + i * timeout,
- y: 0
- });
- }
- return data;
- })()
- }]
- });
- });
- //rx
- $(function() {
- chart_rx = new Highcharts.Chart({
- chart: {
- renderTo: 'rx', //图表放置的容器,DIV
- defaultSeriesType: 'spline', //图表类型为曲线图
- backgroundColor:'#DFFDFD', //背景颜色
- events: {
- }
- },
- title: {
- text: '网络接收流量' //图表标题
- },
- xAxis: { //设置X轴
- title: { text: '时间' },
- type: 'datetime', //X轴为日期时间类型
- tickPixelInterval: 150 //X轴标签间隔
- },
- yAxis: { //设置Y轴
- title: { text: '接收网络流量' },
- labels: {
- formatter: function() {
- return this.value +'kb/s';
- }
- },
- //max: 200, //Y轴最大值
- min: 0 //Y轴最小值
- },
- tooltip: {//当鼠标悬置数据点时的提示框
- formatter: function() { //格式化提示信息
- return Highcharts.dateFormat('%H:%M:%S', this.x) +' '+
- Highcharts.numberFormat(this.y, 2)+'kb/s';
- }
- },
- legend: {
- enabled: false //设置图例不可见
- },
- exporting: {
- enabled: false //设置导出按钮不可用
- },
- series: [{
- data: (function() { //设置默认数据,
- var data = [],
- time = (new Date()).getTime() + 8*3600*1000,
- i;
- for (i = -19; i < 0; i++) {
- data.push({
- x: time + i * timeout,
- y: 0
- });
- }
- return data;
- })()
- }]
- });
- });
- //tx
- $(function() {
- chart_tx = new Highcharts.Chart({
- chart: {
- renderTo: 'tx', //图表放置的容器,DIV
- defaultSeriesType: 'spline', //图表类型为曲线图
- backgroundColor:'#DFFDFD',
- events: {
- load: requestData
- }
- },
- title: {
- text: '网络发送流量' //图表标题
- },
- xAxis: { //设置X轴
- title: { text: '时间' },
- type: 'datetime', //X轴为日期时间类型
- tickPixelInterval: 150 //X轴标签间隔
- },
- yAxis: { //设置Y轴
- title: { text: '发送网络流量' },
- labels: {
- formatter: function() {
- return this.value +'kb/s';
- }
- },
- //max: 200, //Y轴最大值
- min: 0 //Y轴最小值
- },
- tooltip: {//当鼠标悬置数据点时的提示框
- formatter: function() { //格式化提示信息
- return Highcharts.dateFormat('%H:%M:%S', this.x) +' '+
- Highcharts.numberFormat(this.y, 2)+'kb/s';
- }
- },
- legend: {
- enabled: false //设置图例不可见
- },
- exporting: {
- enabled: false //设置导出按钮不可用
- },
- series: [{
- data: (function() { //设置默认数据,
- var data = [],
- time = (new Date()).getTime() + 8*3600*1000,
- i;
- for (i = -19; i < 0; i++) {
- data.push({
- x: time + i * timeout,
- y: 0
- });
- }
- return data;
- })()
- }]
- });
- })
使用ajax,就需要有数据源定期提供数据。使用c语言写一个程序(取名mgtinfo.c)抓取瞬时的cpu、内存、流量。代码如下:
- #include <stdlib.h>
- #include <stdio.h>
- #include <sys/stat.h>
- typedef struct //定义一个cpu occupy的结构体
- {
- char name[20]; //定义一个char类型的数组名name有20个元素
- long user; //定义一个无符号的int类型的user
- long nice; //定义一个无符号的int类型的nice
- long system;//定义一个无符号的int类型的system
- long idle; //定义一个无符号的int类型的idle
- }CPU_OCCUPY;
- typedef struct //定义一个mem occupy的结构体
- {
- char name[20]; //定义一个char类型的数组名name有20个元素
- long total;
- //char name2[20];
- char unit[20];
- long free;
- long buffers;
- long cached;
- }MEM_OCCUPY;
- typedef struct //定义一个cpu occupy的结构体
- {
- char name[20]; //定义一个char类型的数组名name有20个元素
- long rb, rpkt, r_err, r_drop, r_fifo, r_frame, r_compr, r_mcast;
- long tb, tpkt, t_err, t_drop, t_fifo, t_coll, t_carrier, t_compr;
- }NET_OCCUPY;
- int get_memoccupy (MEM_OCCUPY *mem) //对无类型get函数含有一个形参结构体类弄的指针O
- {
- FILE *fd;
- int n;
- char buf[256];
- MEM_OCCUPY *m;
- m=mem;
- long MemFree, Buffers, Cached;
- fd = fopen ("/proc/meminfo", "r");
- fgets (buf, sizeof(buf), fd);
- sscanf (buf, "%s %ld %s", &m->name, &m->total, &m->unit);
- fgets (buf, sizeof(buf), fd);
- sscanf (buf, "%s %ld %s", m->name, &m->free, m->unit);
- fgets (buf, sizeof(buf), fd);
- sscanf (buf, "%s %ld %s", m->name, &m->buffers, m->unit);
- fgets (buf, sizeof(buf), fd);
- sscanf (buf, "%s %ld %s", m->name, &m->cached, m->unit);
- fclose(fd); //关闭文件fd
- return 0;
- }
- int get_cpuoccupy (CPU_OCCUPY *cpust) //对无类型get函数含有一个形参结构体类弄的指针O
- {
- FILE *fd;
- int n;
- char buf[256];
- CPU_OCCUPY *cpu_occupy;
- cpu_occupy=cpust;
- if ((fd = fopen ("/proc/stat", "r")) != NULL){
- while (fgets (buf, sizeof(buf), fd)){
- if( *buf == 'c' && *(buf + 1) == 'p') break;
- }
- fclose (fd);
- }
- else
- printf("read file failed\n");
- sscanf (buf, "cpu %ld %ld %ld %ld", &cpu_occupy->user, &cpu_occupy->nice,&cpu_occupy->system, &cpu_occupy->idle);
- //printf("%ld\n", cpu_occupy->user);
- return 0;
- }
- int get_netoccupy (NET_OCCUPY *net) //对无类型get函数含有一个形参结构体类弄的指针O
- {
- FILE *fd;
- char buf[256];
- NET_OCCUPY *net_occupy;
- net_occupy = net;
- //long MemFree, Buffers, Cached;
- fd = fopen ("/proc/net/dev", "r");
- fgets (buf, sizeof(buf), fd);
- fgets (buf, sizeof(buf), fd);
- fgets (buf, sizeof(buf), fd);
- fgets (buf, sizeof(buf), fd);
- //printf("%s",buf);
- sscanf (buf, "%s %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", &net_occupy->name, &net_occupy->rb ,&net_occupy->rpkt, &net_occupy->r_err, &net_occupy->r_drop, &net_occupy->r_fifo ,&net_occupy->r_frame, &net_occupy->r_compr, &net_occupy->r_mcast, &net_occupy->tb, &net_occupy->tpkt);
- fclose(fd); //关闭文件fd
- return 0;
- }
- int cal_cpuoccupy (CPU_OCCUPY *o, CPU_OCCUPY *n)
- {
- unsigned long od, nd;
- unsigned long id, sd;
- int cpu_use = 0;
- od = (unsigned long) (o->user + o->nice + o->system +o->idle);//第一次(用户+优先级+系统+空闲)的时间再赋给od
- nd = (unsigned long) (n->user + n->nice + n->system +n->idle);//第二次(用户+优先级+系统+空闲)的时间再赋给od
- id = (unsigned long) (n->user - o->user); //用户第一次和第二次的时间之差再赋给id
- sd = (unsigned long) (n->system - o->system);//系统第一次和第二次的时间之差再赋给sd
- if((nd-od) != 0)
- cpu_use = (int)((sd+id)*10000)/(nd-od); //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used
- else cpu_use = 0;
- return cpu_use;
- }
- int main()
- {
- CPU_OCCUPY cpu_stat;
- MEM_OCCUPY mem_stat;
- NET_OCCUPY net_stat;
- long cpu_use, cpu_total;
- //获取内存
- get_memoccupy ((MEM_OCCUPY *)&mem_stat);
- //第一次获取cpu使用情况
- get_cpuoccupy((CPU_OCCUPY *)&cpu_stat);
- cpu_use = cpu_stat.user + cpu_stat.nice + cpu_stat.system;
- cpu_total=cpu_stat.user + cpu_stat.nice + cpu_stat.system + cpu_stat.idle;
- //printf("%ld,%ld,%ld,%ld\n",cpu_stat.user,cpu_stat.nice,cpu_stat.system,cpu_stat.idle);
- get_netoccupy((NET_OCCUPY *)&net_stat);
- printf("%ld,%ld,%ld,%ld,%ld,%ld\n",mem_stat.total/1024,(mem_stat.total-mem_stat.free-mem_stat.buffers-mem_stat.cached)/1024,cpu_use,cpu_total,net_stat.rb,net_stat.tb);
- return 0;
- }
在django中,需要写一个函数jsonmgt,作为ajax请求的响应。每次执行,jsonmgt调用mgtinfo.c,获得瞬时cpu、内存、流量后,以json数据形式返回给页面。页面再用上面贴的js代码添加数据点绘图。
- # time data
- def jsonmgt( request ):
- print "calulate data"
- cmd="cmd/./mgtinfo"
- output = os.popen(cmd,'r')
- ret = output.read()
- info = ret.split(',')
- maxmem = string.atof(info[0])
- mem = string.atof(info[1])
- cpu_use = string.atof(info[2])
- cpu_total = string.atof(info[3])
- rb = string.atof(info[4])
- tb = string.atof(info[5])
- output.close()
- data = [maxmem,mem,cpu_use,cpu_total,rb,tb]
- data = simplejson.dumps( data, cls = QuerySetEncoder )
- return HttpResponse( data )
- # django ajax
- class QuerySetEncoder( simplejson.JSONEncoder ):
- """
- Encoding QuerySet into JSON format.
- """
- def default( self, object ):
- try:
- return serializers.serialize( "python", object,ensure_ascii = False )
- except:
- return simplejson.JSONEncoder.default( self, object )
本文出自 “说话的白菜” 博客,请务必保留此出处http://speakingbaicai.blog.51cto.com/5667326/958314
=============================