#!/usr/bin/env python3 """ スマホアプリエラー監視ツール: リアルタイムで400エラーを監視 """ import subprocess import re import time from datetime import datetime import json def monitor_app_errors(): """ スマホアプリの400エラーをリアルタイム監視 """ print("🔍 スマホアプリエラー監視開始") print("=" * 60) print("Ctrl+C で停止") print() try: # docker compose logs --follow で継続監視 process = subprocess.Popen( ['docker', 'compose', 'logs', '--follow', 'app'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1, universal_newlines=True ) error_patterns = { 'checkin_400': re.compile(r'Bad Request.*checkin_from_rogapp', re.I), 'member_400': re.compile(r'Bad Request.*members', re.I), 'team_400': re.compile(r'Bad Request.*teams', re.I), 'validation_error': re.compile(r'Validation error.*({.*})', re.I), 'checkin_start_error': re.compile(r'Team has not started yet.*team_name: \'([^\']+)\'.*cp_number: (\d+)', re.I), 'dart_request': re.compile(r'Dart/\d+\.\d+.*"([A-Z]+)\s+([^"]+)".*(\d{3})', re.I) } print(f"🎯 監視対象パターン:") for name, pattern in error_patterns.items(): print(f" • {name}") print() while True: line = process.stdout.readline() if not line: break timestamp = datetime.now().strftime("%H:%M:%S") # Dartクライアント(スマホアプリ)のリクエスト監視 dart_match = error_patterns['dart_request'].search(line) if dart_match and 'Dart/' in line: method = dart_match.group(1) path = dart_match.group(2) status = dart_match.group(3) if status.startswith('4'): # 4xx エラー print(f"❌ [{timestamp}] スマホアプリエラー: {method} {path} → HTTP {status}") elif status.startswith('2'): # 2xx 成功 if any(keyword in path.lower() for keyword in ['checkin', 'teams', 'members']): print(f"✅ [{timestamp}] スマホアプリ成功: {method} {path} → HTTP {status}") # チェックインスタートエラー監視 start_error_match = error_patterns['checkin_start_error'].search(line) if start_error_match: team_name = start_error_match.group(1) cp_number = start_error_match.group(2) print(f"⚠️ [{timestamp}] チェックインエラー: チーム'{team_name}'がCP{cp_number}でスタート前チェックイン試行") print(f" 💡 解決策: 先にstart_from_rogappでスタート処理が必要") # バリデーションエラー監視 validation_match = error_patterns['validation_error'].search(line) if validation_match: try: error_details = validation_match.group(1) print(f"❌ [{timestamp}] バリデーションエラー: {error_details}") if 'date_of_birth' in error_details: print(f" 💡 date_of_birthフィールドの問題 - MemberCreationSerializerを確認") except: print(f"❌ [{timestamp}] バリデーションエラー詳細を解析できませんでした") # 一般的な400エラー監視 for pattern_name, pattern in error_patterns.items(): if pattern_name in ['dart_request', 'checkin_start_error', 'validation_error']: continue if pattern.search(line): print(f"❌ [{timestamp}] {pattern_name}: {line.strip()}") except KeyboardInterrupt: print(f"\n\n🛑 監視を停止しました") process.terminate() except Exception as e: print(f"❌ 監視エラー: {e}") if 'process' in locals(): process.terminate() def analyze_current_issues(): """ 現在の問題を分析 """ print("📊 現在の問題分析") print("-" * 40) try: # 最近のエラーログを分析 result = subprocess.run( ['docker', 'compose', 'logs', '--tail=100', 'app'], capture_output=True, text=True ) lines = result.stdout.split('\n') # チェックインエラーの分析 checkin_errors = [] validation_errors = [] for line in lines: if 'Team has not started yet' in line: match = re.search(r'team_name: \'([^\']+)\'.*cp_number: (\d+)', line) if match: checkin_errors.append((match.group(1), match.group(2))) if 'Validation error' in line and 'date_of_birth' in line: validation_errors.append(line) print(f"🔍 分析結果:") print(f" • チェックインスタートエラー: {len(checkin_errors)}件") for team, cp in checkin_errors[-3:]: # 最新3件 print(f" - チーム'{team}' → CP{cp}") print(f" • date_of_birthバリデーションエラー: {len(validation_errors)}件") if checkin_errors: print(f"\n💡 推奨対策:") print(f" 1. スマホアプリでスタート処理を実行") print(f" 2. start_from_rogapp API の正常動作確認") if validation_errors: print(f" 3. MemberCreationSerializerの再確認") except Exception as e: print(f"❌ 分析エラー: {e}") def main(): """ メイン関数 """ print("📱 スマホアプリエラー監視ツール") print("=" * 60) choice = input("選択してください:\n1. リアルタイム監視\n2. 現在の問題分析\n選択 (1/2): ") if choice == "1": monitor_app_errors() elif choice == "2": analyze_current_issues() else: print("無効な選択です") if __name__ == "__main__": main()