Django 配合Echarts绘制图表

Django 配合Echarts绘制图表,第1张

在前面我总结了关于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 %}

    
    
{% 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 %}
    

    {{ 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序列化一下就好。


{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}

{% block content %}
    

    
    
    
{% endblock %}

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

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

{% block content %}

    

    
{% endblock %}
本机仪表盘
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}

{% block content %}

    

    

    

    
    
    
    
{% endblock %}

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


{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}

{% block content %}
    
    
    
    
    
    
    
{% endblock %}

动态监控平台(折线图)

绘图





    

另一种刷新式绘图



数据处理

// 负责对参数的解析
    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 %}




{% 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 %}


    
        网站流量统计
    
    
        
    




{% 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 %}



    
{% endblock %}

加上框架看效果。


    
	
		网站访问状态统计
	
	
		这是一个基本的面板
	

来,搞事



    
        网站访问状态统计
    
    
        
    

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

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

{% block content %}



    
        网站访问状态统计
    
    
        
    


    
        网站设备类型统计
    
    
        
    

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

{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}

{% block content %}


    
        网站访问状态统计
    
    
        
    


    
        网站设备类型统计
    
    
        
    




    


{% 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 %}



    
        网站访问状态统计
    
    
        
    


    
        网站设备类型统计
    
    
        
    




    


{% 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))

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1320580.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-11
下一篇 2022-06-11

发表评论

登录后才能评论

评论列表(0条)

保存