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