sync from local backup
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import time
|
||||
import json
|
||||
import threading
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
SENSITIVE_FIELDS = {
|
||||
'password', 'password1', 'password2', 'old_password', 'new_password',
|
||||
'token', 'access_token', 'refresh_token', 'secret', 'api_key',
|
||||
'authorization', 'credit_card', 'cvv', 'ssn',
|
||||
}
|
||||
|
||||
EXCLUDE_PATHS = [
|
||||
'/static/', '/media/', '/favicon.ico', '/admin/jsi18n/',
|
||||
'/swagger/', '/redoc/',
|
||||
]
|
||||
|
||||
|
||||
def _get_client_ip(request):
|
||||
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||
if x_forwarded_for:
|
||||
return x_forwarded_for.split(',')[0].strip()
|
||||
return request.META.get('REMOTE_ADDR')
|
||||
|
||||
|
||||
def _mask_sensitive_data(data):
|
||||
if not data:
|
||||
return data
|
||||
try:
|
||||
if isinstance(data, str):
|
||||
try:
|
||||
data = json.loads(data)
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
return data[:2000]
|
||||
if isinstance(data, dict):
|
||||
masked = {}
|
||||
for key, value in data.items():
|
||||
if any(s in key.lower() for s in SENSITIVE_FIELDS):
|
||||
masked[key] = '***'
|
||||
elif isinstance(value, dict):
|
||||
masked[key] = _mask_sensitive_data(value)
|
||||
elif isinstance(value, list):
|
||||
masked[key] = [_mask_sensitive_data(item) if isinstance(item, dict) else item for item in value[:10]]
|
||||
else:
|
||||
masked[key] = value
|
||||
return json.dumps(masked, ensure_ascii=False)[:2000]
|
||||
return str(data)[:2000]
|
||||
except Exception:
|
||||
return ''
|
||||
|
||||
|
||||
def _extract_app_name(path):
|
||||
parts = path.strip('/').split('/')
|
||||
if parts and parts[0]:
|
||||
return parts[0]
|
||||
return 'root'
|
||||
|
||||
|
||||
def _save_log_async(log_data):
|
||||
def _save():
|
||||
try:
|
||||
from .models import ApiRequestLog
|
||||
ApiRequestLog.objects.create(**log_data)
|
||||
except Exception:
|
||||
pass
|
||||
thread = threading.Thread(target=_save)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
|
||||
class RequestLoggingMiddleware(MiddlewareMixin):
|
||||
def __init__(self, get_response):
|
||||
super().__init__(get_response)
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
if any(request.path.startswith(path) for path in EXCLUDE_PATHS):
|
||||
return self.get_response(request)
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
try:
|
||||
user = request.user if hasattr(request, 'user') and request.user.is_authenticated else None
|
||||
except Exception:
|
||||
user = None
|
||||
|
||||
response = self.get_response(request)
|
||||
|
||||
try:
|
||||
duration_ms = (time.time() - start_time) * 1000
|
||||
|
||||
request_body = ''
|
||||
if request.method in ('POST', 'PUT', 'PATCH'):
|
||||
try:
|
||||
if hasattr(request, 'body'):
|
||||
body = request.body.decode('utf-8', errors='ignore')
|
||||
request_body = _mask_sensitive_data(body)
|
||||
except Exception:
|
||||
request_body = ''
|
||||
|
||||
response_size = 0
|
||||
if hasattr(response, 'content'):
|
||||
response_size = len(response.content)
|
||||
|
||||
log_data = {
|
||||
'user': user,
|
||||
'username': user.username if user else (request.user.username if hasattr(request, 'user') and hasattr(request.user, 'username') else ''),
|
||||
'ip_address': _get_client_ip(request),
|
||||
'user_agent': request.META.get('HTTP_USER_AGENT', '')[:500],
|
||||
'method': request.method,
|
||||
'path': request.path[:255],
|
||||
'query_string': request.META.get('QUERY_STRING', '')[:1000],
|
||||
'request_body': request_body,
|
||||
'status_code': response.status_code,
|
||||
'response_size': response_size,
|
||||
'duration_ms': round(duration_ms, 2),
|
||||
'app_name': _extract_app_name(request.path),
|
||||
'is_error': response.status_code >= 400,
|
||||
}
|
||||
|
||||
_save_log_async(log_data)
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return response
|
||||
Reference in New Issue
Block a user