django-vue-admin/dvadmin-backend/apps/vadmin/op_drf/middleware.py

103 lines
3.8 KiB
Python

"""
django中间件
"""
import json
import datetime
from django.utils.deprecation import MiddlewareMixin
from mongoengine import DynamicDocument, StringField, IntField, DictField, DateTimeField
from rest_framework_mongoengine.serializers import DocumentSerializer
import logging
from ..utils.decorators import exceptionHandler
from ..utils.request_util import get_request_ip, get_request_data, get_request_path
from .viewsets import CustomMongoModelViewSet
from django.conf import settings
logger = logging.getLogger(__name__)
class ApiLog(DynamicDocument):
"""
API访问日志的Mongo模型
"""
request_ip = StringField(verbose_name="request_ip", help_text="请求IP")
request_username = StringField(verbose_name="request_username", help_text="请求username")
request_method = StringField(verbose_name="request_method", help_text="请求方法")
request_path = StringField(verbose_name="request_path", help_text="请求路径")
request_body = DictField(verbose_name="request_body", help_text="请求参数")
response_code = IntField(verbose_name="response_code", help_text="响应状态码")
response_reason = StringField(verbose_name="response_reason", help_text="响应简述")
access_time = DateTimeField(verbose_name="access_time", help_text="访问时间")
class ApiLogSerializer(DocumentSerializer):
"""
API访问日志的Mongo序列化器
"""
class Meta:
model = ApiLog
fields = '__all__'
class ApiLogModelViewSet(CustomMongoModelViewSet):
"""
API访问日志的CRUD视图
"""
queryset = ApiLog.objects.all()
serializer_class = ApiLogSerializer
search_fields = ('request_ip', 'request_username', 'request_method', 'response_reason', 'source_system')
ordering = '-access_time' # 默认排序
class ApiLoggingMiddleware(MiddlewareMixin):
"""
用于记录API访问日志中间件
"""
def __init__(self, get_response=None):
super().__init__(get_response)
self.enable = op_settings.get_api_log_setting().get('enable', False)
self.methods = op_settings.get_api_log_setting().get('methods', set())
@classmethod
@exceptionHandler()
def __handle_request(cls, request):
request.request_ip = get_request_ip(request)
request.request_data = get_request_data(request)
request.access_time = datetime.datetime.now()
@classmethod
@exceptionHandler(logger=logger)
def __handle_response(cls, request, response):
# request_data,request_ip由PermissionInterfaceMiddleware中间件中添加的属性
body = getattr(request, 'request_data', {})
# 请求含有password则用*替换掉(暂时先用于所有接口的password请求参数)
if isinstance(body, dict) and body.get('password', ''):
body['password'] = '*' * len(body['password'])
info = {
'request_ip': getattr(request, 'request_ip', 'unknown'),
'request_username': request.user.username,
'request_method': request.method,
'request_path': request.path,
'request_body': body,
'response_code': response.status_code,
'response_reason': response.reason_phrase,
'source_system': getattr(settings,'SOURCE_SYSTEM_NAME',None),
'access_time': request.access_time.strftime('%Y-%m-%d %H:%M:%S'),
}
log = ApiLog(**info)
log.save()
def process_request(self, request):
self.__handle_request(request)
def process_response(self, request, response):
"""
主要请求处理完之后记录
:param request:
:param response:
:return:
"""
if self.enable:
if self.methods == 'ALL' or request.method in self.methods:
self.__handle_response(request, response)
return response