独角鲸同步合作方公司数据项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

128 lines
4.3 KiB

import base64
import http
import json
import logging
import threading
import uuid
import traceback
from django.utils.deprecation import MiddlewareMixin
from rest_framework import response as rest_response
from utils.custom import get_ip
local = threading.local() # 获取当前线程对象
logger = logging.getLogger("info")
error_logger = logging.getLogger("error")
class RequestLogFilter(logging.Filter):
"""
日志过滤器,将当前请求线程的request信息保存到日志的record上下文
record带有formater需要的信息。
"""
def filter(self, record):
record.method = getattr(local, 'method', "none")
record.path = getattr(local, 'path', "none")
record.request_id = getattr(local, 'request_id', "none")
record.params = getattr(local, 'params', "none")
record.body = getattr(local, 'body', "none")
record.user = getattr(local, 'user', "none")
return True
class RequestLogMiddleware(MiddlewareMixin):
"""
将request的信息记录在当前的请求线程上。
"""
def process_request(self, request):
# 以下逻辑是 实现请求进来打印 相关请求参数
local.request_id = str(uuid.uuid1()) # 线程对象里面加入uuid
body = {}
try:
body = request.body.decode()
if body:
body = json.loads(body)
except:
pass
token = request.META.get("HTTP_AUTHORIZATION")
local.user = "guest"
if token:
try:
user_base64 = token.split(".")[1]
missing_padding = 4 - len(user_base64) % 4
if missing_padding:
user_base64 += '=' * missing_padding
local.user = str(base64.b64decode(bytes(user_base64, 'utf-8')), encoding='utf-8')
except:
local.user = token
pass
local.method = request.method
local.params = request.GET.dict()
local.path = request.path_info
local.body = json.dumps(body)
local.ip = get_ip(request)
request_info = {
"ip": get_ip(request),
"request_id": local.request_id,
'method': request.method,
'path': request.path_info,
'params': request.GET.dict(),
'body': body,
'user': local.user,
}
logger.info(f'requests: {json.dumps(request_info, ensure_ascii=False)}')
def process_response(self, request, response):
"""
当请求是媒体请求时,需要设置对应的响应头以方便浏览器可以缓存媒体的当前播放时间,从而解决拉进度条会回弹到原点的bug
"""
if request.path.endswith(".mp3"):
response["Accept-Ranges"] = "bytes"
token = request.META.get("HTTP_AUTHORIZATION")
local.user = "guest"
if token:
try:
user_base64 = token.split(".")[1]
missing_padding = 4 - len(user_base64) % 4
if missing_padding:
user_base64 += '=' * missing_padding
local.user = str(base64.b64decode(bytes(user_base64, 'utf-8')), encoding='utf-8')
except Exception as e:
local.user = token
error_logger.error(
"process_response failed: \n%s" % (traceback.format_exc()))
pass
data = response.status_code
# if response.data:
# data = response.data
local.method = request.method
local.params = request.GET.dict()
local.path = request.path_info
local.ip = get_ip(request)
local.response = data
request_info = {
"ip": get_ip(request),
"request_id": local.request_id,
'method': request.method,
'path': request.path_info,
'params': request.GET.dict(),
'user': local.user,
"response": data,
}
logger.info('response: %r' % request_info)
return response
class ExceptionLoggingMiddleware(MiddlewareMixin):
def process_exception(self, request, exception):
import traceback
error_logger.error(traceback.format_exc())