flask+sqlite3+echarts3 系統監控

總的而言,分三部分:
1.監控器(monitor.py): 每秒獲取系統的四個cpu的使用率,存入數據庫。
2.路由器(app.py): 響應頁面的ajax,獲取最新的一條或多條數據。
3.頁面index.html): 發出ajax請求,更新echarts圖表javascript

1、監控器

使用了psutil庫,對系統進行監控。html

import psutil
import sqlite3
import time

'''
說明:四個cpu使用率,顯然是臨時數據,因此最好用內存數據庫,如Redis等
可是這裏強行使用sqlite3,無論了,哪一個叫他是內置的呢?!
'''

db_name = 'mydb.db'


def create_db():
    # 鏈接
    conn = sqlite3.connect(db_name)
    c = conn.cursor()

    # 建立表 
    c.execute('''DROP TABLE IF EXISTS cpu''') # 刪除舊錶,若是存在(由於這是臨時數據)
    c.execute('''CREATE TABLE cpu (id INTEGER PRIMARY KEY AUTOINCREMENT, insert_time text,cpu1 float, cpu2 float, cpu3 float, cpu4 float)''')

    # 關閉
    conn.close()


def save_to_db(data):
    '''參數data格式:['00:01',3.5, 5.9, 0.7, 29.6]'''
    # 創建鏈接
    conn = sqlite3.connect(db_name)
    c = conn.cursor()
    
    # 插入數據
    c.execute('INSERT INTO cpu(insert_time,cpu1,cpu2,cpu3,cpu4) VALUES (?,?,?,?,?)', data)
    
    # 提交!!!
    conn.commit()
    
    # 關閉鏈接
    conn.close()

    

# 建立表
create_db()

# 經過循環,對系統進行監控
while True:
    # 獲取系統cpu使用率(每隔1秒)
    cpus = psutil.cpu_percent(interval=1, percpu=True)
    
    # 獲取系統時間(只取分:秒)
    t = time.strftime('%M:%S', time.localtime())
    
    # 保存到數據庫
    save_to_db((t, *cpus))

2、路由器

import sqlite3
from flask import Flask, request, render_template, jsonify

app = Flask(__name__)


def get_db():
    db = sqlite3.connect('mydb.db')
    db.row_factory = sqlite3.Row
    return db


def query_db(query, args=(), one=False):
    db = get_db()
    cur = db.execute(query, args)
    db.commit()
    rv = cur.fetchall()
    db.close()
    return (rv[0] if rv else None) if one else rv


@app.route("/", methods=["GET"])
def index():
    return render_template("index.html")


@app.route("/cpu", methods=["POST"])
def cpu():
    if request.method == "POST":
        res = query_db("SELECT * FROM cpu WHERE id>=(?)", args=(int(request.form['id'])+1,)) #返回1+個數據
    
    return jsonify(insert_time = [x[1] for x in res],
                   cpu1 = [x[2] for x in res],
                   cpu2 = [x[3] for x in res], 
                   cpu3 = [x[4] for x in res],
                   cpu4 = [x[5] for x in res]) # 返回json格式


if __name__ == "__main__":
    app.run(debug=True)

3、頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>ECharts3 Ajax</title>
    <script src="{{ url_for('static', filename='jquery-3.1.1.js') }}"></script>
    <script src="{{ url_for('static', filename='echarts.js') }}"></script>
</head>

<body>
    <!--爲ECharts準備一個具有大小(寬高)的Dom-->
    <div id="main" style="height:500px;border:1px solid #ccc;padding:10px;"></div>
    
    <script type="text/javascript">
    //--- 折柱 ---
    var myChart = echarts.init(document.getElementById('main'));
    
    myChart.setOption({
        title: {
            text: '服務器系統監控'
        },
        tooltip: {},
        legend: {
            data:['cpu1','cpu2','cpu3','cpu4']
        },
        xAxis: {
            data: []
        },
        yAxis: {},
        series: [{
            name: 'cpu1',
            type: 'line',
            data: []
        },{
            name: 'cpu2',
            type: 'line',
            data: []
        },{
            name: 'cpu3',
            type: 'line',
            data: []
        },{
            name: 'cpu4',
            type: 'line',
            data: []
        }]
    });
    
    
    // 六個全局變量:插入時間、cpu一、cpu二、cpu三、cpu四、 哨兵(用於POST)
    var insert_time = ["","","","","","","","","",""],
        cpu1 = [0,0,0,0,0,0,0,0,0,0],
        cpu2 = [0,0,0,0,0,0,0,0,0,0],
        cpu3 = [0,0,0,0,0,0,0,0,0,0],
        cpu4 = [0,0,0,0,0,0,0,0,0,0],
        
        lastID = 0; // 哨兵,記錄上次數據表中的最後id +1(下次查詢只要>=lastID)

    
    //準備好統一的 callback 函數
    var update_mychart = function (data) { //data是json格式的response對象
        
        myChart.hideLoading(); // 隱藏加載動畫
        
        dataLength = data.insert_time.length; //取回的數據長度
        lastID += dataLength; //哨兵,相應增長。
        
        // 切片是能統一的關鍵!!
        insert_time = insert_time.slice(dataLength).concat(data.insert_time); // 數組,先切片、再拼接
        cpu1 = cpu1.slice(dataLength).concat(data.cpu1.map(parseFloat)); //注意map方法
        cpu2 = cpu2.slice(dataLength).concat(data.cpu2.map(parseFloat));
        cpu3 = cpu3.slice(dataLength).concat(data.cpu3.map(parseFloat));
        cpu4 = cpu4.slice(dataLength).concat(data.cpu4.map(parseFloat));
        
        // 填入數據
        myChart.setOption({
            xAxis: {
                data: insert_time
            },
            series: [{
                name: 'cpu1', // 根據名字對應到相應的系列
                data: cpu1
            },{
                name: 'cpu2',
                data: cpu2
            },{
                name: 'cpu3',
                data: cpu3
            },{
                name: 'cpu4',
                data: cpu4
            }]
        });
        
        if (dataLength == 0){clearInterval(timeTicket);} //若是取回的數據長度爲0,中止ajax
    }
    
    myChart.showLoading(); // 首次顯示加載動畫
    
    
    // 異步加載數據 (首次,get,顯示6個數據)
    $.get('/cpu').done(update_mychart);
    
    
    // 異步更新數據 (之後,定時post,取回1個數據)
    var timeTicket = setInterval(function () {
        $.post('/cpu',{id: lastID}).done(update_mychart);
    }, 3000);
    
    </script>
</body>
</html>

效果圖

相關文章
相關標籤/搜索