import json
import time
import re
from django.conf import settings
from django.urls import resolve
from django.utils import timezone
from drf_api_logger import API_LOGGER_SIGNAL
from drf_api_logger.start_logger_when_server_starts import LOGGER_THREAD
from drf_api_logger.utils import get_headers, get_client_ip, mask_sensitive_data
from knox.auth import TokenAuthentication
from rest_framework import exceptions
"""
File: api_logger_middleware.py
Class: APILoggerMiddleware
重写以在日志中记录用户信息
"""
class APILoggerMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
self.DRF_API_LOGGER_DATABASE = False
if hasattr(settings, 'DRF_API_LOGGER_DATABASE'):
self.DRF_API_LOGGER_DATABASE = settings.DRF_API_LOGGER_DATABASE
self.DRF_API_LOGGER_SIGNAL = False
if hasattr(settings, 'DRF_API_LOGGER_SIGNAL'):
self.DRF_API_LOGGER_SIGNAL = settings.DRF_API_LOGGER_SIGNAL
self.DRF_API_LOGGER_PATH_TYPE = 'ABSOLUTE'
if hasattr(settings, 'DRF_API_LOGGER_PATH_TYPE'):
if settings.DRF_API_LOGGER_PATH_TYPE in ['ABSOLUTE', 'RAW_URI', 'FULL_PATH']:
self.DRF_API_LOGGER_PATH_TYPE = settings.DRF_API_LOGGER_PATH_TYPE
self.DRF_API_LOGGER_SKIP_URL_NAME = []
if hasattr(settings, 'DRF_API_LOGGER_SKIP_URL_NAME'):
if type(settings.DRF_API_LOGGER_SKIP_URL_NAME) is tuple or type(
settings.DRF_API_LOGGER_SKIP_URL_NAME) is list:
self.DRF_API_LOGGER_SKIP_URL_NAME = settings.DRF_API_LOGGER_SKIP_URL_NAME
self.DRF_API_LOGGER_SKIP_NAMESPACE = []
if hasattr(settings, 'DRF_API_LOGGER_SKIP_NAMESPACE'):
if type(settings.DRF_API_LOGGER_SKIP_NAMESPACE) is tuple or type(
settings.DRF_API_LOGGER_SKIP_NAMESPACE) is list:
self.DRF_API_LOGGER_SKIP_NAMESPACE = settings.DRF_API_LOGGER_SKIP_NAMESPACE
self.DRF_API_LOGGER_METHODS = []
if hasattr(settings, 'DRF_API_LOGGER_METHODS'):
if type(settings.DRF_API_LOGGER_METHODS) is tuple or type(
settings.DRF_API_LOGGER_METHODS) is list:
self.DRF_API_LOGGER_METHODS = settings.DRF_API_LOGGER_METHODS
self.DRF_API_LOGGER_STATUS_CODES = []
if hasattr(settings, 'DRF_API_LOGGER_STATUS_CODES'):
if type(settings.DRF_API_LOGGER_STATUS_CODES) is tuple or type(
settings.DRF_API_LOGGER_STATUS_CODES) is list:
self.DRF_API_LOGGER_STATUS_CODES = settings.DRF_API_LOGGER_STATUS_CODES
def __call__(self, request):
# Run only if logger is enabled.
if self.DRF_API_LOGGER_DATABASE or self.DRF_API_LOGGER_SIGNAL:
url_name = resolve(request.path_info).url_name
namespace = resolve(request.path_info).namespace
# Always skip Admin panel
if namespace == 'admin':
return self.get_response(request)
# Skip for url name
print("url_name",url_name)
if url_name in self.DRF_API_LOGGER_SKIP_URL_NAME:
return self.get_response(request)
# Skip entire app using namespace
if namespace in self.DRF_API_LOGGER_SKIP_NAMESPACE:
return self.get_response(request)
start_time = time.time()
request_data = ''
try:
request_data = json.loads(request.body) if request.body else ''
except:
pass
# Code to be executed for each request before
# the view (and later middleware) are called.
response = self.get_response(request)
# Only log required status codes if matching
if self.DRF_API_LOGGER_STATUS_CODES and response.status_code not in self.DRF_API_LOGGER_STATUS_CODES:
return response
# Code to be executed for each request/response after
# the view is called.
headers = get_headers(request=request)
method = request.method
# Log only registered methods if available.
if len(self.DRF_API_LOGGER_METHODS) > 0 and method not in self.DRF_API_LOGGER_METHODS:
return response
if response.get('content-type') in ('application/json', 'application/vnd.api+json', 'application/gzip'):
if response.get('content-type') == 'application/gzip':
response_body = '** GZIP Archive **'
elif getattr(response, 'streaming', False):
response_body = '** Streaming **'
else:
if type(response.content) == bytes:
response_body = json.loads(response.content.decode())
else:
response_body = json.loads(response.content)
if self.DRF_API_LOGGER_PATH_TYPE == 'ABSOLUTE':
api = request.build_absolute_uri()
elif self.DRF_API_LOGGER_PATH_TYPE == 'FULL_PATH':
api = request.get_full_path()
elif self.DRF_API_LOGGER_PATH_TYPE == 'RAW_URI':
api = request.get_raw_uri()
else:
api = request.build_absolute_uri()
try:
user,_ = TokenAuthentication().authenticate(request)
except Exception as e:
user = None
data = dict(
user=user,
api=mask_sensitive_data(api, mask_api_parameters=True),
headers=mask_sensitive_data(headers),
body=mask_sensitive_data(request_data),
method=method,
client_ip_address=get_client_ip(request),
response=mask_sensitive_data(response_body),
status_code=response.status_code,
execution_time=time.time() - start_time,
added_on=timezone.now()
)
if self.DRF_API_LOGGER_DATABASE:
if LOGGER_THREAD:
d = data.copy()
d['headers'] = json.dumps(d['headers'], indent=4, ensure_ascii=False)
if request_data:
d['body'] = json.dumps(d['body'], indent=4, ensure_ascii=False)
d['response'] = json.dumps(d['response'], indent=4, ensure_ascii=False)
LOGGER_THREAD.put_log_data(data=d)
if self.DRF_API_LOGGER_SIGNAL:
API_LOGGER_SIGNAL.listen(**data)
else:
return response
else:
response = self.get_response(request)
return response
没有合适的资源?快使用搜索试试~ 我知道了~
重写 Django REST framework drf-api-logger 应用
共45个文件
pyc:21个
py:20个
html:2个
0 下载量 159 浏览量
2023-06-29
23:30:53
上传
评论 1
收藏 107KB ZIP 举报
温馨提示
默认的`drf-api-logger`没有保存用户并且没有获取日志的接口 本文通过重写`drf-api-logger`增加访问用户及获取日志的接口
资源推荐
资源详情
资源评论
收起资源包目录
drf_api_logger.zip (45个子文件)
drf_api_logger
utils.py 3KB
__init__.py 196B
tests.py 0B
admin.py 7KB
start_logger_when_server_starts.py 596B
migrations
__init__.py 0B
0001_initial.py 1KB
0003_apilogsmodel_user.py 675B
0005_alter_apilogsmodel_body_alter_apilogsmodel_headers_and_more.py 748B
__pycache__
0004_alter_apilogsmodel_body_alter_apilogsmodel_headers_and_more.cpython-311.pyc 1KB
__init__.cpython-311.pyc 193B
0002_auto_20211221_2155.cpython-311.pyc 858B
0005_alter_apilogsmodel_body_alter_apilogsmodel_headers_and_more.cpython-311.pyc 1KB
0001_initial.cpython-311.pyc 2KB
0003_apilogsmodel_user.cpython-311.pyc 1KB
0002_auto_20211221_2155.py 426B
0004_alter_apilogsmodel_body_alter_apilogsmodel_headers_and_more.py 706B
events.py 3KB
serializers.py 704B
apps.py 137B
insert_log_into_database.py 2KB
models.py 1KB
templates
change_form.html 203B
charts_change_list.html 3KB
middleware
__init__.py 0B
api_logger_middleware.py 7KB
__pycache__
__init__.cpython-311.pyc 193B
api_logger_middleware.cpython-311.pyc 7KB
urls.py 222B
__pycache__
models.cpython-311.pyc 3KB
__init__.cpython-311.pyc 503B
utils.cpython-311.pyc 4KB
admin.cpython-311.pyc 10KB
events.cpython-311.pyc 6KB
views.cpython-311.pyc 932B
collectstatic.cpython-311.pyc 396B
serializers.cpython-311.pyc 2KB
insert_log_into_database.cpython-311.pyc 4KB
start_logger_when_server_starts.cpython-311.pyc 889B
tests.cpython-311.pyc 179B
urls.cpython-311.pyc 560B
apps.cpython-311.pyc 539B
static
drf_api_logger
js
Chart.bundle.min.js 205KB
css
Chart.min.css 521B
views.py 401B
共 45 条
- 1
资源评论
超级小的大杯柠檬水
- 粉丝: 670
- 资源: 27
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功