使用python編寫一個監控使用內存並使用flask模塊出圖

使用python編寫一個監控使用內存情況的網頁界面

環境:centos-7.2

1. 獲取內存信息

[root@cml10 web_mem]# cat /proc/meminfo
MemTotal:        1001332 kB
MemFree:          147800 kB
MemAvailable:     257776 kB
Buffers:               0 kB
Cached:           201032 kB

 

說明:

buffers是指用來給塊設備做的緩衝大小

cached是用來給文件做緩衝。

MemFree 是空閒內存

 

算法:

已使用內存 = MemTotal - MemFree - Buffers – Cached(centos6)

已使用內存 = MemTotal - MemAvailable(centos7)

2. 存儲信息

1. 安裝myql

# 安裝mysql

[root@cml10 web_mem]# yum  install  -y  mariadb-server  mariadb

 

#啓動mysql

[root@cml10 web_mem]# systemctl start mariadb

 

#快速配置,設置root密碼

[root@cml10 web_mem]# mysql_secure_installation

 

2. 創建數據庫

[root@cml10 web_mem]#  mysql  -uroot  -predhat
mysql> create database  mem;
mysql> use mem;
mysql> create table mem (mem int(10), date int(20));

注意:用time字段表示時間戳,使用int類型

      爲簡單化,這裏的數據庫名和表名,還有字段名,都使用mem,含義不同。

 

3. 把獲取到的內存信息保存到數據庫

1)安裝python的mysql庫

 [root@cml10 web_mem]#  yum  install  MySQL-python   -y

 

#寫一個python調用mysql模塊持續觀察內存並寫入數據庫

[root@cml10 web_mem]# cat save_mem.py
#_*_coding:utf-8_*_
 
import time
import MySQLdb as mysql
 
db = mysql.connect(user="root",passwd="redhat",db="mem",host="localhost")
 
db.autocommit(True)  #自動提交模式,把每個查詢都當做一個單獨的事務自動執行
cur = db.cursor()   #獲取一個 “遊標”,用來執行sql語句
 
def save_mem():
       f = open("/proc/meminfo")
       total = int(f.readlines()[0].split()[1])
       f = open("/proc/meminfo")
       aviable = int(f.readlines()[2].split()[1])
       mem = (total-aviable)/1024              # unit: MB(把已用內存轉成MB單位)
       cur_time = int(time.time())
       sql = 'insert into mem(mem,date) values(%s,%s)' %(mem,cur_time)
       cur.execute(sql)
while True:
       save_mem()
       time.sleep(1)                              # sleep 1 second(等待一秒時間)

 

##編寫一個消耗內存的程序:

[root@cml10 web_mem]# consumer_mem.py

s1 = "Today is good   day! "
s2 = s1 * 10000
 
for i in range(1,100):
        for j in range(1,100):
                s2.count(s1)


 

測試:

在一個終端運行save_mem.py, 然後在另一個終端運行consumer_mempy

觀察終端1的輸出,輸出信息是否發生變化。

 

 

3. 展示信息構建web服務

安裝flask

使用flask框架構建web服務

 

#安裝pip

[root@cml10 web_mem]# cd  /usr/local/src
[root@cml10 src]# wget  --no-check-certificate  https://bootstrap.pypa.io/get-pip.py
[root@cml10 src]# python  get-pip.py

 

#使用pip安裝python的flask模塊:

[root@cml10 src]# pip  install  flask

編輯後臺頁面

[root@cml10 web_mem]# flask_web.py
from  flask  import  Flask    #導入flask中的Flask模塊=import flask 引用時要flask.Flask
 
app = Flask(__name__)  #產生一個flask實例,即一個網站應用程序。
 
@app.route('/')   #表示訪問網站的根目錄時,觸發函數index()
def index():
       return 'hello flask'
 
if __name__=='__main__':     #指的是隻能自己運行的纔可以運行網站。
       app.run(host='0.0.0.0', port=9092, debug=True)  
#任意主機可以訪問,使用9092端口,啓用調試模式

 

 

關閉防火牆,或者進行配置

[root@cml10 web_mem]# systemctl stop firewalld

 

啓動flask web服務:

[root@cml10 web_mem]# python   flask_web.py

 

在任何客戶端主機的瀏覽器測試:

http://192.168.5.200:9092

 

使用真實數據渲染圖標

1. 在後臺程序中獲取真實數據

2.   爲便於調試,先把真實數據直接打印到後臺的終端,然後把後臺獲取到的數據發送到前端(用json格式)

 

 

  修改後臺程序 flask_web.py

[root@cml10 web_mem]# cat flask_web.py
#_*_coding:utf-8_*_
from flask import Flask,render_template
import MySQLdb as mysql
import json
 
con = mysql.connect(user="root",passwd="redhat",db="mem",host="localhost")
con.autocommit(True)
cur = con.cursor()
 
app = Flask(__name__)
 
last_time = 0
 
@app.route('/')
def index():
#     return "cml test"
       return render_template('index.html')
 
