184 lines
8.2 KiB
Python
184 lines
8.2 KiB
Python
"""
|
||
デバッグ用ミドルウェア
|
||
502エラーの原因を特定するためのリクエスト・レスポンス詳細ログ
|
||
"""
|
||
import logging
|
||
import time
|
||
import uuid
|
||
from django.utils import timezone
|
||
from django.http import JsonResponse
|
||
import traceback
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
class DetailedRequestLoggingMiddleware:
|
||
"""
|
||
すべてのリクエストとレスポンスを詳細にログ出力するミドルウェア
|
||
"""
|
||
|
||
def __init__(self, get_response):
|
||
self.get_response = get_response
|
||
|
||
def __call__(self, request):
|
||
# リクエスト開始時の処理
|
||
request_id = str(uuid.uuid4())[:8]
|
||
start_time = time.time()
|
||
request_timestamp = timezone.now()
|
||
|
||
# リクエスト情報をログ出力
|
||
self.log_request(request, request_id, request_timestamp)
|
||
|
||
# リクエスト処理
|
||
try:
|
||
response = self.get_response(request)
|
||
|
||
# レスポンス成功時の処理
|
||
end_time = time.time()
|
||
duration = end_time - start_time
|
||
self.log_response(request, response, request_id, duration)
|
||
|
||
return response
|
||
|
||
except Exception as e:
|
||
# 例外発生時の詳細ログ
|
||
end_time = time.time()
|
||
duration = end_time - start_time
|
||
self.log_exception(request, e, request_id, duration)
|
||
|
||
# 502エラーの場合は詳細なJSONレスポンスを返す
|
||
return JsonResponse({
|
||
"status": "ERROR",
|
||
"message": "Internal Server Error",
|
||
"error_id": request_id,
|
||
"error_type": type(e).__name__,
|
||
"timestamp": request_timestamp.isoformat()
|
||
}, status=502)
|
||
|
||
def log_request(self, request, request_id, timestamp):
|
||
"""リクエスト詳細をログ出力"""
|
||
try:
|
||
logger.info(f"[MIDDLEWARE] 📥 REQUEST_IN - ID: {request_id}")
|
||
logger.info(f"[MIDDLEWARE] Time: {timestamp}")
|
||
logger.info(f"[MIDDLEWARE] Method: {request.method}")
|
||
logger.info(f"[MIDDLEWARE] Path: {request.path}")
|
||
logger.info(f"[MIDDLEWARE] Full URL: {request.build_absolute_uri()}")
|
||
logger.info(f"[MIDDLEWARE] Client IP: {self.get_client_ip(request)}")
|
||
logger.info(f"[MIDDLEWARE] User Agent: {request.META.get('HTTP_USER_AGENT', 'Unknown')[:200]}")
|
||
logger.info(f"[MIDDLEWARE] Content Type: {request.content_type}")
|
||
logger.info(f"[MIDDLEWARE] Content Length: {request.META.get('CONTENT_LENGTH', 'Unknown')}")
|
||
|
||
# start_from_rogapp の場合は特別な処理
|
||
if 'start_from_rogapp' in request.path:
|
||
logger.info(f"[MIDDLEWARE] 🎯 START_API_REQUEST - ID: {request_id}")
|
||
logger.info(f"[MIDDLEWARE] Request body length: {len(request.body) if request.body else 0}")
|
||
logger.info(f"[MIDDLEWARE] Raw body preview: {str(request.body)[:500]}...")
|
||
|
||
# ヘッダーの詳細情報
|
||
for header, value in request.META.items():
|
||
if header.startswith('HTTP_'):
|
||
logger.info(f"[MIDDLEWARE] Header {header}: {value}")
|
||
|
||
except Exception as e:
|
||
logger.error(f"[MIDDLEWARE] Error logging request: {str(e)}")
|
||
|
||
def log_response(self, request, response, request_id, duration):
|
||
"""レスポンス詳細をログ出力"""
|
||
try:
|
||
logger.info(f"[MIDDLEWARE] 📤 RESPONSE_OUT - ID: {request_id}")
|
||
logger.info(f"[MIDDLEWARE] Status: {response.status_code}")
|
||
logger.info(f"[MIDDLEWARE] Duration: {duration:.3f}s")
|
||
logger.info(f"[MIDDLEWARE] Content Type: {response.get('Content-Type', 'Unknown')}")
|
||
|
||
# start_from_rogapp の場合は特別な処理
|
||
if 'start_from_rogapp' in request.path:
|
||
logger.info(f"[MIDDLEWARE] 🎯 START_API_RESPONSE - ID: {request_id}")
|
||
logger.info(f"[MIDDLEWARE] Status Code: {response.status_code}")
|
||
|
||
# レスポンス内容のプレビュー(最初の500文字)
|
||
if hasattr(response, 'content'):
|
||
content_preview = str(response.content)[:500]
|
||
logger.info(f"[MIDDLEWARE] Response preview: {content_preview}...")
|
||
|
||
except Exception as e:
|
||
logger.error(f"[MIDDLEWARE] Error logging response: {str(e)}")
|
||
|
||
def log_exception(self, request, exception, request_id, duration):
|
||
"""例外詳細をログ出力"""
|
||
try:
|
||
logger.error(f"[MIDDLEWARE] 💥 EXCEPTION - ID: {request_id}")
|
||
logger.error(f"[MIDDLEWARE] Duration: {duration:.3f}s")
|
||
logger.error(f"[MIDDLEWARE] Exception Type: {type(exception).__name__}")
|
||
logger.error(f"[MIDDLEWARE] Exception Message: {str(exception)}")
|
||
logger.error(f"[MIDDLEWARE] Request Path: {request.path}")
|
||
logger.error(f"[MIDDLEWARE] Request Method: {request.method}")
|
||
logger.error(f"[MIDDLEWARE] Client IP: {self.get_client_ip(request)}")
|
||
logger.error(f"[MIDDLEWARE] User: {getattr(request, 'user', 'Unknown')}")
|
||
|
||
# start_from_rogapp の場合は特別な処理
|
||
if 'start_from_rogapp' in request.path:
|
||
logger.error(f"[MIDDLEWARE] 🎯 START_API_EXCEPTION - ID: {request_id}")
|
||
logger.error(f"[MIDDLEWARE] Request body: {str(request.body)}")
|
||
|
||
# 完全なトレースバック
|
||
logger.error(f"[MIDDLEWARE] Full traceback:", exc_info=True)
|
||
|
||
except Exception as e:
|
||
logger.error(f"[MIDDLEWARE] Error logging exception: {str(e)}")
|
||
|
||
def get_client_ip(self, request):
|
||
"""クライアントIPを取得"""
|
||
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
||
if x_forwarded_for:
|
||
ip = x_forwarded_for.split(',')[0]
|
||
else:
|
||
ip = request.META.get('REMOTE_ADDR')
|
||
return ip
|
||
|
||
|
||
class APIResponseEnhancementMiddleware:
|
||
"""
|
||
502エラーレスポンスを強化するミドルウェア
|
||
"""
|
||
|
||
def __init__(self, get_response):
|
||
self.get_response = get_response
|
||
|
||
def __call__(self, request):
|
||
try:
|
||
response = self.get_response(request)
|
||
|
||
# 502エラーの場合、より詳細な情報を追加
|
||
if response.status_code == 502:
|
||
request_id = str(uuid.uuid4())[:8]
|
||
logger.error(f"[API_RESPONSE] 502 Bad Gateway detected - ID: {request_id}")
|
||
logger.error(f"[API_RESPONSE] Path: {request.path}")
|
||
logger.error(f"[API_RESPONSE] Method: {request.method}")
|
||
logger.error(f"[API_RESPONSE] Client: {request.META.get('REMOTE_ADDR', 'Unknown')}")
|
||
|
||
# start_from_rogappの場合は追加ログ
|
||
if 'start_from_rogapp' in request.path:
|
||
logger.error(f"[API_RESPONSE] 🎯 START_API_502_ERROR - ID: {request_id}")
|
||
logger.error(f"[API_RESPONSE] Request body: {str(request.body)}")
|
||
|
||
# カスタム502レスポンスを返す
|
||
return JsonResponse({
|
||
"status": "ERROR",
|
||
"message": "スタート処理でサーバーエラーが発生しました",
|
||
"error_id": request_id,
|
||
"timestamp": timezone.now().isoformat(),
|
||
"path": request.path
|
||
}, status=502)
|
||
|
||
return response
|
||
|
||
except Exception as e:
|
||
request_id = str(uuid.uuid4())[:8]
|
||
logger.error(f"[API_RESPONSE] Middleware exception - ID: {request_id}: {str(e)}", exc_info=True)
|
||
|
||
return JsonResponse({
|
||
"status": "ERROR",
|
||
"message": "サーバーエラーが発生しました",
|
||
"error_id": request_id,
|
||
"timestamp": timezone.now().isoformat()
|
||
}, status=500)
|