新功能(服务器监控): 新增服务器监控功能API

pull/21/head
李强 2021-04-11 01:28:06 +08:00
parent 864d675370
commit 9d8c74e768
9 changed files with 197 additions and 9 deletions

View File

@ -329,3 +329,4 @@ CELERYBEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler' # Back
# ================================================= #
# 接口权限
INTERFACE_PERMISSION = {locals().get("INTERFACE_PERMISSION", False)}
DJANGO_CELERY_BEAT_TZ_AWARE = False

View File

@ -22,7 +22,7 @@ from django.urls import re_path, include
from django.views.static import serve
from rest_framework.views import APIView
from vadmin.utils.response import SuccessResponse
from apps.vadmin.utils.response import SuccessResponse
class CaptchaRefresh(APIView):

View File

@ -5,12 +5,10 @@ from ...op_drf.models import CoreModel
class Monitor(CoreModel):
cpu_num = CharField(max_length=8, verbose_name='CPU核数')
cpu_free = CharField(max_length=8, verbose_name='CPU当前空闲率')
cpu_sys = CharField(max_length=8, verbose_name='CPU已使用率')
mem_num = CharField(max_length=32, verbose_name='内存总数(KB)')
mem_free = CharField(max_length=32, verbose_name='内存剩余大小(KB)')
mem_sys = CharField(max_length=32, verbose_name='内存已使用大小(KB)')
seconds = CharField(max_length=32, verbose_name='运行时间(秒)')
seconds = CharField(max_length=32, verbose_name='系统已运行时间')
server = ForeignKey(to='Server', on_delete=CASCADE, verbose_name="关联服务器信息", db_constraint=False)
class Meta:

View File

@ -1,13 +1,16 @@
from django.db import models
from django.db.models import CharField
from ...op_drf.models import CoreModel
from apps.vadmin.op_drf.fields import UpdateDateTimeField, CreateDateTimeField
class Server(CoreModel):
class Server(models.Model):
name = CharField(max_length=256, verbose_name='服务器名称', null=True, blank=True)
ip = CharField(max_length=32, verbose_name="ip地址")
os = CharField(max_length=32, verbose_name="操作系统")
remark = CharField(max_length=256, verbose_name="备注", null=True, blank=True)
update_datetime = UpdateDateTimeField() # 修改时间
create_datetime = CreateDateTimeField() # 创建时间
class Meta:
verbose_name = '服务器信息'

View File

@ -5,10 +5,10 @@ from ...op_drf.models import CoreModel
class SysFiles(CoreModel):
dir_name = CharField(max_length=32, verbose_name='磁盘路径')
sys_type_name = CharField(max_length=32, verbose_name='系统文件类型')
sys_type_name = CharField(max_length=400, verbose_name='系统文件类型')
type_name = CharField(max_length=32, verbose_name='盘符类型')
total = CharField(max_length=32, verbose_name='磁盘总大小(KB)')
mem_free = CharField(max_length=32, verbose_name='已使用大小(KB)')
disk_sys = CharField(max_length=32, verbose_name='已使用大小(KB)')
monitor = ForeignKey(to='Monitor', on_delete=CASCADE, verbose_name="关联服务器监控信息", db_constraint=False)
class Meta:

View File

