python10min手寫一個服務器內存監控系統

簡易的內存監控系統

本文須要有必定的python和前端基礎,若是沒基礎的,請關注我後續的基礎教程系列博客javascript

文章源地址,還能夠看到具體的代碼,喜歡請加個星星html

騰訊視頻連接

錄製中間網出問題了,重啓了一下,因此有兩部分前端

本文的目的在於,儘量用簡單的代碼,讓你們瞭解內存監控的原理 主題思路java

  • 獲取內存信息
  • 存儲信息
  • 展示
  • 後續擴展
    • 加主機名,monitor部署在多臺機器,不直接插數據庫
    • 經過http請求的方式,一臺機器起flask專門存數據monitor

思路圖 python

第一步,咱們須要獲取內存信息

其實全部的監控項,包括內存數據,都是從文件中讀取的,你們執行如下 cat /proc/meminfo就能夠看到關於內存的信息,咱們關注的是前四行,總內存,空閒內存,緩衝和緩存大小mysql

計算內存佔用量公式:jquery

(總內存-空閒內存-緩衝-緩存)/1024Mbgit

代碼呼之欲出 monitor.pygithub

用with打開文件,能夠自動關閉,比直接open優雅那麼一丟丟web

def getMem():
    with open('/proc/meminfo') as f:
        total = int(f.readline().split()[1])
        free = int(f.readline().split()[1])
        buffers = int(f.readline().split()[1])
        cache = int(f.readline().split()[1])
    mem_use = total-free-buffers-cache
    print mem_use/1024
while True:
    time.sleep(1)
    getMem()

執行文件 python monitor.py,每一秒打印一條內存信息

[woniu@teach memory]$ python mointor.py 
2920
2919
2919
2919
2919

咱們能夠寫個很搓的測試代碼,佔用一點內存,看看數據會不會變 執行下面代碼,能看到內存使用量明顯多了幾M

# test.py

s = 'akdsakjhdjkashdjkhasjkdhasjkdhkjashdaskjhfoopnnm,ioqouiew'*100000

for i in s:
    for j in s:
        s.count(j)

獲取內存數據done!

第二步存儲數據庫

咱們選用mysql

新建表格,咱們須要兩個字段,內存和時間 sql呼之欲出,簡單粗暴

create memory(memory int,time int)

咱們的 monitor.py就不能只打印內存信息了,要存儲數據庫啦,引入mysql模塊,代碼以下

import time
import MySQLdb as mysql

db = mysql.connect(user="reboot",passwd="reboot123",db="memory",host="localhost")
db.autocommit(True)
cur = db.cursor()

def getMem():
    with open('/proc/meminfo') as f:
        total = int(f.readline().split()[1])
        free = int(f.readline().split()[1])
        buffers = int(f.readline().split()[1])
        cache = int(f.readline().split()[1])
    mem_use = total-free-buffers-cache
    t = int(time.time())
    sql = 'insert into memory (memory,time) value (%s,%s)'%(mem_use/1024,t)
    cur.execute(sql)
    print mem_use/1024
    #print 'ok'
while True:
    time.sleep(1)
    getMem()

比以前的多了拼接sql和執行的步驟,具體過程見視頻,你們到數據庫裏執行一下下面的sql,就能看到咱們辛辛苦苦獲取的內存數據啦

select * from memory

咱們的數據庫裏數據愈來愈多,怎麼展現呢

咱們須要flask 咱們看下文件結構

.
├── flask_web.py web後端代碼
├── mointor.py 監控數據獲取
├── static 靜態文件,第三方圖表庫
│   ├── exporting.js
│   ├── highstock.js
│   └── jquery.js
├── templates
│   └── index.html 展現前端頁面
└── test.py 佔用內存的測試代碼

flask_web就是咱們的web服務代碼,template下面的html,就是前端展現的文件,static下面是第三方庫

flask_web的代碼以下

  • 提供兩個路由
    • 根目錄渲染文件index.html
    • /data路由去數據庫插數據,返回json,供畫圖使用
from flask import Flask,render_template,request
import MySQLdb as mysql

con = mysql.connect(user='reboot',passwd='reboot123',host='localhost',db='memory')

con.autocommit(True)
cur = con.cursor()
app = Flask(__name__)
import json

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/data')
def data():
    sql = 'select * from memory'
    cur.execute(sql)
    arr = []
    for i in cur.fetchall():
        arr.append([i[1]*1000,i[0]])
    return json.dumps(arr)

if __name__=='__main__':
    app.run(host='0.0.0.0',port=9092,debug=True)

前端index.html highstock的demo頁面,copy過來,具體過程見視頻

<html>
<head>
<title>51reboot</title>
</head>

<body>
hello world

<div id="container" style="height: 400px; min-width: 310px"></div>

