229 lines
6.6 KiB
Python
Executable File
229 lines
6.6 KiB
Python
Executable File
|
||
from django.shortcuts import render
|
||
import psutil
|
||
from rest_framework.response import Response
|
||
from rest_framework.views import APIView
|
||
from rest_framework.permissions import IsAuthenticated
|
||
from django.conf import settings
|
||
import os
|
||
from rest_framework import serializers
|
||
from apps.monitor.serializers import DbbackupDeleteSerializer, AuditLogSerializer
|
||
from drf_yasg import openapi
|
||
from drf_yasg.utils import swagger_auto_schema
|
||
from rest_framework.exceptions import NotFound
|
||
from rest_framework.mixins import ListModelMixin
|
||
from apps.monitor.filters import DrfLogFilterSet
|
||
from apps.monitor.models import DrfRequestLog, AuditLog
|
||
|
||
from apps.monitor.errors import LOG_NOT_FONED
|
||
from apps.monitor.services import ServerService, CeleryMonitor, RedisMonitor
|
||
from apps.utils.viewsets import CustomGenericViewSet
|
||
|
||
# Create your views here.
|
||
|
||
|
||
def index(request):
|
||
return render(request, 'monitor/index.html')
|
||
|
||
|
||
def room(request, room_name):
|
||
return render(request, 'monitor/room.html', {
|
||
'room_name': room_name
|
||
})
|
||
|
||
|
||
def video(request):
|
||
return render(request, 'monitor/video.html')
|
||
|
||
|
||
class CeleryInfoView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
def get(self, request, *args, **kwargs):
|
||
"""
|
||
获取celery状态信息
|
||
|
||
获取celery状态信息
|
||
"""
|
||
return Response(CeleryMonitor.get_info())
|
||
|
||
|
||
class RedisInfoView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
def get(self, request, *args, **kwargs):
|
||
"""
|
||
获取redis状态信息
|
||
|
||
获取redis状态信息
|
||
"""
|
||
return Response(RedisMonitor.get_info())
|
||
|
||
|
||
class ServerInfoView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
def get(self, request, *args, **kwargs):
|
||
"""
|
||
获取服务器当前状态
|
||
|
||
cpu/内存/硬盘
|
||
"""
|
||
return Response(ServerService.get_full())
|
||
|
||
|
||
def get_file_list(file_path):
|
||
dir_list = os.listdir(file_path)
|
||
if not dir_list:
|
||
return []
|
||
else:
|
||
# 注意,这里使用lambda表达式,将文件按照最后修改时间顺序升序排列
|
||
# os.path.getmtime() 函数是获取文件最后修改时间
|
||
# os.path.getctime() 函数是获取文件最后创建时间
|
||
dir_list = sorted(dir_list, key=lambda x: os.path.getmtime(
|
||
os.path.join(file_path, x)), reverse=True)
|
||
# print(dir_list)
|
||
return dir_list
|
||
|
||
|
||
class LogView(APIView):
|
||
|
||
@swagger_auto_schema(manual_parameters=[
|
||
openapi.Parameter('name', openapi.IN_QUERY,
|
||
description='日志文件名', type=openapi.TYPE_STRING)
|
||
])
|
||
def get(self, request, *args, **kwargs):
|
||
"""
|
||
查看最近的日志列表
|
||
|
||
查看最近的日志列表
|
||
"""
|
||
logs = []
|
||
name = request.GET.get('name', None)
|
||
# for root, dirs, files in os.walk(settings.LOG_PATH):
|
||
# files.reverse()
|
||
for file in get_file_list(settings.LOG_PATH):
|
||
if len(logs) > 50:
|
||
break
|
||
filepath = os.path.join(settings.LOG_PATH, file)
|
||
if name:
|
||
if name in filepath:
|
||
fsize = os.path.getsize(filepath)
|
||
if fsize:
|
||
logs.append({
|
||
"name": file,
|
||
"filepath": filepath,
|
||
"size": round(fsize/1024, 1)
|
||
})
|
||
else:
|
||
fsize = os.path.getsize(filepath)
|
||
if fsize:
|
||
logs.append({
|
||
"name": file,
|
||
"filepath": filepath,
|
||
"size": round(fsize/1024, 1)
|
||
})
|
||
return Response(logs)
|
||
|
||
|
||
class LogDetailView(APIView):
|
||
|
||
def get(self, request, name):
|
||
"""
|
||
查看日志详情
|
||
|
||
查看日志详情
|
||
"""
|
||
try:
|
||
with open(os.path.join(settings.LOG_PATH, name)) as f:
|
||
data = f.read()
|
||
return Response(data)
|
||
except Exception:
|
||
raise NotFound(**LOG_NOT_FONED)
|
||
|
||
|
||
class DbBackupView(APIView):
|
||
perms_map = {'get': '*', 'delete': 'dbback.delete'}
|
||
|
||
@swagger_auto_schema(request_body=DbbackupDeleteSerializer, responses={200: {}})
|
||
def delete(self, request):
|
||
"""
|
||
删除备份
|
||
|
||
删除备份
|
||
"""
|
||
filepaths = request.data.get('filepaths', [])
|
||
for i in filepaths:
|
||
os.remove(i)
|
||
return Response()
|
||
|
||
@swagger_auto_schema(manual_parameters=[
|
||
openapi.Parameter('name', openapi.IN_QUERY,
|
||
description='文件名', type=openapi.TYPE_STRING)
|
||
])
|
||
def get(self, request, *args, **kwargs):
|
||
"""
|
||
查看最近的备份列表
|
||
|
||
查看最近的备份列表
|
||
"""
|
||
items = []
|
||
name = request.GET.get('name', None)
|
||
# for root, dirs, files in os.walk(settings.LOG_PATH):
|
||
# files.reverse()
|
||
backpath = settings.BACKUP_PATH + '/database'
|
||
for file in get_file_list(backpath):
|
||
if len(items) > 50:
|
||
break
|
||
filepath = os.path.join(backpath, file)
|
||
if name:
|
||
if name in filepath:
|
||
fsize = os.path.getsize(filepath)
|
||
if fsize:
|
||
items.append({
|
||
"name": file,
|
||
"filepath": filepath,
|
||
"size": round(fsize/1024/1024, 1)
|
||
})
|
||
else:
|
||
fsize = os.path.getsize(filepath)
|
||
if fsize:
|
||
items.append({
|
||
"name": file,
|
||
"filepath": filepath,
|
||
"size": round(fsize/1024/1024, 1)
|
||
})
|
||
return Response(items)
|
||
|
||
|
||
class DrfRequestLogSerializer(serializers.ModelSerializer):
|
||
class Meta:
|
||
model = DrfRequestLog
|
||
fields = '__all__'
|
||
|
||
|
||
class DrfRequestLogViewSet(ListModelMixin, CustomGenericViewSet):
|
||
"""请求日志
|
||
|
||
请求日志
|
||
"""
|
||
perms_map = {'get': '*'}
|
||
queryset = DrfRequestLog.objects.all()
|
||
list_serializer_class = DrfRequestLogSerializer
|
||
ordering = ['-requested_at']
|
||
filterset_class = DrfLogFilterSet
|
||
search_fields = ['path', 'view']
|
||
|
||
|
||
class AuditlogViewSet(ListModelMixin, CustomGenericViewSet):
|
||
"""审计日志
|
||
|
||
审计日志
|
||
"""
|
||
perms_map = {'get': '*'}
|
||
queryset = AuditLog.objects.all()
|
||
list_serializer_class = AuditLogSerializer
|
||
ordering = ['-change_time']
|
||
filterset_fields = ['change_user', 'model_name', 'action', 'instance_id']
|
||
search_fields = ['model_name', 'action']
|