zoukankan      html  css  js  c++  java
  • Django 配合Echarts绘制图表

    在前面我总结了关于DjangoAdmin的使用技巧,利用DjangoAdmin这个后台管理功能,自己定制页面可以完成非常多的功能,下面我们将重点研究主机图形的绘制,展示和报表等功能的具体实现步骤,这里也算是个人的一点点经验。

    定制查询图形功能

    urls.py

    from django.contrib import admin
    from django.urls import path
    from MyWeb import views
    urlpatterns = [
        path('', admin.site.urls),
        path("grup/",views.grup)
    ]
    

    views.py

    from django.shortcuts import render,HttpResponse
    def grup(request):
        if request.method == "POST":
            StartData = request.POST.get("StartData")
            EndData = request.POST.get("EndData")
            sel = request.POST.get("selec")
            print(StartData,EndData,sel)
    
        return render(request,"grup.html")
    

    grup.html

    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    
    {% block content %}
    
        <form action="/grup/" method="post">
            开始时间: <input type="datetime-local" name="StartData" />
            结束时间: <input type="datetime-local" name="EndData" />
    
        <select name="selec">
          <option value="CPU">CPU负载</option>
          <option value="Mem">内存负载</option>
        </select>
            <input type="submit" value="查询">
        </form>
        <br>
        <div id="main" style=" 90%; height: 300px; border: 1px solid #eecc11; padding: 40px">
        <script src="http://echarts.baidu.com/dist/echarts.min.js"></script>
        <script>
            var mychart = echarts.init(document.getElementById("main"));
            var option = {
                xAxis: {
                    type: 'category',
                    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                },
                yAxis: {
                    type: 'value'
                },
                series: [{
                    data: [820, 932, 901, 934, 1290, 1330, 1320],
                    type: 'line'
                }]
            };
            mychart.setOption(option)
    
        </script>
    
    {% endblock %}
    

    更新数据 为了方便后期内容,批量填充数据.

    import os,sys,sqlite3
    import time,psutil,datetime
    def GetCPU_Load(addr):
        dic = {}
        times = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M")
        cpu = psutil.cpu_percent(interval=None,percpu=True)
        dic["Address"] = addr
        dic["Times"] = times
        dic["load5"] = cpu[0]
        dic["load10"] = cpu[1]
        dic["load15"] = cpu[2]
        return dic
    
    if __name__ == "__main__":
        conn = sqlite3.connect("db.sqlite3")
        cursor = conn.cursor()
        while True:
            dic = GetCPU_Load("192.168.1.1")
            insert = 'insert into MyWeb_cpu(Address,Times,load5,load10,load15) values("{}","{}","{}","{}","{}")'.
                format(dic["Address"],dic["Times"],dic["load5"],dic["load10"],dic["load15"])
            print(insert)
            cursor.execute(insert)
            conn.commit()
            time.sleep(1)
    

    来看下数据库的设计。

    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    {% load static %}
    {% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}
    
    {% block content %}
        <form action="/cpu/" method="post">
            主机地址: <input type="text" name="Address" />
            开始时间: <input type="datetime-local" name="StartData" />
            结束时间: <input type="datetime-local" name="EndData" />
        <select name="selec">
          <option value="CPU">CPU负载</option>
          <option value="Mem">内存负载</option>
        </select>
            <input type="submit" value="查询">
        </form>
    
        {{ time }}
        {{ load }}
    
    from django.shortcuts import render,HttpResponse
    from MyWeb import  models
    import time,datetime
    
    def cpu(request):
        if request.method == "POST":
            times = []
            load = []
            Address = request.POST.get("Address")
            StartData = request.POST.get("StartData")
            EndData = request.POST.get("EndData")
            ret = models.CPU.objects.raw('select * from MyWeb_cpu where Times>="{}" and Times <="{}";'.
                                         format(StartData,EndData))
            for item in ret:
                times.append(item.Times.split("T")[1])
                load.append(item.load5)
            return render(request,"index.html",{"time":times,"load":load})
    

    有个问题,没有解决,可能得用json发数据。

    最后没找到解决方法,应该是要用json序列化一下就好。

    <!--name: index.html-->
    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    {% load static %}
    {% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}
    
    {% block content %}
        <form action="/cpu/" method="post">
            开始时间: <input type="datetime-local" name="StartData" />
            结束时间: <input type="datetime-local" name="EndData" />
        <select name="selec">
          <option value="CPU">CPU Load5 负载</option>
        </select>
            <input type="submit" value="检索图形">
        </form>
    
        <div id="main" style=" 90%; height: 300px; border: 1px solid #eecc11; padding: 40px">
        <script src="http://echarts.baidu.com/dist/echarts.min.js"></script>
        <script>
            var mychart = echarts.init(document.getElementById("main"));
            var option = {
                grid:{
                          top:"50px",
                          left:"50px",
                          right:"15px",
                          bottom:"50px"
                      },
                xAxis: {
                    type: 'category',
                    data: {{ cpu_data }}
                },
                yAxis: {
                    type: 'value'
                },
                series: [{
                    type: 'line',
                    data: {{ cpu_data }}
                }]
            };
            mychart.setOption(option)
        </script>
    {% endblock %}
    

    顺便加上IP查询功能,则更加完整了。

    上方form表单提交后会自动清除表单内容,如果不想清空,可以使用ajax方式提交,或使用一下方法来完成.

    {% block content %}
    
        <form action="/fw/" method="post" target="not_iframe">
            <input type="text" name="user"/>
            <input type="submit" value="提交">
        </form>
    
        <iframe id="id_iframe" name="not_iframe" style="display:none;"></iframe>
    {% endblock %}
    

    本机仪表盘

    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    {% load static %}
    {% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}
    
    {% block content %}
    
        <div id="cpuChart" style=" 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>
    
        <div id="memChart" style=" 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>
    
        <div id="diskChart" style=" 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>
    
        <script src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>
        <script>
            var cpuChart = echarts.init(document.getElementById("cpuChart"));
            var option = {
            series: [
                {
                    type: 'gauge',
                    detail: {formatter: '{value}%'},
                    data: [{value: 44, name: 'CPU 利用率'}]
                }
            ]
        };cpuChart.setOption(option, true);
        </script>
        <script>
            var memChart = echarts.init(document.getElementById("memChart"));
            var option = {
            series: [
                {
                    type: 'gauge',
                    detail: {formatter: '{value}%'},
                    data: [{value: 25, name: '内存利用率'}]
                }
            ]
        };memChart.setOption(option, true);
        </script>
        <script>
            var diskChart = echarts.init(document.getElementById("diskChart"));
            var option = {
            series: [
                {
                    type: 'gauge',
                    detail: {formatter: '{value}%'},
                    data: [{value: 18, name: '磁盘使用量'}]
                }
            ]
        };diskChart.setOption(option, true);
        </script>
    {% endblock %}
    

    增加自定义页面(本机图形监控): 除了默认页面可以使用以外,还可以自己创造一个新页面.

    <!--name: index.html(本机仪表盘)-->
    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    {% load static %}
    {% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}
    
    {% block content %}
        <div id="cpuChart" style=" 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>
        <div id="memChart" style=" 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>
        <div id="diskChart" style=" 32%; height: 380px; border: 1px solid #dddddd; float:left; margin-right: 8px;"></div>
        <script src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>
        <script>
            var cpuChart = echarts.init(document.getElementById("cpuChart"));
            var option = {
            series: [
                {
                    type: 'gauge',
                    detail: {formatter: '{value}%'},
                    data: [{value: 44, name: 'CPU 利用率'}]
                }
            ]
        };cpuChart.setOption(option, true);
        </script>
        <script>
            var memChart = echarts.init(document.getElementById("memChart"));
            var option = {
            series: [
                {
                    type: 'gauge',
                    detail: {formatter: '{value}%'},
                    data: [{value: 25, name: '内存利用率'}]
                }
            ]
        };memChart.setOption(option, true);
        </script>
        <script>
            var diskChart = echarts.init(document.getElementById("diskChart"));
            var option = {
            series: [
                {
                    type: 'gauge',
                    detail: {formatter: '{value}%'},
                    data: [{value: 18, name: '磁盘使用量'}]
                }
            ]
        };diskChart.setOption(option, true);
        </script>
    {% endblock %}
    

    动态监控平台(折线图)

    绘图

        <div id="echo" style=" 100%; height: 400px;  "></div>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script>
    <script src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>
    
        <script type="text/javascript" charset="UTF-8">
            var display = function(time,cpu1,cpu5,cpu15){
      var echo =echarts.init(document.getElementById("echo"));
                    var option = {
                        // tooltip 鼠标放上去之后会自动出现坐标
                        tooltip: {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'cross',
                                label: {
                                    backgroundColor: '#6a7985'
                                }
                            }
                        },// toolbox = 菜单栏中的各种小功能
                        toolbox: {
                            feature: {
                                dataZoom: {
                                    yAxisIndex: 'none'
                                },
                                restore: {},
                                saveAsImage: {}
                            }
                        },
                        legend: {
                            data: [ '1分钟负载', '5分钟负载', '15分钟负载']
                        },
    
                        xAxis: {
                            type: 'category',
                            data: time
                        },
                        yAxis: {
                            type: 'value'
                        },
                        series: [
                        {
                            name: "1分钟负载",
                            stack: "总量",
                            data: cpu1,
                            type: 'line'
                        },
                        {
                            name: "5分钟负载",
                            stack: "总量",
                            data: cpu5,
                            type: 'line'
                        },
                        {
                            name: "15分钟负载",
                            stack: "总量",
                            data: cpu15,
                            type: 'line'
                        }
                        ]
                    };
                    echo.setOption(option,true);
        };
    </script>
    

    另一种刷新式绘图

    <script type="text/javascript" src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>
    <div id="main" style="height:500px;1200px;border:1px solid #eecc11;padding:10px;"></div>
    <script type="text/javascript" charset="UTF-8">
            var display = function(time,cpu){
                // 负责初始化绘图画布
                var myChart = echarts.init(document.getElementById('main'));
                myChart.setOption({
            title: {
                text: '监控系统CPU资源'
            },
            tooltip: {},
            xAxis: {
                data: []
            },
            yAxis: {},
            series: [{
                name: 'cpu',
                type: 'line',
                data: []
            }]
        });
            // 下方就是给指定字段填充数据
            myChart.setOption({
                xAxis: {
                    data: time
                },
                series: [{
                    name: 'cpu', // 根据名字对应到相应的系列
                    data: cpu
                }]
            });
        };
        // 首次显示加载动画
        myChart.showLoading();
    </script>
    

    数据处理

        // 负责对参数的解析
        var time =["","","","","","","","","",""];
        var cpu1 = [0,0,0,0,0,0,0,0,0,0];
        var cpu5 = [0,0,0,0,0,0,0,0,0,0];
        var cpu15 = [0,0,0,0,0,0,0,0,0,0];
        var update = function(recv){
            time.push(recv.response[0]);
            cpu1.push(parseFloat(recv.response[1]));
            cpu5.push(parseFloat(recv.response[2]));
            cpu15.push(parseFloat(recv.response[3]));
            if(time.length >=10){
                time.shift();
                cpu1.shift();
                cpu5.shift();
                cpu15.shift();
                display(time,cpu1,cpu5,cpu15)
            }
        };
    

    图形更新

        $(
            function () {
                fetchData();
                setInterval(fetchData, 1000);
            }
        );
        function fetchData(){
            $.ajax({
                url:"/_ajax/",
                type:"GET",
                dataType: 'json',
                success:function (recv) {
                    update(recv);
                }
            })
        }
    

    view.py

    from django.shortcuts import render,HttpResponse
    import os,subprocess,time,json
    
    def index(request):
        return render(request,"index.html")
    
    def ajax(request):
        if request.method == "GET":
            data = []
            data.append(time.strftime("%M:%S", time.localtime()))
            for key in ["system.cpu.util[,,avg1]", "system.cpu.util[,,avg5]", "system.cpu.util[,,avg15]"]:
                cmd = "C:/get.exe -s {} -p {} -k {}".format("192.168.1.20", "10050", key)
                proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
                data.append(float(proc.stdout.readlines()[0].split()[0]))
            return HttpResponse(json.dumps({"response":data}))
    

    urls.py

    from django.contrib import admin
    from django.urls import path
    from MyWeb import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path("cpu/",views.index),
        path("_ajax/",views.ajax)
    ]
    

    可能效果不是很明显,你可以稍微改一下代码。

    def ajax(request):
        if request.method == "GET":
            data = []
            data.append(time.strftime("%M:%S", time.localtime()))
            data.append(random.randint(1,100))
            data.append(random.randint(100, 200))
            data.append(random.randint(23, 90))
            return HttpResponse(json.dumps({"response":data}))
    
        // 负责对参数的解析
        var time =["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""];
        var cpu1 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
        var cpu5 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
        var cpu15 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
        var update = function(recv){
            time.push(recv.response[0]);
            cpu1.push(parseFloat(recv.response[1]));
            cpu5.push(parseFloat(recv.response[2]));
            cpu15.push(parseFloat(recv.response[3]));
            if(time.length >=40){
                time.shift();
                cpu1.shift();
                cpu5.shift();
                cpu15.shift();
                display(time,cpu1,cpu5,cpu15)
            }
        };
    

    除了可以监控系统负载外,还可以监控网卡,监控内存等,原理都是一样的,网卡监控代码。

    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    {% load static %}
    {% block content %}
    <div id="main" style=" 100%; height: 400px;"></div>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script type="text/javascript" src="https://cdn.bootcss.com/echarts/4.6.0/echarts.min.js"></script>
    <script type="text/javascript" charset="UTF-8">
        var display = function(){
            var main =echarts.init(document.getElementById("main"));
            var option = {
                // tooltip 鼠标放上去之后会自动出现坐标
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'cross',
                        label: {
                            backgroundColor: '#6a7985'
                        }
                    }
                },// toolbox = 菜单栏中的各种小功能
                toolbox: {
                    feature: {
                        dataZoom: {
                            yAxisIndex: 'none'
                        },
                        restore: {},
                        saveAsImage: {}
                    }
                },
                legend: {
                    data: [ '网卡入口流量', '网卡出口流量']
                },
                // 负责绘图的配置
                xAxis: {
                    type: 'category',
                    data: [1,2,3,4,5,1,2,3,4,5]
                },
                yAxis: {
                    type: 'value'
                },
                series: [
                {
                    name: "网卡入口流量",
                    stack: "总量",
                    data: [1,2,3,4,5,1,2,3,4,5],
                    type: 'line',
                    areaStyle: {}
                },
                {
                    name: "网卡出口流量",
                    stack: "总量",
                    data: [1,2,3,4,5,1,2,3,4,5],
                    type: 'line',
                    areaStyle: {}
                }
                ]
            };
            main.setOption(option,true);
        };
        display()
    </script>
    {% endblock %}
    

    网站流量统计(折线图)

    通过分析日志统计流量。

    import os,sys
    
    def log(path):
        key = []
        value = []
        for item in fp.readlines():
            date = item.split()[3]
            HourData = date.split(":")[1] + ":" + date.split(":")[2]
            if item.split()[9] != "-" and item.split()[9] != '"-"':
                SendByte = int(item.split()[9])
        key.append(HourData)
        value.append(SendByte)
        return dict(zip(key,value))
    
    fp = open("c://access.log","r")
    dic = log(fp)
    

    针对Web服务的流量统计 上面代码只能统计出所有的流量,无法叠加,可以以IP为例进行流量叠加。

    import os,sys
    
    def Count_IP_And_Flow(file):
        addr = {}  # key 保存当前的IP信息
        flow = {}  # value 保存当前IP流量总和
        Count= 0   # 针对IP地址的计数器
        with open(file) as f:
            contexts = f.readlines()
        for line in contexts:
            if line.split()[9] != "-" and line.split()[9] != '"-"':
                size = line.split()[9]
            ip_attr = line.split()[0]
            Count = int(size) + Count
            if ip_attr in addr.keys():
                addr[ip_attr] = addr[ip_attr] + 1
                flow[ip_attr] = flow[ip_attr] + int(size)
            else:
                addr[ip_attr] = 1
                flow[ip_attr] = int(size)
        return addr,flow
    
    if __name__ == "__main__":
        Address,OutFlow = Count_IP_And_Flow("c://access.log")
        print("地址计数:{}  ---> 流量计数:{}".format(Address,OutFlow))
    

    上面的代码,稍微修改一下就能统计时间与流量的关系。

    def Count_IP_And_Flow(file):
        addr = {}  # key 保存当前的IP信息
        flow = {}  # value 保存当前IP流量总和
        Count= 0   # 针对IP地址的计数器
        with open(file) as f:
            contexts = f.readlines()
        for line in contexts:
            if line.split()[9] != "-" and line.split()[9] != '"-"':
                size = line.split()[9]
            temp = line.split()[3]
            ip_attr = temp.split(":")[1] + ":" + temp.split(":")[2]
            Count = int(size) + Count
            if ip_attr in addr.keys():
                addr[ip_attr] = addr[ip_attr] + 1
                flow[ip_attr] = flow[ip_attr] + int(size)
            else:
                addr[ip_attr] = 1
                flow[ip_attr] = int(size)
        return addr,flow
    
    if __name__ == "__main__":
        Address,OutFlow = Count_IP_And_Flow("c://access.log")
        print("流量计数:{}".format(Address,OutFlow))
    

    接着是绘图,这里直接把代码拿出来吧。

    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    {% load static %}
    {% block content %}
    <link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
    <div class="panel panel-primary" style=" 100%;height: 30%; float: left">
        <div class="panel-heading">
            <h3 class="panel-title">网站流量统计</h3>
        </div>
        <div class="panel-body">
            <div id="main" style="100%; height: 400px"></div>
        </div>
    </div>
    <script src="https://www.blib.cn/cdn/echarts.js" type="text/javascript"></script>
    <script src="https://www.blib.cn/cdn/jquery.js" type="text/javascript"></script>
    <script type="text/javascript" charset="UTF-8">
            var kv = new Array();
            var keys = new Array();
            var values = new Array();
            kv = {{ data | safe }};
            for(var logkey in kv){
                keys.push(logkey);
                values.push(kv[logkey]);
            }
    
            var display = function() {
                var main = echarts.init(document.getElementById("main"));
                var option = {
                    xAxis: {
                        type: 'category',
                        boundaryGap: false,
                        data: keys
                    },
                    yAxis: {
                        type: 'value'
                    },
                    series: [{
                        data: values,
                        type: 'line',
                        areaStyle: {},
                    }]
                };
                main.setOption(option,true);
            };
        display();
    </script>
    {% endblock %}
    
    from django.shortcuts import render
    import json
    
    def Count_IP_And_Flow(file):
        addr = {}  # key 保存当前的IP信息
        flow = {}  # value 保存当前IP流量总和
        Count= 0   # 针对IP地址的计数器
        with open(file) as f:
            contexts = f.readlines()
        for line in contexts:
            if line.split()[9] != "-" and line.split()[9] != '"-"':
                size = line.split()[9]
            temp = line.split()[3]
            ip_attr = temp.split(":")[1] + ":" + temp.split(":")[2]
            Count = int(size) + Count
            if ip_attr in addr.keys():
                flow[ip_attr] = flow[ip_attr] + int(size)
            else:
                addr[ip_attr] = 1
                flow[ip_attr] = int(size)
        return flow
    
    def index(request):
        OutFlow = Count_IP_And_Flow("c://access.log")
        print(OutFlow)
        return render(request,"index.html",{"data":json.dumps(OutFlow)})
    

    效果图如下,我这台机器访问量很小,将就着看吧。

    统计IP出现的次数。

    def IP_Count(file):
        ip = {}
        with open(file) as f:
            for i in f.readlines():
                ip_attr = i.strip().split()[0]
                if ip_attr in ip.keys():
                    ip[ip_attr] = ip[ip_attr] + 1
                else:
                    ip[ip_attr] = 1
        print(ip)
    
    IP_Count("c://access.log")
    

    网站状态码统计(饼状图)

    饼状图的绘制: 统计目标主机网页状态码,与个数,并绘制饼状图,饼图和其他图不太一样,绘制起来蛮烦一些。

    from django.shortcuts import render
    import json
    
    def Count_Flag_And_Flow(file):
        list = []
        flag = {}
        with open(file) as f:
            contexts = f.readlines()
        for line in contexts:
            it = line.split()[8]
            list.append(it)
        list_num = set(list)
        for item in list_num:
            num = list.count(item)
            flag[item] = num
        return flag
    
    def index(request):
        Address = Count_Flag_And_Flow("c://access.log")
        print(Address)
        return render(request,"index.html",{"data":json.dumps(Address)})
    
    from MyWeb import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path("log/",views.index)
    ]
    
    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    {% load static %}
    
    {% block content %}
    <div id="main" style="50%; height: 300px"></div>
    <script src="https://www.blib.cn/cdn/echarts.js" type="text/javascript"></script>
    <script src="https://www.blib.cn/cdn/jquery.js" type="text/javascript"></script>
        <script type="text/javascript" charset="UTF-8">
            var kv = new Array();
            kv = {{ data | safe }}
            var test = new Array();
            for(var logkey in kv){
                test.push( {value:kv[logkey], name:logkey} )
            }
    
            var display = function(){
                var main = echarts.init(document.getElementById("main"));
                var option = {
                    legend: {
                        orient: 'vertical',
                        left: 'left',
                    },
                    series: [
                        {
                            type: 'pie',
                            radius: '70%',
                            center: ['50%', '50%'],
                            detail: {formatter:'{value}'},
                            data: test
                        }
                    ]
                };
                main.setOption(option,true);
            };
            display();
        </script>
    {% endblock %}
    

    加上框架看效果。

    	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
        <div class="panel panel-primary" style=" 60%;height: 50%">
    	<div class="panel-heading">
    		<h3 class="panel-title">网站访问状态统计</h3>
    	</div>
    	<div class="panel-body">
    		这是一个基本的面板
    	</div>
    </div>
    

    来,搞事

    <link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
    <div class="panel panel-primary" style=" 40%;height: 30%">
        <div class="panel-heading">
            <h3 class="panel-title">网站访问状态统计</h3>
        </div>
        <div class="panel-body">
            <div id="main" style="100%; height: 300px"></div>
        </div>
    </div>
    

    网站访问设备统计(柱状图)

    统计设备的类型,例如Windows linux 等,这里我们接着上面的做吧,先来改布局。

    {% block content %}
    
    <link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
    <div class="panel panel-primary" style=" 40%;height: 30%;float: left">
        <div class="panel-heading">
            <h3 class="panel-title">网站访问状态统计</h3>
        </div>
        <div class="panel-body">
            <div id="main" style="100%; height: 300px"></div>
        </div>
    </div>
    <div class="panel panel-primary" style=" 58%;height: 30%; float: right">
        <div class="panel-heading">
            <h3 class="panel-title">网站设备类型统计</h3>
        </div>
        <div class="panel-body">
            <div id="main1" style="100%; height: 300px"></div>
        </div>
    </div>
    

    完整代码如下,就是拼接起来就行,没什么技术含量。

    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    {% load static %}
    
    {% block content %}
    <link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
    <div class="panel panel-primary" style=" 40%;height: 30%;float: left">
        <div class="panel-heading">
            <h3 class="panel-title">网站访问状态统计</h3>
        </div>
        <div class="panel-body">
            <div id="main" style="100%; height: 300px"></div>
        </div>
    </div>
    <div class="panel panel-primary" style=" 58%;height: 30%; float: right">
        <div class="panel-heading">
            <h3 class="panel-title">网站设备类型统计</h3>
        </div>
        <div class="panel-body">
            <div id="main1" style="100%; height: 300px"></div>
        </div>
    </div>
    
    <script src="https://www.blib.cn/cdn/echarts.js" type="text/javascript"></script>
    <script src="https://www.blib.cn/cdn/jquery.js" type="text/javascript"></script>
        <script type="text/javascript" charset="UTF-8">
            var kv = new Array();
            kv = {{ data | safe }}
            var test = new Array();
            for(var logkey in kv){
                test.push( {value:kv[logkey], name:logkey} )
            }
            var display = function(){
                var main = echarts.init(document.getElementById("main"));
                var option = {
                    legend: {
                        orient: 'vertical',
                        left: 'left',
                    },
                    series: [
                        {
                            type: 'pie',
                            radius: '70%',
                            center: ['50%', '50%'],
                            detail: {formatter:'{value}'},
                            data: test
                        }
                    ]
                };
                main.setOption(option,true);
            };
            display();
        </script>
    
    <script type="text/javascript" charset="UTF-8">
            var display = function() {
                var main1 = echarts.init(document.getElementById("main1"));
                var option = {
                    xAxis: {
                        type: 'category',
                        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                    },
                    yAxis: {
                        type: 'value'
                    },
                    series: [{
                        data: [120, 200, 150, 80, 70, 110, 130],
                        type: 'bar'
                    }]
                };
                main1.setOption(option,true);
            };
    display();
    </script>
    {% endblock %}
    

    import os,sys
    
    def Count_Flag_And_Type(file):
        list = []
        flag = {}
        with open(file) as f:
            contexts = f.readlines()
        for line in contexts:
            list.append( line.split()[12].replace("(",""))
        list_num = set(list)
        for item in list_num:
            num = list.count(item)
            flag[item] = num
        return flag
    
    if __name__ == "__main__":
        a = Count_Flag_And_Type("c://access.log")
        print(a)
    

    最终代码如下,前端第二个拼接位置需要注意。

    {% extends "admin/base_site.html" %}
    {% load i18n static %}
    {% load static %}
    
    {% block content %}
    
    <link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css">
    <div class="panel panel-primary" style=" 40%;height: 30%;float: left">
        <div class="panel-heading">
            <h3 class="panel-title">网站访问状态统计</h3>
        </div>
        <div class="panel-body">
            <div id="main" style="100%; height: 300px"></div>
        </div>
    </div>
    <div class="panel panel-primary" style=" 58%;height: 30%; float: right">
        <div class="panel-heading">
            <h3 class="panel-title">网站设备类型统计</h3>
        </div>
        <div class="panel-body">
            <div id="main1" style="100%; height: 300px"></div>
        </div>
    </div>
    
    <script src="https://www.blib.cn/cdn/echarts.js" type="text/javascript"></script>
    <script src="https://www.blib.cn/cdn/jquery.js" type="text/javascript"></script>
        <script type="text/javascript" charset="UTF-8">
            var kv = new Array();
            kv = {{ data | safe }}
            var test = new Array();
            for(var logkey in kv){
                test.push( {value:kv[logkey], name:logkey} )
            }
            var display = function(){
                var main = echarts.init(document.getElementById("main"));
                var option = {
                    legend: {
                        orient: 'vertical',
                        left: 'left',
                    },
                    series: [
                        {
                            type: 'pie',
                            radius: '70%',
                            center: ['50%', '50%'],
                            detail: {formatter:'{value}'},
                            data: test
                        }
                    ]
                };
                main.setOption(option,true);
            };
            display();
        </script>
    
    <script type="text/javascript" charset="UTF-8">
            var kv = new Array();
            kv = {{ data1 | safe }}
            var keys = new Array();
            var values = new Array();
            for(var logkey in kv){
                keys.push(logkey);
                values.push(kv[logkey]);
            }
            console.log(keys,values);
    
            var display = function() {
                var main1 = echarts.init(document.getElementById("main1"));
                var option = {
                    xAxis: {
                        type: 'category',
                        data: keys
                    },
                    yAxis: {
                        type: 'value'
                    },
                    series: [{
                        data: values,
                        type: 'bar'
                    }]
                };
                main1.setOption(option,true);
            };
    display();
    </script>
    {% endblock %}
    

    后端处理日志并返回结果。

    from django.shortcuts import render
    import json
    
    def Count_Flag_And_Flow(file):
        list = []
        flag = {}
        with open(file) as f:
            contexts = f.readlines()
        for line in contexts:
            it = line.split()[8]
            list.append(it)
        list_num = set(list)
        for item in list_num:
            num = list.count(item)
            flag[item] = num
        return flag
    
    def Count_Flag_And_Type(file):
        list = []
        flag = {}
        with open(file) as f:
            contexts = f.readlines()
        for line in contexts:
            list.append( line.split()[12].replace("(",""))
        list_num = set(list)
        for item in list_num:
            num = list.count(item)
            flag[item] = num
        return flag
    
    def index(request):
        Address = Count_Flag_And_Flow("c://access.log")
        print(Address)
        Types = Count_Flag_And_Type("c://access.log")
        print(Types)
        return render(request,"index.html",{"data":json.dumps(Address),"data1":json.dumps(Types)})
    
    def mob(request):
        return render(request,"mob.html")
    

    经过测试上面的代码有一定的局限性,比如下面的这两条代码,会出现异常。

    ::1 - - [15/Jan/2020:04:43:40 -0500] "OPTIONS * "
    192.168.1.2 - - [15/Jan/2020:04:37:09 -0500] "-" 408 - "-" "-"

    日志统计时,应该避免出现这种无效行,该怎么做,我就不说了,正则!!

    单位时间访客(访客位置)

    未完待续。。。

    先来几个API查询地址。

    http://ip.ws.126.net/ipquery?ip=192.168.1.100

    import os,sys
    import urllib.request
    
    def counts(file):
        Addr = []
        with open(file) as f:
            contexts = f.readlines()
        for line in contexts:
            lt = line.split()[0]
            if lt !="::1" and lt !="127.0.0.1":
                Addr.append(lt)
        return set(Addr)
    
    if __name__ == "__main__":
        ret = counts("C://access.log")
        for item in ret:
            url = "http://ip.ws.126.net/ipquery?ip={}".format(item)
            ret = urllib.request.urlopen(url)
            print(ret.read().decode('gbk'))
    

    if __name__ == "__main__":
        ret = counts("C://access.log")
        for item in ret:
            url = "http://ip.ws.126.net/ipquery?ip={}".format(item)
            ret = urllib.request.urlopen(url).read().decode('gbk')
            City = ret.split()[5].replace('province:"', '').replace('"}', "")
            print("IP:{} -----> 城市:{}".format(item,City))
    

  • 相关阅读:
    request和response使用
    oracle_to_char
    oracl_LTRIM_RITRIM
    convert
    jdbc
    oracle_trunc
    [python]glob模块中的glob()函数为什么返回空列表??
    win10 anaconda+tensorflow+keras
    Golang学习:sublime text3配置golang环境
    2018/12/05学习笔记
  • 原文地址:https://www.cnblogs.com/LyShark/p/12200823.html
Copyright © 2011-2022 走看看