<script src='/static/jquery.js'></script>
<script src='/static/highstock.js'></script>
<script src='/static/exporting.js'></script>
<script>
$(function () {
    // 使用當前時區,不然東八區會差八個小時
    Highcharts.setOptions({
        global: {
            useUTC: false
        }
    });
    $.getJSON('/data', function (data) {
        // Create the chart
        $('#container').highcharts('StockChart', {
            rangeSelector : {
                selected : 1
            },
            title : {
                text : '內存數據'
            },
            series : [{
                name : '本機內存',
                data : data,
                tooltip: {
                    valueDecimals: 2
                }
            }]
        });
    });
});
</script>
</body>
</html>

具體觀察數據結構的過程,見視頻和demo連接,咱們作的 就是把數據庫裏的數據,拼接成前端畫圖須要的數據,展示出來

這時候前端就能看到圖表啦

咱們並不只限於此,若是想實時的看到內存,應該怎麼搞呢

  • 查詢數據時候增長一個時間戳當限制條件,再次查詢時,只返回兩次查詢之間的增量數據
  • 前端動態添加增量結點數據到圖表中
  • 代碼呼之欲出

python

tmp_time = 0

@app.route('/data')
def data():
    global tmp_time
    if tmp_time>0:
        sql = 'select * from memory where time>%s' % (tmp_time/1000)
    else:
        sql = 'select * from memory'
    cur.execute(sql)
    arr = []
    for i in cur.fetchall():
        arr.append([i[1]*1000,i[0]])
    if len(arr)>0:
        tmp_time = arr[-1][0]
    return json.dumps(arr)

前端,3秒查一次增量數據

$.getJSON('/data', function (data) {

        // Create the chart
        $('#container').highcharts('StockChart', {
        chart:{
        events:{
            load:function(){
                var series = this.series[0]
                setInterval(function(){
                $.getJSON('/data',function(res){
                    $.each(res,function(i,v){
                        series.addPoint(v)
                    })
                })
                },3000)
            }
        }
        },
            rangeSelector : {
                selected : 1
            },
            title : {
                text : 'AAPL Stock Price'
            },
            series : [{
                name : 'AAPL',
                data : data,
                tooltip: {
                    valueDecimals: 2
                }
            }]
        });
    });

done!兩個文件都搞定,double kill! 效果

最終代碼直接下載那個木看也行

監控文件monitor.py

import time
import MySQLdb as mysql

db = mysql.connect(user="reboot",passwd="reboot123",db="memory",host="localhost")
db.autocommit(True)
cur = db.cursor()

def getMem():
    f = open('/proc/meminfo')
    total = int(f.readline().split()[1])
    free = int(f.readline().split()[1])
    buffers = int(f.readline().split()[1])
    cache = int(f.readline().split()[1])
    mem_use = total-free-buffers-cache
    t = int(time.time())
    sql = 'insert into memory (memory,time) value (%s,%s)'%(mem_use/1024,t)
    cur.execute(sql)
    print mem_use/1024
    #print 'ok'
while True:
    time.sleep(1)
    getMem()

flask

from flask import Flask,render_template,request
import MySQLdb as mysql

con = mysql.connect(user='reboot',passwd='reboot123',host='localhost',db='memory')
con.autocommit(True)
cur = con.cursor()
app = Flask(__name__)
import json

@app.route('/')
def index():
    return render_template('index.html')

tmp_time = 0

@app.route('/data')
def data():
    global tmp_time
    if tmp_time>0:
        sql = 'select * from memory where time>%s' % (tmp_time/1000)
    else:
        sql = 'select * from memory'
    cur.execute(sql)
    arr = []
    for i in cur.fetchall():
        arr.append([i[1]*1000,i[0]])
    if len(arr)>0:
        tmp_time = arr[-1][0]
    return json.dumps(arr)

if __name__=='__main__':
    app.run(host='0.0.0.0',port=9092,debug=True)

前端

<html>
<head>
<title>51reboot</title>
<meta charset='utf-8'>
</head>

<body>
hello world

<div id="container" style="height: 400px; min-width: 310px"></div>

<script src='/static/jquery.js'></script>
<script src='/static/highstock.js'></script>
<script src='/static/exporting.js'></script>
<script>
$(function () {
    // 使用當前時區,不然東八區會差八個小時
    Highcharts.setOptions({
        global: {
            useUTC: false
        }
    });
    $.getJSON('/data', function (data) {

        // Create the chart
        $('#container').highcharts('StockChart', {
        chart:{
        events:{
        
            load:function(){
            
                var series = this.series[0]
                setInterval(function(){
                $.getJSON('/data',function(res){
                    $.each(res,function(i,v){
                        series.addPoint(v)
                    })
                })
                },3000)
            }
        }
        },

            rangeSelector : {
                selected : 1
            },

            title : {
                text : '內存數據'
            },

            series : [{
                name : '本機內存',
                data : data,
                tooltip: {
                    valueDecimals: 2
                }
            }]
        });
    });

});
</script>

</body>
</html>

代碼沒有特別注意細節,但願你們喜歡。


歡迎你們關注我的公共號,高品質運維開發

相關文章
相關標籤/搜索