Files
rogaining_srv/rog/middleware.py
2025-09-02 20:47:04 +09:00

184 lines
8.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
デバッグ用ミドルウェア
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)