Ai
3 Star 3 Fork 1

朱启玉/django_monitor

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
views.py 43.44 KB
一键复制 编辑 原始数据 按行查看 历史
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render, redirect
from .models import (UserInfo, Salt, UserGroup, Asset, HostGroup,
Templates, Triggers, RuleIndex, RuleResult,
CustomMonitor)
# create pdf
from reportlab.graphics.charts.lineplots import LinePlot
from reportlab.graphics.shapes import *
from reportlab.graphics.charts.textlabels import Label
from reportlab.graphics import renderPDF
# Create your views here.
from .forms import RegisterForm, AssetListForm, RuleIndexForm
from django.http.response import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from .Authcode import authCode
import logging
import json
import os
import time
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import telnetlib
import hashlib
import re
import traceback
def login(request):
""" 登录函数
结果: 跳转到assetlist
"""
result = ''
if request.session.get('username', None):
user = request.session.get('name', None)
return render(request, 'login2.html', {'user': user})
if request.method == 'POST':
user = request.POST.get('username', None)
pwd = request.POST.get('password', None).encode("utf-8")
# pwd_md5 = request.POST.get('', None)
auth_code = request.POST.get('auth_code_client', None)
all_message = all([user, pwd, auth_code])
print(all_message)
if not all_message:
result = '用户名/密码不能为空'
return render(request, 'login.html', {'status': result})
elif auth_code == request.session["verify_code"]:
try:
salt = UserInfo.objects.get(name=user).salt.value
except Exception as e:
print("用户名/密码错误", e)
result = '用户名/密码错误'
return render(request, 'login.html', {'status': result})
# 判断客户端是否加盐
if len(pwd) != 32:
pwd = hashlib.md5(pwd).hexdigest().encode("utf-8")
salt_password = salt + pwd
pwd = hashlib.md5(salt_password).hexdigest()
if UserInfo.objects.filter(name=user, password=pwd).count() >= 1:
# 区分超级管理员和管理员
admin_level = UserInfo.objects.get(name=user).user_type
if admin_level == 1:
request.session['username'] = "superadmin"
request.session.set_expiry(6000)
else:
request.session['username'] = "admin"
request.session.set_expiry(6000)
request.session["name"] = user
return redirect('/ad/assetlist')
# return HttpResponse('登录成功')
else:
result = '用户名/密码错误'
return render(request, 'login.html', {'status': result})
else:
result = '验证码错误'
return render(request, 'login.html', {'code_status': result})
else:
return render(request, 'login.html', {'status': result})
def ad_exit(request):
# 登出
"""
:return: sign out
"""
request.session["username"] = None
return redirect("/ad/login/")
auth_code_color = None
def auth(request):
""" 验证码函数 ,authCode类来自Authcode.py
@:return
auth_code_img, 二进制图片
"""
auth_code = authCode()
auth_code_img = auth_code.gene_code()
auth_code_text = auth_code.text
global auth_code_color
auth_code_color = auth_code.create_color()
# cache.set("verify_code", auth_code_text,60) # auth_code_text
request.session["verify_code"] = auth_code_text
return HttpResponse(auth_code_img, 'image/png')
def auth2(request):
time.sleep(0.01)
global auth_code_color
return HttpResponse(auth_code_color, 'image/png')
def pdf(request):
drawing = Drawing(400, 200)
data = [(2010, 5, 5, 10, 1), (2014, 3, 15, 20, 11), (2017, 6, 25, 30, 21)]
pred = [row[2] for row in data]
high = [row[3] for row in data]
low = [row[4] for row in data]
times = [row[0] + row[1] / 12 for row in data]
# 创建多线条
lp = LinePlot()
lp.x = 50
lp.y = 50
lp.height = 125
lp.width = 300
lp.data = [
list(zip(times, pred)),
list(zip(times, high)),
list(zip(times, low))
]
lp.lines[0].strokeColor = colors.blue
lp.lines[1].strokeColor = colors.red
lp.lines[2].strokeColor = colors.green
# 加线条
drawing.add(lp)
# 加文字说明
# drawing.add(String(250, 150, "Sunspots", fontsize=14, fillColor=colors.red))
pdf2 = renderPDF.drawToString(drawing, "Sunspots")
return HttpResponse(pdf2, 'application/pdf')
def Register(request):
""" 注册函数 """
result = ''
registerForm = RegisterForm()
if request.method == 'POST':
form = RegisterForm(request.POST)
# print form
if form.is_valid():
# data = form.clean()
name = request.POST.get("name", None)
password = request.POST.get("password", None).encode("utf-8")
email = request.POST.get("email", None)
memo = request.POST.get("memo", None)
user_type = request.POST.get("user_type", None)
print(name, password, email, memo, user_type)
if UserInfo.objects.filter(name=name).count():
result = '用户名已存在'
return render(request, 'register.html',
{'form': registerForm, 'status': result})
else:
try:
# 加盐
salt = os.urandom(12)
if len(password) != 32:
password = hashlib.md5(password).hexdigest().encode("utf-8")
salt_password = salt + password
print(salt_password)
password = hashlib.md5(salt_password).hexdigest()
salt_id = Salt.objects.create(value=salt).id
UserInfo.objects.create(user_type=user_type, name=name,
password=password, email=email,
memo=memo, salt_id=salt_id)
# form.save()
return redirect('/ad/login/')
except Exception as e:
logging.error("form.save()", e)
return render(request, 'register.html',
{'form': registerForm, 'status': result})
# form.save()
else:
# print form.errors.as_json()
result = '无效的用户名/密码'
return render(request, 'register.html',
{'form': registerForm, 'status': result})
def AssetList(request, page_num=1):
"""
资产列表,
:param request: 用户登录
:param page_num: 页码
@return:
result: 状态
asset_list: asset表的objects数据
assetlistform: assetlistform 表单验证
host_group: 资产对应的的用户组
"""
if not request.session.get('username', None):
return redirect('/ad/login/')
asset_list = Asset.objects.all()
# 调用分页函数
pagination_value = pagination(table_queryset=asset_list,
page_num=page_num, default_size=10)
if not pagination_value:
return HttpResponse("please input valid page number")
else:
down_page, up_page, page_min, page_value, page_total = pagination_value
try:
page_content = asset_list[page_min:page_value]
except Exception as err:
print(err)
result = ''
assetlistform = AssetListForm()
host_group = HostGroup.objects.all()
if request.method == 'POST':
Hostname = request.POST.get('hostname', None)
Ip = request.POST.get('ip', None)
user_group = request.POST.get('user_group', None)
try:
groupinstance = UserGroup.objects.get(id=user_group)
except Exception as e:
logging.error("user_group", e)
print(Hostname, Ip, user_group)
# is_empty = all([Hostname,Ip])
# print Id,Ip,Hostname
if Hostname and Ip:
print('Hostname', Hostname)
print('ip', Ip)
try:
Asset.objects.create(hostname=Hostname, ip=Ip,
user_group=groupinstance)
return redirect("/ad/assetlist/%d/" % page_total)
except Exception as e:
logging.error(e)
return redirect("/ad/assetlist/")
else:
# return HttpResponse('ip或主机名错误')
return redirect("/ad/assetlist/")
else:
return render(request, 'assetlist.html',
{'data': page_content, 'form': assetlistform,
"down_page": down_page, "up_page": up_page,
"page_num": page_num, 'host_group': host_group,
'status': result})
def AssetUpdate(request):
"""
资产配置修改
:request: user login
:return: httpresponse('ok')
"""
if not request.session.get('username', 0):
return redirect('/ad/login/')
if request.method == 'POST':
# print request.POST.get('data')
Hostname = request.POST.get('hostname', None)
Ip = request.POST.get('ip', None)
Id = request.POST.get('id', None)
# is_empty = all([Hostname,Ip])
# print Id,Ip,Hostname
if Hostname and Ip:
print('Hostname', Hostname)
print('ip', Ip)
obj = Asset.objects.get(id=Id)
obj.hostname = Hostname
obj.ip = Ip
try:
obj.save()
print("ok")
except Exception as e:
logging.error(e)
return HttpResponse("主机名或ip不能相同")
return HttpResponse('ok')
else:
return HttpResponse('ip或主机名不能为空')
return render(request, 'assetlist.html')
# elif Ip:
# print 'Ip',Ip
# obj = Asset.objects.get(id=Id)
# obj.ip = Ip
# obj.save()
# return HttpResponse('ok')
else:
return HttpResponse('404')
def UserList(request, page_num=1):
"""
:param request: 用户登录
:param page_num: 页码
@return:
user_list_name: table 标题
user_list: 用户数据
"""
user_list = UserInfo.objects.all()
# 调用分页函数
pagination_value = pagination(table_queryset=user_list,
page_num=page_num, default_size=10)
if not pagination_value:
return HttpResponse("please input valid page number")
else:
down_page, up_page, page_min, page_value, page_total = pagination_value
try:
page_content = user_list[page_min:page_value]
except Exception as err:
print(err)
if not request.session.get('username', None):
return redirect('/ad/login/')
elif request.session['username'] != "superadmin":
return redirect('/ad/assetlist/')
user_list_name = ('name', 'email', 'memo', 'typeId', '修改时间', u'创建时间')
return render(request, 'userlist.html',
{'data': page_content, "down_page": down_page,
"up_page": up_page, "page_num": page_num, 'list': user_list_name})
def UserUpdate(request):
"""
用户信息升级
:param request: user login
:return:200
"""
if not request.session.get('username', 0):
return redirect('/ad/login/')
if request.method == 'POST':
# print request.POST.get('data')
name = request.POST.get('Name', None)
email = request.POST.get('Email', None)
if '@' not in email:
return HttpResponse('邮箱信息错误')
exit(0)
u_id = request.POST.get('Id', None)
memo = request.POST.get('Memo', None)
# is_empty = all([Hostname,Ip])
# print name,email,id,memo
is_empty = all([name, email, u_id, memo])
if is_empty:
print('name', name)
print('email', email)
# noinspection PyBroadException
try:
obj = UserInfo.objects.get(id=u_id)
obj.email = email
obj.name = name
obj.memo = memo
obj.save()
except Exception as e:
return HttpResponse(0)
print(e)
return HttpResponse(200)
else:
return HttpResponse(0)
else:
return HttpResponse('404')
@csrf_exempt
def server_monitor_monitor(request):
host = request.get_host().split(":")[0]
print(host)
if host not in ("127.0.0.1", "192.168.115.21", "192.168.115.1"):
return HttpResponse(status=404)
if request.method == 'POST':
# 定义变量
hostname = request.POST.get("hostname", None)
ip = request.POST.get("ip", None)
times = request.POST.get("times", None)
data = request.POST.get("data", None)
user_group = request.POST.get("user_group", 2)
hostgroup = request.POST.get("hostgroup", 1)
print(times)
if not all([hostname, ip, times, data]):
return HttpResponse("err")
# model
asset_db = Asset.objects.filter(hostname=hostname, ip=ip)
# 提交每分钟监控数据
RuleResult.objects.create(host=hostname, time=times, data=data)
# 如果数据库没有这个数据,将主机数据录入进asset表
if len(asset_db) < 1:
Asset.objects.create(hostname=hostname, ip=ip, user_group_id=user_group, hostgroup_id=hostgroup)
return HttpResponse("ook")
else:
data = {}
return render(request, "monitor_monitor.html", {'data': data})
def server_monitor(request, name):
"""
:前置条件: 用户登录
:param request: 用户请求
:param name: asset hostname
:return:
正确返回: 主机对应最新一条记录的list 格式,方便前台进行Echart处理
错误返回: 无监控数据
异常返回: 跳转到/ad/monitor/hostgroup/
"""
if not request.session.get('username', None):
return redirect('/ad/login/')
try:
server_data = RuleResult.objects.filter(host=name)
data1 = dict()
if server_data:
data1["time"] = []
data1["cpu"] = []
data1["memcache"] = []
data1["load"] = dict()
data1["inode"] = dict()
data1["diskpercent"] = dict()
data1["IOPS"] = dict()
data1["sentbyte"] = dict()
data1["recvbyte"] = dict()
data1["connections"] = dict()
data1_index = ("load", "inode", "diskpercent",
"IOPS", "sentbyte", "recvbyte", "connections")
# data1['inode']['/'] = []
# data1['inode']['/boot'] = []
# data1['inode']['/data'] = []
for i in range(len(server_data)):
data1["time"].append(time.mktime(server_data[i].time.timetuple()))
server_data[i].data = json.loads(server_data[i].data)
data1["cpu"].append(server_data[i].data["cpupercent"])
data1["memcache"].append(server_data[i].data["mempercent"])
for item in data1_index:
for k, v in server_data[i].data[item].items():
if item == "inode":
v = int(v.strip("%"))
if type(data1[item].get(k, None)) != list:
data1[item][k] = []
data1[item][k].append(v)
data1["host"] = server_data[0].host
return render(request, "monitor.html", {"data": data1})
return HttpResponse("无监控数据")
except Exception as e:
logging.error("RuleResult", e)
return redirect("/ad/monitor/hostgroup/")
def server_monitor_host(request, page_num=1):
"""
从Asset表(主机表)中取出所有主机,
去RuleResult表(监控结果表)取出每个主机对应的最新数据.
:param request: 用户请求
:return:
正常返回:
data1:
host: 主机名; ip: 主机ip;cpu: cpu;mem: 内存;diskpercent: 磁盘百分比
异常返回: 无监控数据; 跳转到 hostgroup
"""
# 用户必须登录
if not request.session.get('username', None):
return redirect('/ad/login/')
try:
server_data = []
all_host = Asset.objects.all().values("hostname")
print(all_host)
for host in all_host:
one_host = host['hostname']
one_server_data = RuleResult.objects.filter(host=one_host)
server_data.append(one_server_data[len(one_server_data)-1])
print(server_data)
data1 = []
if server_data:
for item in server_data:
item_data = dict()
item.data = json.loads(item.data)
item_data['host'] = item.host
item_data['ip'] = Asset.objects.filter(hostname=item.host).values("ip")[0]['ip']
item_data['cpu'] = item.data['cpupercent']
item_data['mem'] = item.data['mempercent']
temp_disk_percent = 0
for k in item.data['diskpercent']:
if temp_disk_percent < item.data['diskpercent'][k]:
temp_disk_percent = item.data['diskpercent'][k]
item_data['disk'] = temp_disk_percent
print(temp_disk_percent)
data1.append(item_data)
# 调用分页函数
try:
default_size = int(request.GET.get("default_size", 10))
except Exception as e:
logging.warning("error default size, Not an integer", e)
default_size = 10
pagination_value = pagination(table_queryset=data1,
page_num=page_num, default_size=default_size)
if not pagination_value:
return HttpResponse("please input valid page number")
else:
down_page, up_page, page_min, page_value, page_total = pagination_value
page_content = data1[page_min:page_value]
return render(request, "monitor_host.html", {"data": page_content, "down_page": down_page,
"up_page": up_page, "page_num": page_num,
"default_size": default_size})
return HttpResponse("无监控数据")
except Exception as e:
logging.error("RuleResult", e)
return redirect("/ad/monitor1/")
def server_monitor_hostgroup(request, page_num=1):
"""主机组管理"""
if not request.session.get('username', None):
return redirect('/ad/login/')
result = ''
host_group = HostGroup.objects.all()
# 调用分页函数
pagination_value = pagination(table_queryset=host_group,
page_num=page_num, default_size=10)
if not pagination_value:
return HttpResponse("please input valid page number")
else:
down_page, up_page, page_min, page_value, page_total = pagination_value
try:
page_content = host_group[page_min:page_value]
except Exception as err:
print(err)
# print(host_group[0].id)
host_list = dict()
templetes_form = Templates.objects.all()
# 7/2 start
# templates_form = TemplatesForm()
if request.method == 'POST':
hostgroup_name = request.POST.get("hostgroup_name", None)
hostgroup_templates = request.POST.get("hostgroup_templates", None)
hostgroup_memo = request.POST.get("hostgroup_memo", None)
print("创建模板", hostgroup_name, hostgroup_templates, hostgroup_memo)
try:
HostGroup.objects.create(name=hostgroup_name,
templates_id=hostgroup_templates,
memo=hostgroup_memo)
except Exception as err:
print("主机组创建失败", err)
return redirect("/ad/monitor/hostgroup/%d/" % page_total)
else:
# 7/2 end
for i in host_group:
hosts = Asset.objects.filter(hostgroup=i.id)
host_list[i.id] = []
for item in hosts:
host_list[i.id].append(item.hostname)
print(host_list)
return render(request, 'hostgroup.html',
{'data': page_content, "host_list": host_list,
"down_page": down_page, "up_page": up_page,
"page_num": page_num, 'status': result,
"form2": templetes_form})
def server_monitor_templates(request, page_num=1):
"""模板管理"""
if not request.session.get('username', None):
return redirect('/ad/login/')
result = ''
templetes = Templates.objects.all()
# 调用分页函数
pagination_value = pagination(table_queryset=templetes,
page_num=page_num, default_size=10)
if not pagination_value:
return HttpResponse("please input valid page number")
else:
down_page, up_page, page_min, page_value, page_total = pagination_value
try:
page_content = templetes[page_min:page_value]
except Exception as err:
print(err)
# templates_form = TemplatesForm()
triggers_form = Triggers.objects.all()
# 7/2 start
if request.method == 'POST':
templates_name = request.POST.get("templates_name", None)
templates_triggers = request.POST.get("templates_triggers", None)
templates_memo = request.POST.get("templates_memo", None)
print("创建模板", templates_name, templates_triggers, templates_memo)
try:
Templates.objects.create(name=templates_name,
triggers_id=templates_triggers,
memo=templates_memo)
except Exception as err:
print("模板创建失败", err)
return redirect("/ad/monitor/templates/%d/" % page_total)
else:
# 7/2 end
return render(request, 'templetes.html',
{'data': page_content, 'status': result,
"down_page": down_page, "up_page": up_page,
"page_num": page_num, "form2": triggers_form})
def server_monitor_triggers(request, page_num=1):
"""触发器管理"""
if not request.session.get('username', None):
return redirect('/ad/login/')
result = ''
triggers = Triggers.objects.all()
# 调用分页函数
pagination_value = pagination(table_queryset=triggers,
page_num=page_num, default_size=10)
if not pagination_value:
return HttpResponse("please input valid page number")
else:
down_page, up_page, page_min, page_value, page_total = pagination_value
try:
page_content = triggers[page_min:page_value]
except Exception as err:
print(err)
# 7/2 start
if request.method == 'POST':
# 新建触发器
triggers_name = request.POST.get("triggers_name", None)
triggers_memo = request.POST.get("triggers_memo", None)
print("name, memo", triggers_name, triggers_memo)
try:
Triggers.objects.create(name=triggers_name, memo=triggers_memo)
except Exception as err:
print("触发器创建失败", err)
return redirect("/ad/monitor/triggers/%d/" % page_total)
else:
# 7/2 end
return render(request, 'triggers.html',
{'data': page_content, "down_page": down_page,
"up_page": up_page, "page_num": page_num,
'status': result})
def server_monitor_warning(request, page_num=1):
"""
告警显示(get), 添加新的告警规则(post)
:param request: 用户请求
:param page_num: 请求页面
:return:
"""
if not request.session.get('username', None):
return redirect('/ad/login/')
# rule_index 是报警规则
rule_index = RuleIndex.objects.all()
# 调用分页函数
pagination_value = pagination(table_queryset=rule_index,
page_num=page_num, default_size=10)
if not pagination_value:
return HttpResponse("please input valid page number")
else:
down_page, up_page, page_min, page_value, page_total = pagination_value
try:
page_content = rule_index[page_min: page_value]
except Exception as err:
print(err)
result = ''
rule_index_form = RuleIndexForm()
triggers = Triggers.objects.all()
if request.method == 'POST':
# check_num = triggers_times_choice[int(request.POST["triggers_times"])]
form = RuleIndexForm(request.POST)
# form["warning"] = 1 - check_num
if form.is_valid():
# data = form.clean()
# user = data.get('name',None)
# triggers_times_choice = (1, 3, 5, 10, 15, 30)
post_name = request.POST.get("name", None)
post_triggers = int(request.POST.get("triggers", None))
post_time = request.POST.get("time", None)
post_triggers_times = request.POST.get("triggers_times", None)
post_triggers_diff = request.POST.get("triggers_diff", None)
post_triggers_value = request.POST.get("triggers_value", None)
check_num = int(request.POST["triggers_times"])
post_warning = 1 - check_num
switch = request.POST.get("switch", 1)
try:
# form.save()
RuleIndex.objects.create(name=post_name, triggers_id=post_triggers, time=post_time,
triggers_times=post_triggers_times, triggers_diff=post_triggers_diff,
triggers_value=post_triggers_value, warning=post_warning, switch=switch)
return redirect('/ad/monitor/warning/%d/' % page_total)
except Exception as e:
logging.error("form.save", e)
else:
print("表单无效")
print(form.clean())
result = '表单无效'
return HttpResponse(result)
return render(request, 'warning.html', {'data': page_content, 'form': triggers,
"down_page": down_page, "up_page": up_page,
"page_num": page_num, "form2": rule_index_form,
'status': result})
def server_monitor_warning_update(request, page_num=1):
"""启用/停止 告警规则"""
if not request.session.get('username', None):
return redirect('/ad/login/')
rule_index_id = request.POST.get("id", None)
rule_index_switch = request.POST.get("switch", None)
print(rule_index_id, rule_index_switch)
# triggers_times_choice = (1, 3, 5, 10, 15, 30)
if all([rule_index_id, rule_index_switch]):
try:
obj = RuleIndex.objects.get(id=rule_index_id)
obj.switch = rule_index_switch
print(type(obj.switch), obj.switch)
if obj.switch == str(1):
obj.warning = 1 - obj.triggers_times
else:
obj.warning = -30
print(obj.warning)
obj.save()
except Exception as e:
print(e)
return redirect("/ad/monitor/warning/%d/" % page_num)
def server_monitor_message(request, u_id):
if request.META.get("REMOTE_ADDR", None) not in ("192.168.115.20", "192.168.115.21"):
return HttpResponse(status=444)
try:
rule_index = RuleIndex.objects.get(id=u_id)
rule_index_name = RuleIndex.objects.get(id=u_id).name # this is a number
triggers_id = RuleIndex.objects.get(id=u_id).triggers_id
templates_id = Templates.objects.get(triggers=triggers_id).id
host_group = HostGroup.objects.get(templates=templates_id)
hosts = Asset.objects.filter(hostgroup=host_group.id)
# triggers_times_choice = (1, 3, 5, 10, 15, 30)
triggers_times = rule_index.triggers_times
triggers_diff = rule_index.triggers_diff_choice[rule_index.triggers_diff][1]
triggers_value = rule_index.triggers_value
host_list = []
temp_warning_status = 0
rule_index_switch = rule_index.switch
rule_index_name_choice = ("ping", "cpupercent", "mempercent", "inode",
"diskpercent", "IOPS", "sentbyte",
"connections", "recvbyte", "LISTEN")
for item in hosts:
host_list.append(item.hostname)
hostname = item.hostname
rule_result_query_set = RuleResult.objects.filter(host=hostname)
data = json.loads(rule_result_query_set[len(rule_result_query_set) - 1].data)
print(type(rule_index_switch), rule_index_switch)
# 检测监控是启动状态
if not rule_index_switch:
break
# 检测主机列表不为空
if len(RuleResult.objects.filter(host=hostname)) == 0:
continue
# 检查数据是否超时且不是ping检测, ping检测是服务端检测
elif time.mktime(rule_result_query_set[len(rule_result_query_set)-1].time.timetuple()) + 120\
< time.time() and rule_index_name != 0:
continue
else:
# print(triggers_times, triggers_diff, triggers_value)
# print(type(triggers_times), type(triggers_diff), type(triggers_value))
temp_warning_rule_name = rule_index_name_choice[rule_index_name]
# 服务器宕机检测
if temp_warning_rule_name == 'ping':
# ping监控函数,检查后跳过后续监控项
temp_warning_status += server_monitor_message_ping(item.ip, rule_index, triggers_times,
hostname, host_group, temp_warning_rule_name)
continue
print(rule_index_name)
print(data[temp_warning_rule_name])
result_data = data[temp_warning_rule_name]
# 服务器 CPU 内存检测
if type(result_data) is float or type(result_data) is int:
if eval(str(result_data) + triggers_diff + str(triggers_value)):
print("参数%s ,当前值为%f" % (temp_warning_rule_name, result_data))
temp_warning_status += 1
# 大于触发次数, 进行邮件报警
warning_action(rule_index, triggers_times, hostname, host_group,
temp_warning_rule_name, result_data)
print(rule_index.warning, host_group.name)
break
else:
# 无告警/告警恢复
# warning_recover(rule_index, triggers_times, rule_index_name_choice)
continue
elif type(result_data) is dict:
# 多性能指标参数监控 如: 磁盘 网卡
temp_warning_status += server_monitor_message_dict(result_data, temp_warning_rule_name,
rule_result_query_set, triggers_diff,
triggers_value, rule_index, triggers_times,
hostname, host_group)
elif type(result_data) is list and temp_warning_rule_name == "LISTEN":
# 端口检查
addr_and_port = "0.0.0.0:" + str(triggers_value)
if addr_and_port not in result_data:
temp_warning_status += 1
# 告警动作
warning_action(rule_index, triggers_times, hostname, host_group,
temp_warning_rule_name, result_data)
print(rule_index.warning, host_group.name)
break
else:
# 无告警/告警恢复
# warning_recover(rule_index, triggers_times, rule_index_name_choice)
continue
else:
print("其他")
if temp_warning_status == 0:
warning_recover(rule_index, triggers_times, rule_index_name_choice)
# 调用rule_index数据库保存函数
rule_index_save(temp_warning_status, rule_index, triggers_times)
return render(request, "message.html",
{"host_group": host_group, "host_list": host_list, "data": data})
except Exception as e:
logging.error("报警规则id错误", e)
return HttpResponse("ok")
def server_monitor_message_ping(ip, rule_index, triggers_times,
hostname, host_group, temp_warning_rule_name):
"""
服务器宕机检测
:param ip: 服务器ip
:param rule_index: 数据库报警规则表的报列
:param triggers_times: 触发器次数
:param hostname: 主机名
:param host_group: 主机组
:param temp_warning_rule_name: 报警规则名称
:return: 返回1/0; 1表示数据异常,0表示数据正常
"""
try:
print("ip", ip)
tn = telnetlib.Telnet(ip, '22', timeout=5)
tn.close()
# 无告警/告警恢复
# warning_recover(rule_index, triggers_times, rule_index_name_choice)
result = 0
return result
except Exception:
result = 1
# 告警动作
warning_action(rule_index, triggers_times, hostname, host_group,
temp_warning_rule_name, -1)
return result
def server_monitor_message_dict(result_data, temp_warning_rule_name, rule_result_query_set,
triggers_diff, triggers_value, rule_index,
triggers_times, hostname, host_group):
"""
:param result_data: 客户端返回的数据
:param temp_warning_rule_name: 报警名称
:param rule_result_query_set: 主机对应的所有报警规则
:param triggers_diff: 触发比较符
:param triggers_value: 阈值
:param rule_index: 对应的报警规则
:param triggers_times: 触发次数
:param hostname: 主机名
:param host_group: 主机组
:return: 返回1/0; 1表示数据异常,0表示数据正常
"""
result = 0
for k in result_data:
if temp_warning_rule_name == "sentbyte" or temp_warning_rule_name == "recvbyte":
temp_last_data = json.loads(rule_result_query_set[len(rule_result_query_set) - 2].data)
temp_last_value = temp_last_data[temp_warning_rule_name][k]
else:
temp_last_value = 0
if eval(str(result_data[k]).strip("%") + "-" + str(temp_last_value) +
triggers_diff + str(triggers_value)):
if type(result_data[k]) != str:
# 告警动作
warning_action(rule_index, triggers_times, hostname, host_group,
temp_warning_rule_name, result_data)
print("参数%s ,当前值为%f" %
(temp_warning_rule_name, result_data[k]))
print(result_data[k] - temp_last_value)
# inode数据, 删除去除百分号
elif temp_warning_rule_name == "inode":
print("参数%s ,当前值为%f" %
(temp_warning_rule_name, int(result_data[k].strip("%"))))
result += 1
break
else:
# 无告警/告警恢复
# warning_recover(rule_index, triggers_times, rule_index_name_choice)
continue
return result
@csrf_exempt
def custom_monitor(request):
"""
get: 返回所有自定义监控
post: 新增自定义监控
"""
# if not request.session.get('username', None):
# return redirect('/ad/login/')
if request.method == 'POST':
url = request.POST.get("url", None)
if not re.match(r'(http://|https://)?([a-zA-Z1-9]+\.)+[a-zA-Z1-9]+?', url):
return HttpResponse('url错误')
method = request.POST.get("method", None)
post_data = request.POST.get("post_data", None)
if post_data == '': post_data = None
get_params = request.POST.get("get_params", None)
if get_params == '': get_params = None
headers = request.POST.get("headers", None)
if headers == "": headers = None
status = request.POST.get("status", None)
try:
if "https://" not in url or "http://" not in url:
url_list = list(url)
url_list.insert(0, "http://")
url = ''.join(url_list)
print({"url": url, "method": method})
print(post_data, get_params, headers)
CustomMonitor.objects.create(url=url, method=method, post_data=post_data,
get_params=get_params, headers=headers,
status=int(status))
return redirect("/ad/custom_monitor/")
except Exception as e:
return redirect("/ad/custom_monitor/")
print("数据写入异常", e)
if request.method == 'GET':
custom_monitor_data = CustomMonitor.objects.all()
return render(request, "custom_monitor.html", {"data": custom_monitor_data})
return HttpResponse("ok")
@csrf_exempt
def custom_monitor_dict(request):
"""
get: 将自定义监控返回给client
post: 允许client修改状态
"""
if request.method == 'GET':
custom_monitor_data = CustomMonitor.objects.all().values_list()
custom_monitor_json = []
for i in custom_monitor_data:
temp_dict = dict()
temp_dict["id"] = i[0]
temp_dict["url"] = i[1]
temp_dict["method"] = i[2]
temp_dict["post_data"] = i[3]
temp_dict["get_params"] = i[4]
temp_dict["headers"] = i[5]
custom_monitor_json.append(temp_dict)
custom_monitor_json = json.dumps(custom_monitor_json)
return HttpResponse(custom_monitor_json)
# 处理自定义监控的处理结果
if request.method == "POST":
cm_id = request.POST.get("id", None)
status = request.POST.get("status", None)
print(cm_id, status)
try:
custom_monitor_obj = CustomMonitor.objects.get(id=cm_id)
custom_monitor_obj.status = status
custom_monitor_obj.save()
except Exception as e:
traceback.print_exc()
return HttpResponse('err')
return HttpResponse('ok')
def rule_index_save(temp_warning_status, rule_index, triggers_times):
"""
数据库保存监控状态
:param temp_warning_status: 临时状态
:param rule_index: 数据库查询集
:param triggers_times: 触发器触发次数
:return: 保存数据到数据库
"""
try:
print(temp_warning_status, rule_index.name)
if temp_warning_status > 0:
rule_index.warning += 1
if rule_index.name == 0:
rule_index.warning = 1
elif not rule_index.switch:
rule_index.warning = -30
else:
rule_index.warning = 1 - triggers_times
rule_index.save()
except Exception as err:
print("数据库储存失败", err)
def warning_action(rule_index, triggers_times, hostname, host_group,
temp_warning_rule_name, result_data, message="Email"):
# 告警动作
try:
print("异常", temp_warning_rule_name, rule_index.warning)
if temp_warning_rule_name == 'ping':
temp_warning_rule_name = "服务器宕机"
elif temp_warning_rule_name == "LISTEN":
result_data = -1
if rule_index.warning > 0 and rule_index.warning % triggers_times == 1:
if message == "Email":
# 邮件接口
send_mail(hostname,
host_group.name,
temp_warning_rule_name,
result_data)
elif message == "Message":
# 短信接口待开发
pass
elif message == "ALL":
# 同时发送邮件和短信
# 邮件接口
send_mail(hostname,
host_group.name,
temp_warning_rule_name,
result_data)
# 短信接口
pass
except Exception as err:
print("发件失败", err)
def warning_recover(rule_index, triggers_times, rule_index_name_choice):
# 告警恢复
print(rule_index.warning - triggers_times)
if rule_index.warning > 0:
print("本次告警持续时间为: %d 分钟" %
((rule_index.warning - 1 + triggers_times) * 5))
return True
else:
print(rule_index_name_choice[rule_index.name], "参数正常")
return False
def send_mail(host, host_group, warning_name, warning_value):
"""
# 邮件发送函数, 报警中引用
:param host: 主机名
:param host_group: 主机组
:param warning_name: 告警名
:param warning_value: 告警值
:return:
正常输出: 邮件发送成功
异常输出: 邮件发送失败
"""
# 设置服务器
mail_host = "smtp.163.com"
# 用户名
mail_user = "17051018558@163.com"
# 口令
mail_pass = "j2H1EsQTJ4qRG89z"
sender = '17051018558@163.com'
receivers = ['17051018558@163.com']
message = MIMEText("主机%s 所在主机组 %s 当前发生告警,告警名称为 %s ,当前值为 %f" %
(host, host_group, warning_name, warning_value), 'plain', 'utf-8')
message['From'] = "monitor@huaxixianchang.com"
message['To'] = "17051018558@163.com"
subject = "%s 监控告警" % warning_name
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP()
# 25 为 SMTP 端口号
smtpObj.connect(mail_host, 25)
smtpObj.login(mail_user, mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
print("邮件发送成功")
except smtplib.SMTPException as e:
print("Error: 无法发送邮件", e)
def pagination(table_queryset, page_num, default_size=10):
"""
分页函数
:param table_queryset: 数据库表查询集合
:param page_num: 页码
:param default_size: 页面大小
:return: 返回 下一页, 上一页, 页面开始处, 集合长度, 最大页码
"""
page_total = int((len(table_queryset) + default_size - 1) / default_size)
print(page_total)
if 0 < page_num < page_total:
page_value = page_num * default_size
page_min = page_value - default_size
down_page = page_num + 1
up_page = page_num - 1
if page_num == 1:
up_page = page_num
elif page_num == page_total:
page_value = len(table_queryset)
page_min = len(table_queryset) - len(table_queryset) % default_size
down_page = page_num
up_page = page_num - 1
if page_total == 1:
up_page = page_num
print(page_value, page_min)
else:
return False
return down_page, up_page, page_min, page_value, page_total
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/zhuqiyu/django_monitor.git
git@gitee.com:zhuqiyu/django_monitor.git
zhuqiyu
django_monitor
django_monitor
master

搜索帮助