@app.route('/cml')
def cml():
       global last_time
       if (last_time > 0):
              sql = 'select * from mem where date > %s' %(last_time/1000)
       else:
              sql = 'select * from mem'
       cur.execute(sql)
       arr = []
       for i in cur.fetchall():
#            print i
              arr.append([i[1]*1000,i[0]])
#     return "ok"
       if (len(arr) > 0):
              last_time = arr[-1][0]
       return json.dumps(arr)
 
if __name__=='__main__':
       app.run(host='0.0.0.0',port=9092,debug=True)

 

動靜態文件分離和使用圖表展現

使用highchats圖標庫

測試圖表顯示

使用示例數據測試圖表顯示:

 

1. 準備用於顯示圖片的基礎js文件

   jquery.js 和 highstock.js(可以在github網站上搜索下載)

   並把這兩個文件保存到網站根目錄下的static子目錄下

   [root@cml10 web_mem]# mkdir  static
   [root@cml10 web_mem]# cp   jquery.js  highstock.js   static

 

[root@cml10 web_mem]# tree
.
├── flask_web.py
├── save_mem.py
├── static
│   ├── highstock.js
│   └── jquery.js
└── templates
    └── index.html
 
2 directories, 5 files

2. 選擇圖表模板

選擇一個基本的圖 single line series

https://www.hcharts.cn/demo/highstock/basic-line

 

[root@cml10 web_mem]# cat templates/index.html
from flask import Flask,render_template
import MySQLdb as mysql
import  json
 
con = mysql.connect(user="root", passwd="redhat", db="mem", host="localhost")
con.autocommit(True)
cur = con.cursor()
 
app = Flask(__name__)
 
@app.route('/')
def index():
       #return 'cml test'
       return render_template('index.html')
 
@app.route('/cml')
def cml():
       sql = 'select * from memory'
       cur.execute(sql)
       arr = []
       for i in cur.fetchall():
              #print i
              arr.append([i[1]*1000, i[0])   #如果寫入數據庫使沒轉這裏可以,除以1024,以MB爲單位
       #return 'ok'
       return json.dumps(arr)
 
if __name__=='__main__':
       app.run(host='0.0.0.0', port=9092, debug=True)

 

測試:(先執行save_mem.py在執行flask_web.py)

[root@cml10 web_mem]# python save_mem.py
[root@cml10 web_mem]# python flask_web.py

##最後出圖展示的結果:

1.png


4. 擴展獲取增量數據

##修改文件加上判斷取最新的值

[root@cml10 web_mem]# cat flask_web.py
#_*_coding:utf-8_*_
from flask import Flask,render_template
import MySQLdb as mysql
import json
 
con = mysql.connect(user="root",passwd="redhat",db="mem",host="localhost")
con.autocommit(True)
cur = con.cursor()
 
app = Flask(__name__)
 
last_time = 0
 
@app.route('/')
def index():
#     return "cml test"
       return render_template('index.html')
 
@app.route('/cml')
def cml():
       global last_time
       if (last_time > 0):
              sql = 'select * from mem where date > %s' %(last_time/1000)
       else:
              sql = 'select * from mem'
       cur.execute(sql)
       arr = []
       for i in cur.fetchall():
#            print i
              arr.append([i[1]*1000,i[0]])
#     return "ok"
       if (len(arr) > 0):
              last_time = arr[-1][0]           ##意思是取最新的值
       return json.dumps(arr)
 
if __name__=='__main__':
       app.run(host='0.0.0.0',port=9092,debug=True)

 

 

##修改index.html文件前端輸出自動更新

[root@cml10 web_mem]# cat templates/index.html
<html>
<head>
        <title> my memory monitor </title>
</head>
 
<body>
<div id="container" style="min-width:400px;height:400px"></div>
 
<script src='/static/jquery.js'></script>
<script src='/static/highstock.js'></script>
<script type="text/javascript"> 
     Highcharts.setOptions({ global: { useUTC: false } });  
</script>
<script>
$(function () {
    $.getJSON('/cml', function (cml) {
        $('#container').highcharts('StockChart', {
           chart: {
                            events: {
                                   load:function() {
                                          var series = this.series[0]
                                          setInterval(
                                                 // 表示每隔3000ms(參數2),就執行指定的函數(參數1)
                                                 function(){
                                                        $.getJSON('/cml',function(res){
                                                               $.each(res, function(i,v){
                                                                    series.addPoint(v)
                                                               })
                                                        })
                                                 },
                                                 3000)
                                   }            
                            }
                     },
 
            rangeSelector : {
                selected : 1
            },
            title : {
                text : '服務器以用內存使用情況'
            },
            series : [{
                name : 'AAPL',
                data : cml,
                tooltip: {
                    valueDecimals: 2
                }
            }]
        });
    });
});
 
</script>
</body>
</html>


###注意新寫了一遍擴展監控多臺主機上的內存情況代碼:(需要可以看看,也可以給給意見)

http://blog.51cto.com/legehappy/2043776

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章