@ -0,0 +1,89 @@
import datetime
import logging
import sys
import time
import psutil
from ..monitor.models import Server, Monitor, SysFiles
from ..op_drf.response import SuccessResponse
from ..system.models import ConfigSettings
from ..utils.decorators import BaseCeleryApp
logger = logging.getLogger(__name__)
from platform import platform
def getIP():
"""获取ipv4地址"""
dic = psutil.net_if_addrs()
ipv4_list = []
for adapter in dic:
snicList = dic[adapter]
for snic in snicList:
if snic.family.name == 'AF_INET':
ipv4 = snic.address
if ipv4 != '127.0.0.1':
ipv4_list.append(ipv4)
if len(ipv4_list) >= 1:
return ipv4_list[0]
else:
return None
@BaseCeleryApp(name='apps.vadmin.monitor.tasks.get_monitor_info')
def get_monitor_info():
"""
定时获取系统监控信息
:return:
"""
# 获取服务器
ip = getIP()
if not ip:
logger.error("无法获取到IP")
return
server_obj, create = Server.objects.get_or_create(ip=ip)
if create:
server_obj.name = ip
terse = ('terse' in sys.argv or '--terse' in sys.argv)
aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv)
server_obj.os = platform(aliased, terse)
server_obj.save()
# 获取CPU和内存信息
mem = psutil.virtual_memory()
monitor_obj = Monitor()
monitor_obj.cpu_num = psutil.cpu_count()
monitor_obj.cpu_sys = float(psutil.cpu_percent(0.1))
monitor_obj.mem_num = int(mem.total / 1024)
monitor_obj.mem_sys = int(mem.used / 1024)
monitor_obj.seconds = time.strftime("%d%H 小时 %M 分 %S 秒", time.gmtime(int(time.time()) - int(psutil.boot_time())))
monitor_obj.server = server_obj
monitor_obj.save()
# 保存磁盘信息
for ele in psutil.disk_partitions():
disk = psutil.disk_usage('/')
sys_files_obj = SysFiles()
sys_files_obj.dir_name = ele.mountpoint
sys_files_obj.sys_type_name = ele.opts
sys_files_obj.type_name = ele.fstype
sys_files_obj.total = disk.total
sys_files_obj.disk_sys = disk.used
sys_files_obj.monitor = monitor_obj
sys_files_obj.save()
return SuccessResponse(msg="")
@BaseCeleryApp(name='apps.vadmin.monitor.tasks.clean_surplus_monitor_info')
def clean_surplus_monitor_info():
"""
定时清理多余 系统监控信息
:return:
"""
config_settings_obj = ConfigSettings.objects.filter(configKey='sys.monitor.info.save_days').first()
Monitor.objects.filter(
update_datetime__lt=datetime.timedelta(days=int(config_settings_obj.configValue or 30))).delete()
logger.info(f"成功清空{config_settings_obj.configValue}天前数据")

View File

@ -1,3 +1,4 @@
from django.urls import re_path
from rest_framework.routers import DefaultRouter
from .views import ServerModelViewSet, MonitorModelViewSet
@ -7,6 +8,8 @@ router.register(r'server', ServerModelViewSet)
router.register(r'monitor', MonitorModelViewSet)
urlpatterns = [
re_path('monitor/info/', MonitorModelViewSet.as_view({'get': 'get_monitor_info'})),
re_path('monitor/enabled/', MonitorModelViewSet.as_view({'get': 'enabled_monitor_info'})),
re_path('monitor/clean/', MonitorModelViewSet.as_view({'get': 'clean_all'})),
]
urlpatterns += router.urls

View File

