[py]flask动态展示主机内存图

echarts基础

需要借助这个图来绘制,动态内存图.

绘制步骤

  • 写py脚本来入库日志
  • 选取合适的echart,并观察图所需的数据格式
  • 用flask返回这个静态的echarts
  • 用flask写接口返回echarts所需格式的日志
  • 修改echarts,用jq请求方式填充真实数据

查看echarts教程


#### 这是最基础的echarts代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ECharts</title>
    <!-- 引入 echarts.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.0.2/echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style=" 600px;height:400px;"></div>
<script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'));
    
    //其他的js填充在这里即可

    myChart.setOption(option);
</script>
</body>
</html>

其他的js填充在这里即可

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ECharts</title>
    <!-- 引入 echarts.js -->
    <script src="echarts.min.js"></script>
</head>
<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style=" 600px;height:400px;"></div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));

        // 指定图表的配置项和数据
        var option = {
            title: {
                text: 'ECharts 入门示例'
            },
            tooltip: {},
            legend: {
                data:['销量']
            },
            xAxis: {
                data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
            },
            yAxis: {},
            series: [{
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        };

        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
    </script>
</body>
</html>

flask将选定的图展示出去

- app.py

# -*- coding:utf-8 -*-
from flask import Flask, render_template

con = mysql.connect(user="root", passwd="123456", db="mem", host="192.168.2.22")
con.autocommit(True)
cur = con.cursor()

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')
    
if __name__ == '__main__':
    app.run(debug=True)


- index.html


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ECharts</title>
    <!-- 引入 echarts.js -->
    <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.0.2/echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style=" 600px;height:400px;"></div>
<script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'));

    function randomData() {
        now = new Date(+now + oneDay);
        value = value + Math.random() * 21 - 10;
        return {
            name: now.toString(),
            value: [
                [now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'),
                Math.round(value)
            ]
        }
    }

    var data = [];
    var now = +new Date(1997, 9, 3);
    var oneDay = 24 * 3600 * 1000;
    var value = Math.random() * 1000;
    for (var i = 0; i < 100; i++) {
        data.push(randomData());
    }
    console.log(data);
    option = {
        title: {
            text: '动态数据 + 时间坐标轴'
        },
        tooltip: {
            trigger: 'axis',
            formatter: function (params) {
                params = params[0];
                var date = new Date(params.name);
                return date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear() + ' : ' + params.value[1];
            },
            axisPointer: {
                animation: false
            }
        },
        xAxis: {
            type: 'time',
            splitLine: {
                show: false
            }
        },
        yAxis: {
            type: 'value',
            boundaryGap: [0, '100%'],
            splitLine: {
                show: false
            }
        },
        series: [{
            name: '模拟数据',
            type: 'line',
            showSymbol: false,
            hoverAnimation: false,
            data: data
        }]
    };

    setInterval(function () {

        for (var i = 0; i < 5; i++) {
            data.shift();
            data.push(randomData());
        }

        myChart.setOption({
            series: [{
                data: data
            }]
        });
    }, 1000);

    myChart.setOption(option);
</script>
</body>
</html>

入库数据

这里主要是内存和时间

#!/usr/bin/env python
# coding=utf-8

## 1, 获取内存  2,入库
import pymysql
from time import time, sleep
import psutil

con = pymysql.connect(host='127.0.0.1', user='root', passwd='123456', db='mem')
con.autocommit(True)
cur = con.cursor()


def get_mem():
    free = psutil.virtual_memory().free / 1024 / 1024
    sql = "insert into mem_used VALUES(%s,%s)" % (free, int(time()))
    cur.execute(sql)


while True:
    get_mem()
    sleep(1)

观察echarts所需的数据

flask获取数据重组,然后返回

@app.route('/getdata')
def getdata():
    sql = 'select * from mem_used'
    cur.execute(sql)
    arr = []
    for i in cur.fetchall():
        arr.append({'name': i[1], 'value': [i[1], i[0]]})
    return json.dumps(arr)

修改js使用ajax动态请求api

$.getJSON('/getdata', function (res) {
    
});




    var myChart = echarts.init(document.getElementById('main'));

    function randomData() {
        now = new Date(+now + oneDay);
        value = value + Math.random() * 21 - 10;
        return {
            name: now.toString(),
            value: [
                [now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'),
                Math.round(value)
            ]
        }
    }

    var data = [];
    var now = +new Date(1997, 9, 3);
    var oneDay = 24 * 3600 * 1000;
    var value = Math.random() * 1000;
    for (var i = 0; i < 100; i++) {
        data.push(randomData());
    }
    console.log(data);
    option = {
        title: {
            text: '动态数据 + 时间坐标轴'
        },
        tooltip: {
            trigger: 'axis',
            formatter: function (params) {
                params = params[0];
                var date = new Date(params.name);
                return date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear() + ' : ' + params.value[1];
            },
            axisPointer: {
                animation: false
            }
        },
        xAxis: {
            type: 'time',
            splitLine: {
                show: false
            }
        },
        yAxis: {
            type: 'value',
            boundaryGap: [0, '100%'],
            splitLine: {
                show: false
            }
        },
        series: [{
            name: '模拟数据',
            type: 'line',
            showSymbol: false,
            hoverAnimation: false,
            data: data
        }]
    };

    setInterval(function () {

        for (var i = 0; i < 5; i++) {
            data.shift();
            data.push(randomData());
        }

        myChart.setOption({
            series: [{
                data: data
            }]
        });
    }, 1000);

    myChart.setOption(option);

搞进去后前端访问应该就是真实数据了, 不过现在还不能随着时间自动推动.

自动推动思路: 第一次获取,或者刷新,获取所有数据.

select * from mem_used

如果不动的化,动态请求数据,应该传一个时间戳,获取增量数据

select * from mem_used where time > 1516889313

修改js动态获取数据部分

- 默认js动态填充数据部分
    function randomData() {
        now = new Date(+now + oneDay);
        value = value + Math.random() * 21 - 10;
        return {
            name: now.toString(),
            value: [
                [now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'),
                Math.round(value)
            ]
        }
    }

    var data = [];
    var now = +new Date(1997, 9, 3);
    var oneDay = 24 * 3600 * 1000;
    var value = Math.random() * 1000;
    for (var i = 0; i < 100; i++) {
        data.push(randomData());
    }
    console.log(data);

- 修改如下

        setInterval(function (new_res) {
            $.getJSON('/getdata?lasttime=' + last_time, function (new_res) {
                $.each(new_res.data, function (i, v) {
                    data.push(v);
                });
                myChart.setOption({
                    series: [{
                        data: data
                    }]
                });
            });
        }, 1000);

        myChart.setOption(option);


即每次请求时候外加时间戳, /getdata?lasttime=

完成设置后,可见可以自动发带时间戳的请求了

获取前端

获取前端传来的时间lasttime, 加在sql里查询出结果后返回.
这里重组下数据, 顺便将最终时间返回.即arr[-1]['name']

@app.route('/getdata')
def getdata():
    lasttime = request.args.get('lasttime')
    sql = 'select * from mem_used'
    if lasttime:
        sql += ' where time > %s' % (lasttime)
    print(sql)
    cur.execute(sql)
    arr = []
    for i in cur.fetchall():
        arr.append({'name': i[1], 'value': [i[1], i[0]]})
    all_res = {'data': arr}
    all_res['max_time'] = arr[-1]['name']
    return json.dumps(all_res)

修改前端-完整如下

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ECharts</title>
    <!-- 引入 echarts.js -->
    <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.0.2/echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style=" 600px;height:400px;"></div>
<script type="text/javascript">
    var last_time;
    // 基于准备好的dom,初始化echarts实例
    $.getJSON('/getdata', function (res) {
        var myChart = echarts.init(document.getElementById('main'));
        var data = res.data;
        last_time = res.max_time;
        option = {
            title: {
                text: '动态数据 + 时间坐标轴'
            },
            tooltip: {
                trigger: 'axis',
                formatter: function (params) {
                    params = params[0];
                    var date = new Date(params.name);
                    return date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear() + ' : ' + params.value[1];
                },
                axisPointer: {
                    animation: false
                }
            },
            xAxis: {
                type: 'time',
                splitLine: {
                    show: false
                }
            },
            yAxis: {
                type: 'value',
                boundaryGap: [0, '100%'],
                splitLine: {
                    show: false
                }
            },
            series: [{
                name: '模拟数据',
                type: 'line',
                showSymbol: false,
                hoverAnimation: false,
                data: data
            }]
        };

        setInterval(function (new_res) {
            $.getJSON('/getdata?lasttime=' + last_time, function (new_res) {
                $.each(new_res.data, function (i, v) {
                    data.push(v);
                });
                myChart.setOption({
                    series: [{
                        data: data
                    }]
                });
            });
        }, 1000);
        myChart.setOption(option);
    });
</script>
</body>
</html>



定义全局变量lasttime, 从后端获取到的.
然后遍历.

最终展示效果

源码code

多台主机监控参考

原文地址:https://www.cnblogs.com/iiiiiher/p/8353501.html