zoukankan      html  css  js  c++  java
  • [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

    多台主机监控参考

  • 相关阅读:
    工欲性能调优,必先利其器(2)- 火焰图
    工欲性能调优,必先利其器(1)
    关于烂代码的那些事(上)
    HTTP 返回码中 301 与 302 的区别
    HTTP 状态码 301 和 302 详解及区别——辛酸的探索之路
    HTTP 状态码之:301、302 重定向
    记一次获得 3 倍性能的 go 程序优化实践,及 on-cpu / off-cpu 火焰图的使用
    Coloring Flame Graphs: Code Hues
    StackOverflow 创始人关于如何高效编程的清单
    Spring Bean的生命周期(非常详细)
  • 原文地址:https://www.cnblogs.com/iiiiiher/p/8353501.html
Copyright © 2011-2022 走看看