@ -1,8 +1,13 @@
from django_celery_beat.models import PeriodicTask, IntervalSchedule, CrontabSchedule
from rest_framework.request import Request
from .filters import ServerFilter, MonitorFilter
from .models import Server, Monitor
from .serializers import ServerSerializer, MonitorSerializer
from ..op_drf.response import SuccessResponse
from ..op_drf.viewsets import CustomModelViewSet
from ..permission.permissions import CommonPermission
from ..system.models import ConfigSettings
class ServerModelViewSet(CustomModelViewSet):
@ -18,6 +23,7 @@ class ServerModelViewSet(CustomModelViewSet):
create_extra_permission_classes = (CommonPermission,)
ordering = '-create_datetime' # 默认排序
class MonitorModelViewSet(CustomModelViewSet):
"""
服务器监控信息 模型的CRUD视图
@ -30,3 +36,90 @@ class MonitorModelViewSet(CustomModelViewSet):
destroy_extra_permission_classes = (CommonPermission,)
create_extra_permission_classes = (CommonPermission,)
ordering = '-create_datetime' # 默认排序
def get_monitor_info(self, request: Request, *args, **kwargs):
# 定时获取系统监控信息
periodictask_obj = PeriodicTask.objects.filter(task='apps.vadmin.monitor.tasks.get_monitor_info').first()
if not periodictask_obj:
intervalschedule_obj, _ = IntervalSchedule.objects.get_or_create(every=5, period="seconds")
periodictask_obj = PeriodicTask()
periodictask_obj.task = "apps.vadmin.monitor.tasks.get_monitor_info"
periodictask_obj.name = "定时获取系统监控信息"
periodictask_obj.interval = intervalschedule_obj
periodictask_obj.enabled = False
periodictask_obj.save()
# 定时清理多余 系统监控信息
clean_task_obj = PeriodicTask.objects.filter(
task='apps.vadmin.monitor.tasks.clean_surplus_monitor_info').first()
if not clean_task_obj:
crontab_obj, _ = CrontabSchedule.objects.get_or_create(day_of_month="*", day_of_week="*", hour="1",
minute="0", month_of_year="*")
clean_task_obj = PeriodicTask()
clean_task_obj.task = "apps.vadmin.monitor.tasks.clean_surplus_monitor_info"
clean_task_obj.name = "定时清理多余-系统监控信息"
clean_task_obj.crontab = crontab_obj
clean_task_obj.enabled = True
clean_task_obj.save()
# 配置添加
config_obj = ConfigSettings.objects.filter(configKey='sys.monitor.info.save_days').first()
if not config_obj:
config_obj = ConfigSettings()
config_obj.configKey = "sys.monitor.info.save_days"
config_obj.configName = "定时清理多余系统监控信息"
config_obj.configValue = "30"
config_obj.configType = "Y"
config_obj.status = "1"
config_obj.remark = "定时清理多余-系统监控信息默认30天"
config_obj.save()
# 获取保留天数
return SuccessResponse(data={
"enabled": periodictask_obj.enabled,
"interval": periodictask_obj.interval.every,
"save_days": config_obj.configValue if config_obj else "30",
})
def enabled_monitor_info(self, request: Request, *args, **kwargs):
enabled = request.query_params.get('enabled', None)
save_days = request.query_params.get('save_days', None)
interval = request.query_params.get('interval', None)
periodictask_obj = PeriodicTask.objects.filter(task='apps.vadmin.monitor.tasks.get_monitor_info').first()
if enabled:
# 更新监控状态
periodictask_obj.enabled = True if enabled == "1" else False
periodictask_obj.save()
# 更新 定时清理多余 系统监控信息 状态
clean_task_obj = PeriodicTask.objects.filter(
task='apps.vadmin.monitor.tasks.clean_surplus_monitor_info').first()
clean_task_obj.enabled = True if enabled == "1" else False
clean_task_obj.save()
# 更新保留天数
config_obj = ConfigSettings.objects.filter(configKey='sys.monitor.info.save_days').first()
print(33, save_days)
print(22, config_obj)
if save_days and config_obj:
config_obj.configValue = save_days
config_obj.save()
# 更新监控获取频率
if interval:
periodictask_obj.interval.every = interval
periodictask_obj.interval.save()
return SuccessResponse(data={
"enabled": periodictask_obj.enabled,
"interval": periodictask_obj.interval.every,
"save_days": config_obj.configValue if config_obj else "30",
})
def clean_all(self, request: Request, *args, **kwargs):
"""
清空监控信息
:param request:
:param args:
:param kwargs:
:return:
"""
self.get_queryset().delete()
return SuccessResponse(msg="清空成功")

View File

@ -26,3 +26,4 @@ xlrd==2.0.1
coreapi==2.3.3
user-agents==2.2.0
eventlet==0.30.2
psutil==5.8.0