diff --git a/analyze_nginx_logs.py b/analyze_nginx_logs.py index 391e69d..27241d2 100644 --- a/analyze_nginx_logs.py +++ b/analyze_nginx_logs.py @@ -8,7 +8,138 @@ import re from collections import defaultdict, Counter from datetime import datetime -def analyze_nginx_logs(): +def analyze_provided_logs(): + """ + ユーザーが提供したログデータを分析 + """ + print("🔍 提供されたログデータの分析") + print("=" * 50) + + # ユーザーが提供したログデータ + log_data = """ +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:15 +0000] "GET /api/new-events/ HTTP/1.0" 200 22641 "-" "Dart/3.9 (dart:io)" "202.215.43.20" +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:15 +0000] "GET /api/entry/ HTTP/1.0" 200 11524 "-" "Dart/3.9 (dart:io)" "202.215.43.20" +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:15 +0000] "GET /api/teams/ HTTP/1.0" 200 674 "-" "Dart/3.9 (dart:io)" "202.215.43.20" +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:15 +0000] "GET /api/categories/ HTTP/1.0" 200 2824 "-" "Dart/3.9 (dart:io)" "202.215.43.20" +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:18 +0000] "GET /api/user/current-entry-info/ HTTP/1.0" 200 512 "-" "Dart/3.9 (dart:io)" "202.215.43.20" +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:19 +0000] "PATCH /api/entries/897/update-status/ HTTP/1.0" 200 1281 "-" "Dart/3.9 (dart:io)" "202.215.43.20" +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:31 +0000] "GET /api/entry/ HTTP/1.0" 200 11523 "-" "Dart/3.9 (dart:io)" "202.215.43.20" +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:31 +0000] "GET /api/teams/ HTTP/1.0" 200 674 "-" "Dart/3.9 (dart:io)" "202.215.43.20" +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:31 +0000] "GET /api/new-events/ HTTP/1.0" 200 22641 "-" "Dart/3.9 (dart:io)" "202.215.43.20" +nginx-1 | 172.18.0.1 - - [05/Sep/2025:17:25:31 +0000] "GET /api/categories/ HTTP/1.0" 200 2824 "-" "Dart/3.9 (dart:io)" "202.215.43.20" + """.strip() + + analyze_log_content(log_data.split('\n')) + +def analyze_log_content(lines): + """ + ログ内容を分析する共通関数 + """ + print(f"📊 ログ行数: {len(lines)}") + + # チェックイン・画像関連のエンドポイント + checkin_endpoints = { + '/api/checkinimage/': '画像アップロード', + '/gifuroge/checkin_from_rogapp': 'チェックイン登録', + '/api/bulk_upload_checkin_photos/': '一括写真アップロード', + '/api/user/current-entry-info/': 'ユーザー参加情報', + '/api/entries/': 'エントリー操作', + '/api/new-events/': 'イベント情報', + '/api/teams/': 'チーム情報', + '/api/categories/': 'カテゴリ情報' + } + + # 分析結果 + endpoint_counts = defaultdict(int) + methods = Counter() + status_codes = Counter() + user_agents = Counter() + client_ips = Counter() + dart_requests = 0 + + for line in lines: + if not line.strip(): + continue + + # ログパターンマッチング + # nginx-1 | IP - - [timestamp] "METHOD path HTTP/1.0" status size "-" "user-agent" "real-ip" + match = re.search(r'"(\w+)\s+([^"]+)\s+HTTP/[\d\.]+"\s+(\d+)\s+(\d+)\s+"[^"]*"\s+"([^"]*)"\s+"([^"]*)"', line) + + if match: + method = match.group(1) + path = match.group(2) + status = match.group(3) + size = match.group(4) + user_agent = match.group(5) + real_ip = match.group(6) + + methods[method] += 1 + status_codes[status] += 1 + user_agents[user_agent] += 1 + client_ips[real_ip] += 1 + + # Dartクライアント(スマホアプリ)の検出 + if 'Dart/' in user_agent: + dart_requests += 1 + + # エンドポイント別カウント + for endpoint in checkin_endpoints: + if endpoint in path: + endpoint_counts[endpoint] += 1 + + # 結果表示 + print(f"\n📱 Dartクライアント(スマホアプリ)リクエスト: {dart_requests}件") + + print(f"\n🎯 関連APIエンドポイントの使用状況:") + print("-" * 60) + + found_activity = False + for endpoint, description in checkin_endpoints.items(): + count = endpoint_counts[endpoint] + if count > 0: + print(f"✅ {description:20s} ({endpoint}): {count}回") + found_activity = True + else: + print(f"❌ {description:20s} ({endpoint}): アクセスなし") + + print(f"\n📊 HTTPメソッド別:") + for method, count in methods.most_common(): + print(f" {method}: {count}回") + + print(f"\n📊 ステータスコード別:") + for status, count in status_codes.most_common(): + print(f" HTTP {status}: {count}回") + + print(f"\n📊 User Agent:") + for ua, count in user_agents.most_common(): + ua_short = ua[:50] + "..." if len(ua) > 50 else ua + print(f" {ua_short}: {count}回") + + print(f"\n📊 クライアントIP:") + for ip, count in client_ips.most_common(): + print(f" {ip}: {count}回") + + # チェックイン・画像機能の判定 + print(f"\n🎯 機能使用状況の判定:") + print("-" * 40) + + checkin_active = endpoint_counts['/gifuroge/checkin_from_rogapp'] > 0 + image_upload_active = endpoint_counts['/api/checkinimage/'] > 0 + bulk_upload_active = endpoint_counts['/api/bulk_upload_checkin_photos/'] > 0 + + print(f"チェックイン登録機能: {'✅ 使用中' if checkin_active else '❌ 未使用'}") + print(f"画像アップロード機能: {'✅ 使用中' if image_upload_active else '❌ 未使用'}") + print(f"一括写真アップロード機能: {'✅ 使用中' if bulk_upload_active else '❌ 未使用'}") + print(f"スマホアプリ(Dartクライアント): {'✅ アクティブ' if dart_requests > 0 else '❌ 非アクティブ'}") + + if dart_requests > 0: + print(f"\n📱 スマホアプリの動作状況:") + print(f" • アプリは正常に動作している") + print(f" • イベント情報、エントリー情報、チーム情報を取得中") + print(f" • エントリーステータスの更新も実行中") + print(f" • ただし、チェックインや画像アップロードは確認されていない") + + return found_activity """ nginxログを分析してチェックイン・画像関連の活動を確認 """ @@ -20,8 +151,7 @@ def analyze_nginx_logs(): result = subprocess.run( ['docker-compose', 'logs', '--tail=500', 'nginx'], capture_output=True, - text=True, - cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv' + text=True ) if result.returncode != 0: @@ -204,9 +334,50 @@ def get_status_emoji(status_code): else: return '❓' -def main(): +def analyze_nginx_logs(): + """ + Dockerコンテナからnginxログを取得・分析 + """ + print("🔍 Dockerからnginxログを取得中...") + print("=" * 50) + try: - analyze_nginx_logs() + # docker-compose logsでnginxのログを取得 + result = subprocess.run( + ['docker-compose', 'logs', '--tail=100', 'nginx'], + capture_output=True, + text=True, + check=True + ) + + lines = result.stdout.split('\n') + analyze_log_content(lines) + + except subprocess.CalledProcessError as e: + print(f"❌ ログ取得エラー: {e}") + print(f"stderr: {e.stderr}") + print("\n💡 Dockerコンテナが起動していることを確認してください") + print(" docker-compose ps") + except FileNotFoundError: + print("❌ docker-composeコマンドが見つかりません") + print("💡 Dockerがインストールされていることを確認してください") + + +def main(): + print("🚀 スマホアプリのnginxログ解析ツール") + print("=" * 50) + + choice = input("\n分析方法を選択してください:\n1. Dockerからログを取得\n2. 提供されたログデータを分析\n選択 (1/2): ") + + try: + if choice == "1": + analyze_nginx_logs() + elif choice == "2": + analyze_provided_logs() + else: + print("無効な選択です。提供されたログデータを分析します。") + analyze_provided_logs() + print(f"\n✅ 分析完了") print(f"\n💡 結論:") print(f" ログから、チェックイン・画像アップロード機能の実際の使用状況を確認できます") @@ -214,6 +385,8 @@ def main(): except Exception as e: print(f"❌ エラー: {e}") + import traceback + traceback.print_exc() if __name__ == '__main__': main() diff --git a/debug_502_error.py b/debug_502_error.py new file mode 100644 index 0000000..1271d13 --- /dev/null +++ b/debug_502_error.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python3 +""" +502エラー調査スクリプト: checkin_from_rogappエンドポイントのデバッグ +""" + +import subprocess +import time +import requests +import json +from datetime import datetime + +def test_checkin_endpoint(): + """ + checkin_from_rogappエンドポイントをテストして502エラーを再現 + """ + print("🔍 502エラー調査: checkin_from_rogappエンドポイント") + print("=" * 60) + + # テストデータ + test_data = { + "event_code": "fc_gifu_2025", + "team_name": "テストチーム", + "cp_number": "1", + "image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABA...", # 短縮版 + "buy_flag": False, + "gps_coordinates": { + "latitude": 35.6762, + "longitude": 139.6503, + "accuracy": 5.0, + "timestamp": datetime.now().isoformat() + }, + "camera_metadata": { + "capture_time": datetime.now().isoformat(), + "device_info": "debug_script" + } + } + + # URLを構築 + base_url = "http://localhost:8100" + checkin_url = f"{base_url}/gifuroge/checkin_from_rogapp" + + print(f"🎯 テスト対象URL: {checkin_url}") + print(f"📊 テストデータ: {json.dumps({k: v if k != 'image' else '[BASE64_DATA]' for k, v in test_data.items()}, indent=2, ensure_ascii=False)}") + + try: + print(f"\n🚀 POSTリクエスト送信中...") + + # リクエスト送信 + response = requests.post( + checkin_url, + json=test_data, + headers={ + 'Content-Type': 'application/json', + 'User-Agent': 'Debug-Script/1.0' + }, + timeout=30 + ) + + print(f"📥 レスポンス受信:") + print(f" ステータスコード: {response.status_code}") + print(f" ヘッダー: {dict(response.headers)}") + + if response.status_code == 502: + print(f"❌ 502 Bad Gateway エラーを確認しました") + print(f" レスポンステキスト: {response.text}") + return False + elif response.status_code == 200: + print(f"✅ 正常レスポンス") + print(f" レスポンスデータ: {response.json()}") + return True + else: + print(f"⚠️ 予期しないステータスコード: {response.status_code}") + print(f" レスポンステキスト: {response.text}") + return False + + except requests.exceptions.ConnectionError as e: + print(f"❌ 接続エラー: {e}") + return False + except requests.exceptions.Timeout as e: + print(f"❌ タイムアウトエラー: {e}") + return False + except Exception as e: + print(f"❌ その他のエラー: {e}") + return False + +def monitor_logs_during_test(): + """ + テスト実行中のログを監視 + """ + print(f"\n🔍 ログ監視開始") + print("-" * 40) + + try: + # アプリケーションログを監視 + result = subprocess.run( + ['docker', 'compose', 'logs', '--tail=20', '--follow', 'app'], + cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', + capture_output=True, + text=True, + timeout=10 + ) + + print(f"📋 アプリケーションログ:") + print(result.stdout) + + if result.stderr: + print(f"⚠️ エラー出力:") + print(result.stderr) + + except subprocess.TimeoutExpired: + print(f"⏰ ログ監視タイムアウト(正常)") + except Exception as e: + print(f"❌ ログ監視エラー: {e}") + +def check_docker_services(): + """ + Dockerサービスの状態確認 + """ + print(f"\n🐳 Dockerサービス状態確認") + print("-" * 40) + + try: + # サービス状態確認 + result = subprocess.run( + ['docker', 'compose', 'ps'], + cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', + capture_output=True, + text=True, + check=True + ) + + print(f"📊 サービス状態:") + print(result.stdout) + + # ヘルスチェック + health_result = subprocess.run( + ['docker', 'compose', 'exec', 'app', 'python', 'manage.py', 'check'], + cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', + capture_output=True, + text=True + ) + + if health_result.returncode == 0: + print(f"✅ Djangoアプリケーション: 正常") + print(health_result.stdout) + else: + print(f"❌ Djangoアプリケーション: エラー") + print(health_result.stderr) + + except subprocess.CalledProcessError as e: + print(f"❌ Dockerコマンドエラー: {e}") + print(f"stderr: {e.stderr}") + except Exception as e: + print(f"❌ その他のエラー: {e}") + +def analyze_nginx_config(): + """ + nginx設定の確認 + """ + print(f"\n🌐 nginx設定確認") + print("-" * 40) + + try: + # nginx設定テスト + result = subprocess.run( + ['docker', 'compose', 'exec', 'nginx', 'nginx', '-t'], + cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', + capture_output=True, + text=True + ) + + if result.returncode == 0: + print(f"✅ nginx設定: 正常") + print(result.stdout) + else: + print(f"❌ nginx設定: エラー") + print(result.stderr) + + # 最近のnginxエラーログ + error_log_result = subprocess.run( + ['docker', 'compose', 'logs', '--tail=10', 'nginx'], + cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', + capture_output=True, + text=True + ) + + print(f"\n📋 nginx最近のログ:") + print(error_log_result.stdout) + + except Exception as e: + print(f"❌ nginx確認エラー: {e}") + +def main(): + """ + メイン実行関数 + """ + print(f"🚨 502 Bad Gateway エラー調査ツール") + print(f"時刻: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") + print("=" * 60) + + # 1. Dockerサービス状態確認 + check_docker_services() + + # 2. nginx設定確認 + analyze_nginx_config() + + # 3. エンドポイントテスト + print(f"\n🎯 エンドポイントテスト実行") + print("-" * 40) + + success = test_checkin_endpoint() + + # 4. ログ確認 + monitor_logs_during_test() + + # 結果まとめ + print(f"\n📊 調査結果まとめ") + print("=" * 60) + + if success: + print(f"✅ checkin_from_rogappエンドポイントは正常に動作しています") + print(f"💡 502エラーは一時的な問題だった可能性があります") + else: + print(f"❌ 502エラーを確認しました") + print(f"💡 次の対策が必要です:") + print(f" 1. アプリケーションのエラーログを詳細確認") + print(f" 2. データベース接続状態の確認") + print(f" 3. メモリ使用量やリソース状況の確認") + print(f" 4. 依存関係やモジュールの問題確認") + +if __name__ == "__main__": + main()