Add log on APIs

This commit is contained in:
2025-09-02 17:01:40 +09:00
parent c95c8713d4
commit d6b40bd0f8
2 changed files with 136 additions and 48 deletions

View File

@ -4,7 +4,7 @@ from datetime import datetime, timezone
from rest_framework.decorators import api_view from rest_framework.decorators import api_view
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status
from rog.models import Location2025, NewEvent2, Entry, GpsLog from rog.models import Location2025, NewEvent2, Entry, GpsLog, TeamStart, TeamGoal
import logging import logging
import uuid import uuid
import os import os
@ -42,18 +42,24 @@ def remove_checkin_from_rogapp(request):
- team_name: チーム名 - team_name: チーム名
- cp_number: チェックポイント番号 - cp_number: チェックポイント番号
""" """
logger.info("remove_checkin_from_rogapp called") # ログ用のリクエストID生成
request_id = uuid.uuid4().hex[:8]
request_time = timezone.now()
client_ip = request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR', 'Unknown'))
user_info = f"{request.user.username}({request.user.id})" if request.user.is_authenticated else "Anonymous"
# リクエストからパラメータを取得 # リクエストからパラメータを取得
event_code = request.data.get('event_code') event_code = request.data.get('event_code')
team_name = request.data.get('team_name') team_name = request.data.get('team_name')
cp_number = request.data.get('cp_number') cp_number = request.data.get('cp_number')
logger.info(f"[REMOVE_CHECKIN] 🗑️ API call started - ID: {request_id}, event_code: '{event_code}', team_name: '{team_name}', cp_number: {cp_number}, Client IP: {client_ip}, User: {user_info}")
logger.debug(f"Parameters: event_code={event_code}, team_name={team_name}, cp_number={cp_number}") logger.debug(f"Parameters: event_code={event_code}, team_name={team_name}, cp_number={cp_number}")
# パラメータ検証 # パラメータ検証
if not all([event_code, team_name, cp_number]): if not all([event_code, team_name, cp_number]):
logger.warning("Missing required parameters") logger.error(f"[REMOVE_CHECKIN] ❌ Missing required parameters - ID: {request_id}, event_code: '{event_code}', team_name: '{team_name}', cp_number: {cp_number}, Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "イベントコード、チーム名、チェックポイント番号が必要です" "message": "イベントコード、チーム名、チェックポイント番号が必要です"
@ -63,12 +69,14 @@ def remove_checkin_from_rogapp(request):
# イベントの存在確認 # イベントの存在確認
event = NewEvent2.objects.filter(event_name=event_code).first() event = NewEvent2.objects.filter(event_name=event_code).first()
if not event: if not event:
logger.warning(f"Event not found: {event_code}") logger.error(f"[REMOVE_CHECKIN] ❌ Event not found - ID: {request_id}, event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたイベントが見つかりません" "message": "指定されたイベントが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[REMOVE_CHECKIN] ✅ Event found - ID: {request_id}, event: '{event.event_name}', event_id: {event.id}")
# チームの存在確認 # チームの存在確認
entry = Entry.objects.filter( entry = Entry.objects.filter(
event=event, event=event,
@ -76,12 +84,14 @@ def remove_checkin_from_rogapp(request):
).first() ).first()
if not entry: if not entry:
logger.warning(f"Team not found: {team_name} in event: {event_code}") logger.error(f"[REMOVE_CHECKIN] ❌ Team not found - ID: {request_id}, team_name: '{team_name}', event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたチームが見つかりません" "message": "指定されたチームが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[REMOVE_CHECKIN] ✅ Team found - ID: {request_id}, team_name: '{team_name}', zekken: {entry.zekken_number}, entry_id: {entry.id}")
# 対象のチェックポイント記録を検索 # 対象のチェックポイント記録を検索
checkpoint = GpsLog.objects.filter( checkpoint = GpsLog.objects.filter(
entry=entry, entry=entry,
@ -89,18 +99,33 @@ def remove_checkin_from_rogapp(request):
).first() ).first()
if not checkpoint: if not checkpoint:
logger.warning(f"Checkpoint {cp_number} not found for team: {team_name}") logger.warning(f"[REMOVE_CHECKIN] ⚠️ Checkpoint not found - ID: {request_id}, team_name: '{team_name}', zekken: {entry.zekken_number}, cp_number: {cp_number}, Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたチェックポイント記録が見つかりません" "message": "指定されたチェックポイント記録が見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[REMOVE_CHECKIN] ✅ Checkpoint found for removal - ID: {request_id}, checkpoint_id: {checkpoint.id}, checkin_time: {checkpoint.checkin_time}, has_image: {bool(checkpoint.image_address)}")
# チェックポイント記録を削除 # チェックポイント記録を削除
checkin_time = checkpoint.checkin_time checkin_time = checkpoint.checkin_time
checkpoint_id = checkpoint.id checkpoint_id = checkpoint.id
image_address = checkpoint.image_address
with transaction.atomic():
# 拡張情報も一緒に削除(存在する場合)
try:
from ..models import CheckinExtended
extended_info = CheckinExtended.objects.filter(gpslog=checkpoint).first()
if extended_info:
extended_info.delete()
logger.info(f"[REMOVE_CHECKIN] ✅ Extended info also removed - ID: {request_id}, checkpoint_id: {checkpoint_id}")
except Exception as ext_error:
logger.warning(f"[REMOVE_CHECKIN] ⚠️ Failed to remove extended info - ID: {request_id}, Error: {ext_error}")
checkpoint.delete() checkpoint.delete()
logger.info(f"Successfully removed CP {cp_number} for team: {team_name} in event: {event_code}") logger.success(f"[REMOVE_CHECKIN] 🎉 Successfully removed checkpoint - ID: {request_id}, team_name: '{team_name}', zekken: {entry.zekken_number}, cp_number: {cp_number}, checkpoint_id: {checkpoint_id}, had_image: {bool(image_address)}, Client IP: {client_ip}")
return Response({ return Response({
"status": "OK", "status": "OK",
@ -112,7 +137,7 @@ def remove_checkin_from_rogapp(request):
}) })
except Exception as e: except Exception as e:
logger.error(f"Error in remove_checkin_from_rogapp: {str(e)}") logger.error(f"[REMOVE_CHECKIN] 💥 ERROR - ID: {request_id}, team_name: '{team_name}', cp_number: {cp_number}, Client IP: {client_ip}, Error: {str(e)}", exc_info=True)
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "サーバーエラーが発生しました" "message": "サーバーエラーが発生しました"
@ -149,17 +174,22 @@ def start_checkin(request):
- event: イベントコード - event: イベントコード
- zekken: ゼッケン番号 - zekken: ゼッケン番号
""" """
logger.info("start_checkin called") # リクエスト詳細情報を取得
client_ip = request.META.get('REMOTE_ADDR', 'Unknown')
user_agent = request.META.get('HTTP_USER_AGENT', 'Unknown')
user_info = request.user.email if request.user.is_authenticated else 'Anonymous'
logger.info(f"[ADMIN_START] API called - Client IP: {client_ip}, User: {user_info}")
# リクエストからパラメータを取得 # リクエストからパラメータを取得
event_code = request.query_params.get('event') event_code = request.query_params.get('event')
zekken_number = request.query_params.get('zekken') zekken_number = request.query_params.get('zekken')
logger.debug(f"Parameters: event={event_code}, zekken={zekken_number}") logger.info(f"[ADMIN_START] Request parameters - event_code: {event_code}, zekken_number: {zekken_number}, user_agent: {user_agent[:100]}")
# パラメータ検証 # パラメータ検証
if not all([event_code, zekken_number]): if not all([event_code, zekken_number]):
logger.warning("Missing required parameters") logger.warning(f"[ADMIN_START] Missing required parameters - event_code: {event_code}, zekken_number: {zekken_number}, Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "イベントコードとゼッケン番号が必要です" "message": "イベントコードとゼッケン番号が必要です"
@ -251,18 +281,23 @@ def add_checkin(request):
- zekken: ゼッケン番号 - zekken: ゼッケン番号
- list: カンマ区切りのチェックポイント番号リスト - list: カンマ区切りのチェックポイント番号リスト
""" """
logger.info("add_checkin called") # ログ用のリクエストID生成
request_id = uuid.uuid4().hex[:8]
request_time = timezone.now()
client_ip = request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR', 'Unknown'))
user_agent = request.META.get('HTTP_USER_AGENT', 'Unknown')
user_info = f"{request.user.username}({request.user.id})" if request.user.is_authenticated else "Anonymous"
# リクエストからパラメータを取得 # リクエストからパラメータを取得
event_code = request.query_params.get('event') event_code = request.query_params.get('event')
zekken_number = request.query_params.get('zekken') zekken_number = request.query_params.get('zekken')
cp_list_string = request.query_params.get('list') cp_list_string = request.query_params.get('list')
logger.debug(f"Parameters: event={event_code}, zekken={zekken_number}, list={cp_list_string}") logger.info(f"[ADMIN_CHECKIN] 📝 Bulk checkin API call started - ID: {request_id}, event_code: '{event_code}', zekken_number: {zekken_number}, cp_list: '{cp_list_string}', Client IP: {client_ip}, User: {user_info}, User-Agent: {user_agent[:100]}")
# パラメータ検証 # パラメータ検証
if not all([event_code, zekken_number, cp_list_string]): if not all([event_code, zekken_number, cp_list_string]):
logger.warning("Missing required parameters") logger.error(f"[ADMIN_CHECKIN] ❌ Missing required parameters - ID: {request_id}, event_code: '{event_code}', zekken_number: {zekken_number}, cp_list: '{cp_list_string}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "イベントコード、ゼッケン番号、チェックポイントリストが必要です" "message": "イベントコード、ゼッケン番号、チェックポイントリストが必要です"
@ -272,12 +307,14 @@ def add_checkin(request):
# イベントの存在確認 # イベントの存在確認
event = NewEvent2.objects.filter(event_name=event_code).first() event = NewEvent2.objects.filter(event_name=event_code).first()
if not event: if not event:
logger.warning(f"Event not found: {event_code}") logger.error(f"[ADMIN_CHECKIN] ❌ Event not found - ID: {request_id}, event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたイベントが見つかりません" "message": "指定されたイベントが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[ADMIN_CHECKIN] ✅ Event found - ID: {request_id}, event: '{event.event_name}', event_id: {event.id}")
# チームの存在確認 # チームの存在確認
entry = Entry.objects.filter( entry = Entry.objects.filter(
event=event, event=event,
@ -285,19 +322,21 @@ def add_checkin(request):
).first() ).first()
if not entry: if not entry:
logger.warning(f"Team with zekken number {zekken_number} not found in event: {event_code}") logger.error(f"[ADMIN_CHECKIN] ❌ Team not found - ID: {request_id}, zekken: {zekken_number}, event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたゼッケン番号のチームが見つかりません" "message": "指定されたゼッケン番号のチームが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[ADMIN_CHECKIN] ✅ Team found - ID: {request_id}, team_name: '{entry.team_name}', zekken: {zekken_number}, entry_id: {entry.id}")
# チームがスタートしているか確認(オプション) # チームがスタートしているか確認(オプション)
if not hasattr(entry, 'start_info'): if not hasattr(entry, 'start_info'):
# スタート情報がない場合は自動的にスタートさせる # スタート情報がない場合は自動的にスタートさせる
# 注意: 管理画面からの操作なので、自動スタートを許可 # 注意: 管理画面からの操作なので、自動スタートを許可
from rog.models import TeamStart from rog.models import TeamStart
TeamStart.objects.create(entry=entry, start_time=timezone.now()) TeamStart.objects.create(entry=entry, start_time=timezone.now())
logger.info(f"Auto-started team {entry.team_name} (zekken: {zekken_number})") logger.info(f"[ADMIN_CHECKIN] ✅ Auto-started team - ID: {request_id}, team_name: '{entry.team_name}', zekken: {zekken_number}")
# チェックポイントリストを解析 # チェックポイントリストを解析
cp_list = [cp.strip() for cp in cp_list_string.split(',') if cp.strip()] cp_list = [cp.strip() for cp in cp_list_string.split(',') if cp.strip()]

View File

@ -2,13 +2,18 @@
from rest_framework.decorators import api_view from rest_framework.decorators import api_view
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status
from rog.models import NewEvent2, Entry, Location2025 from rog.models import NewEvent2, Entry, Location2025, TeamStart, TeamGoal
from rog.models import GpsLog from rog.models import GpsLog
import logging import logging
from django.db.models import F, Q from django.db.models import F, Q
from django.conf import settings from django.conf import settings
import os import os
from urllib.parse import urljoin from urllib.parse import urljoin
from django.db import transaction
from django.utils import timezone
from datetime import datetime
import uuid
import time
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -225,17 +230,24 @@ def start_from_rogapp(request):
- event_code: イベントコード - event_code: イベントコード
- team_name: チーム名 - team_name: チーム名
""" """
logger.info("start_from_rogapp called") # リクエスト詳細情報を取得
client_ip = request.META.get('REMOTE_ADDR', 'Unknown')
user_agent = request.META.get('HTTP_USER_AGENT', 'Unknown')
user_info = request.user.email if request.user.is_authenticated else 'Anonymous'
request_time = timezone.now()
request_id = str(uuid.uuid4())[:8]
logger.info(f"[COMPETITION_START] 🏁 API Request Started - ID: {request_id}, Time: {request_time}, Client IP: {client_ip}, User: {user_info}")
# リクエストからパラメータを取得 # リクエストからパラメータを取得
event_code = request.data.get('event_code') event_code = request.data.get('event_code')
team_name = request.data.get('team_name') team_name = request.data.get('team_name')
logger.debug(f"Parameters: event_code={event_code}, team_name={team_name}") logger.info(f"[COMPETITION_START] Request parameters - ID: {request_id}, event_code: '{event_code}', team_name: '{team_name}', user_agent: '{user_agent[:100]}'")
# パラメータ検証 # パラメータ検証
if not all([event_code, team_name]): if not all([event_code, team_name]):
logger.warning("Missing required parameters") logger.warning(f"[COMPETITION_START] ❌ Missing required parameters - ID: {request_id}, event_code: '{event_code}', team_name: '{team_name}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "イベントコードとチーム名が必要です" "message": "イベントコードとチーム名が必要です"
@ -245,12 +257,14 @@ def start_from_rogapp(request):
# イベントの存在確認 # イベントの存在確認
event = NewEvent2.objects.filter(event_name=event_code).first() event = NewEvent2.objects.filter(event_name=event_code).first()
if not event: if not event:
logger.warning(f"Event not found: {event_code}") logger.warning(f"[COMPETITION_START] ❌ Event not found - ID: {request_id}, event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたイベントが見つかりません" "message": "指定されたイベントが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[COMPETITION_START] ✅ Event found - ID: {request_id}, Event ID: {event.id}, Name: '{event.event_name}', Start: {event.start_datetime}, End: {event.end_datetime}")
# チームの存在確認 # チームの存在確認
entry = Entry.objects.filter( entry = Entry.objects.filter(
event=event, event=event,
@ -258,15 +272,17 @@ def start_from_rogapp(request):
).first() ).first()
if not entry: if not entry:
logger.warning(f"Team not found: {team_name} in event: {event_code}") logger.warning(f"[COMPETITION_START] ❌ Team not found - ID: {request_id}, team_name: '{team_name}', event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたチームが見つかりません" "message": "指定されたチームが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[COMPETITION_START] ✅ Team found - ID: {request_id}, Entry ID: {entry.id}, Team: '{team_name}', Zekken: {entry.zekken_number}, Category: '{entry.category.category_name if entry.category else 'N/A'}', Owner: '{entry.owner.email if entry.owner else 'N/A'}')")
# 既にスタート済みかチェック # 既にスタート済みかチェック
if hasattr(entry, 'start_info'): if hasattr(entry, 'start_info'):
logger.warning(f"Team {team_name} already started at {entry.start_info.start_time}") logger.warning(f"[COMPETITION_START] ⚠️ Team already started - ID: {request_id}, team_name: '{team_name}', zekken: {entry.zekken_number}, start_time: {entry.start_info.start_time}, Client IP: {client_ip}")
return Response({ return Response({
"status": "WARNING", "status": "WARNING",
"message": "このチームは既にスタートしています", "message": "このチームは既にスタートしています",
@ -281,7 +297,10 @@ def start_from_rogapp(request):
start_time=timezone.now() start_time=timezone.now()
) )
logger.info(f"Team {team_name} started at {start_info.start_time}") # 統計情報取得
total_checkpoints = Location2025.objects.filter(event=event).count() if hasattr(Location2025, 'event') else 0
logger.info(f"[COMPETITION_START] 🎉 SUCCESS - ID: {request_id}, Team: '{team_name}', Zekken: {entry.zekken_number}, Event: '{event_code}', Start Time: {start_info.start_time}, Total CPs Available: {total_checkpoints}, Client IP: {client_ip}, User: {user_info}")
return Response({ return Response({
"status": "OK", "status": "OK",
@ -292,7 +311,7 @@ def start_from_rogapp(request):
}) })
except Exception as e: except Exception as e:
logger.error(f"Error in start_from_rogapp: {str(e)}") logger.error(f"[COMPETITION_START] 💥 CRITICAL ERROR - ID: {request_id}, team_name: '{team_name}', event_code: '{event_code}', Client IP: {client_ip}, Error: {str(e)}", exc_info=True)
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "サーバーエラーが発生しました" "message": "サーバーエラーが発生しました"
@ -333,7 +352,14 @@ def checkin_from_rogapp(request):
- gps_coordinates: GPS座標情報 (新規) - gps_coordinates: GPS座標情報 (新規)
- camera_metadata: カメラメタデータ (新規) - camera_metadata: カメラメタデータ (新規)
""" """
logger.info("checkin_from_rogapp called") # リクエスト詳細情報を取得
client_ip = request.META.get('REMOTE_ADDR', 'Unknown')
user_agent = request.META.get('HTTP_USER_AGENT', 'Unknown')
user_info = request.user.email if request.user.is_authenticated else 'Anonymous'
request_time = timezone.now()
request_id = str(uuid.uuid4())[:8]
logger.info(f"[CHECKIN] 📍 API Request Started - ID: {request_id}, Time: {request_time}, Client IP: {client_ip}, User: {user_info}")
# リクエストからパラメータを取得 # リクエストからパラメータを取得
event_code = request.data.get('event_code') event_code = request.data.get('event_code')
@ -346,12 +372,19 @@ def checkin_from_rogapp(request):
gps_coordinates = request.data.get('gps_coordinates', {}) gps_coordinates = request.data.get('gps_coordinates', {})
camera_metadata = request.data.get('camera_metadata', {}) camera_metadata = request.data.get('camera_metadata', {})
logger.debug(f"Parameters: event_code={event_code}, team_name={team_name}, " logger.info(f"[CHECKIN] Request parameters - ID: {request_id}, event_code: '{event_code}', team_name: '{team_name}', cp_number: {cp_number}, has_image: {bool(image_url)}, image_size: {len(image_url) if image_url else 0} chars, buy_flag: {buy_flag}, user_agent: '{user_agent[:100]}'")
f"cp_number={cp_number}, image={image_url}")
# GPS座標情報をログに記録
if gps_coordinates:
logger.info(f"[CHECKIN] GPS coordinates - ID: {request_id}, lat: {gps_coordinates.get('latitude')}, lng: {gps_coordinates.get('longitude')}, accuracy: {gps_coordinates.get('accuracy')}m, timestamp: {gps_coordinates.get('timestamp')}")
# カメラメタデータをログに記録
if camera_metadata:
logger.info(f"[CHECKIN] Camera metadata - ID: {request_id}, capture_time: {camera_metadata.get('capture_time')}, device: {camera_metadata.get('device_info')}")
# パラメータ検証 # パラメータ検証
if not all([event_code, team_name, cp_number]): if not all([event_code, team_name, cp_number]):
logger.warning("Missing required parameters") logger.warning(f"[CHECKIN] ❌ Missing required parameters - ID: {request_id}, event_code: '{event_code}', team_name: '{team_name}', cp_number: {cp_number}, Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "イベントコード、チーム名、チェックポイント番号が必要です" "message": "イベントコード、チーム名、チェックポイント番号が必要です"
@ -361,12 +394,14 @@ def checkin_from_rogapp(request):
# イベントの存在確認 # イベントの存在確認
event = NewEvent2.objects.filter(event_name=event_code).first() event = NewEvent2.objects.filter(event_name=event_code).first()
if not event: if not event:
logger.warning(f"Event not found: {event_code}") logger.warning(f"[CHECKIN] ❌ Event not found - ID: {request_id}, event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたイベントが見つかりません" "message": "指定されたイベントが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[CHECKIN] ✅ Event found - ID: {request_id}, Event ID: {event.id}, Name: '{event.event_name}'")
# チームの存在確認 # チームの存在確認
entry = Entry.objects.filter( entry = Entry.objects.filter(
event=event, event=event,
@ -374,15 +409,17 @@ def checkin_from_rogapp(request):
).first() ).first()
if not entry: if not entry:
logger.warning(f"Team not found: {team_name} in event: {event_code}") logger.warning(f"[CHECKIN] ❌ Team not found - ID: {request_id}, team_name: '{team_name}', event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたチームが見つかりません" "message": "指定されたチームが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[CHECKIN] ✅ Team found - ID: {request_id}, Entry ID: {entry.id}, Team: '{team_name}', Zekken: {entry.zekken_number}, Category: '{entry.category.category_name if entry.category else 'N/A'}'")
# チームがスタートしているか確認 # チームがスタートしているか確認
if not hasattr(entry, 'start_info'): if not hasattr(entry, 'start_info'):
logger.warning(f"Team {team_name} has not started yet") logger.warning(f"[CHECKIN] ❌ Team has not started yet - ID: {request_id}, team_name: '{team_name}', zekken: {entry.zekken_number}, cp_number: {cp_number}, Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "このチームはまだスタートしていません。先にスタート処理を行ってください。" "message": "このチームはまだスタートしていません。先にスタート処理を行ってください。"
@ -395,7 +432,7 @@ def checkin_from_rogapp(request):
).first() ).first()
if existing_checkpoint: if existing_checkpoint:
logger.warning(f"Checkpoint {cp_number} already registered for team: {team_name}") logger.warning(f"[CHECKIN] ⚠️ Checkpoint already registered - ID: {request_id}, team_name: '{team_name}', zekken: {entry.zekken_number}, cp_number: {cp_number}, previous_checkin_time: {existing_checkpoint.checkin_time}, Client IP: {client_ip}")
return Response({ return Response({
"status": "WARNING", "status": "WARNING",
"message": "このチェックポイントは既に登録されています", "message": "このチェックポイントは既に登録されています",
@ -410,8 +447,12 @@ def checkin_from_rogapp(request):
event=event, event=event,
cp_number=cp_number cp_number=cp_number
).first() ).first()
except: if event_cp:
logger.info(f"Location2025 model not available or CP {cp_number} not defined for event") logger.info(f"[CHECKIN] ✅ Event checkpoint found - ID: {request_id}, CP: {cp_number}, Name: '{event_cp.cp_name}', Points: {getattr(event_cp, 'checkin_point', 'N/A')}, Category: '{event_cp.category}'")
else:
logger.info(f"[CHECKIN] ⚠️ Event checkpoint not defined - ID: {request_id}, CP: {cp_number}")
except Exception as e:
logger.warning(f"[CHECKIN] Location2025 model issue - ID: {request_id}, CP: {cp_number}, Error: {e}")
# トランザクション開始 # トランザクション開始
with transaction.atomic(): with transaction.atomic():
@ -424,8 +465,6 @@ def checkin_from_rogapp(request):
is_service_checked=event_cp.is_service_cp if event_cp else False is_service_checked=event_cp.is_service_cp if event_cp else False
) )
logger.info(f"Successfully registered CP {cp_number} for team: {team_name} in event: {event_code}")
# 獲得ポイントの計算イベントCPが定義されている場合 # 獲得ポイントの計算イベントCPが定義されている場合
point_value = event_cp.cp_point if event_cp else 0 point_value = event_cp.cp_point if event_cp else 0
bonus_points = 0 bonus_points = 0
@ -442,6 +481,8 @@ def checkin_from_rogapp(request):
scoring_breakdown["camera_bonus"] = 5 scoring_breakdown["camera_bonus"] = 5
scoring_breakdown["total_points"] += 5 scoring_breakdown["total_points"] += 5
logger.info(f"[CHECKIN] ✅ SUCCESS - Team: {team_name}, Zekken: {entry.zekken_number}, CP: {cp_number}, Points: {point_value}, Bonus: {bonus_points}, Time: {checkpoint.checkin_time}, Has Image: {bool(image_url)}, Buy Flag: {buy_flag}, Client IP: {client_ip}, User: {user_info}")
# 拡張情報があれば保存 # 拡張情報があれば保存
if gps_coordinates or camera_metadata: if gps_coordinates or camera_metadata:
try: try:
@ -475,7 +516,7 @@ def checkin_from_rogapp(request):
}) })
except Exception as e: except Exception as e:
logger.error(f"Error in checkin_from_rogapp: {str(e)}") logger.error(f"[CHECKIN] ❌ ERROR - team_name: {team_name}, event_code: {event_code}, cp_number: {cp_number}, Client IP: {client_ip}, Error: {str(e)}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "サーバーエラーが発生しました" "message": "サーバーエラーが発生しました"
@ -514,7 +555,12 @@ def goal_from_rogapp(request):
- image: 画像URL - image: 画像URL
- goal_time: ゴール時間 - goal_time: ゴール時間
""" """
logger.info("goal_from_rogapp called") # ログ用のリクエストID生成
request_id = uuid.uuid4().hex[:8]
request_time = time.time()
client_ip = request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR', 'Unknown'))
user_agent = request.META.get('HTTP_USER_AGENT', 'Unknown')
user_info = f"{request.user.username}({request.user.id})" if request.user.is_authenticated else "Anonymous"
# リクエストからパラメータを取得 # リクエストからパラメータを取得
event_code = request.data.get('event_code') event_code = request.data.get('event_code')
@ -522,12 +568,11 @@ def goal_from_rogapp(request):
image_url = request.data.get('image') image_url = request.data.get('image')
goal_time_str = request.data.get('goal_time') goal_time_str = request.data.get('goal_time')
logger.debug(f"Parameters: event_code={event_code}, team_name={team_name}, " logger.info(f"[GOAL] 🏁 API call started - ID: {request_id}, event_code: '{event_code}', team_name: '{team_name}', has_image: {bool(image_url)}, goal_time: '{goal_time_str}', Client IP: {client_ip}, User: {user_info}, User-Agent: {user_agent[:100]}")
f"image={image_url}, goal_time={goal_time_str}")
# パラメータ検証 # パラメータ検証
if not all([event_code, team_name]): if not all([event_code, team_name]):
logger.warning("Missing required parameters") logger.error(f"[GOAL] ❌ Missing required parameters - ID: {request_id}, event_code: '{event_code}', team_name: '{team_name}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "イベントコードとチーム名が必要です" "message": "イベントコードとチーム名が必要です"
@ -537,12 +582,14 @@ def goal_from_rogapp(request):
# イベントの存在確認 # イベントの存在確認
event = NewEvent2.objects.filter(event_name=event_code).first() event = NewEvent2.objects.filter(event_name=event_code).first()
if not event: if not event:
logger.warning(f"Event not found: {event_code}") logger.error(f"[GOAL] ❌ Event not found - ID: {request_id}, event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたイベントが見つかりません" "message": "指定されたイベントが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[GOAL] ✅ Event found - ID: {request_id}, event: '{event.event_name}', event_id: {event.id}")
# チームの存在確認 # チームの存在確認
entry = Entry.objects.filter( entry = Entry.objects.filter(
event=event, event=event,
@ -550,12 +597,14 @@ def goal_from_rogapp(request):
).first() ).first()
if not entry: if not entry:
logger.warning(f"Team not found: {team_name} in event: {event_code}") logger.error(f"[GOAL] ❌ Team not found - ID: {request_id}, team_name: '{team_name}', event_code: '{event_code}', Client IP: {client_ip}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "指定されたチームが見つかりません" "message": "指定されたチームが見つかりません"
}, status=status.HTTP_404_NOT_FOUND) }, status=status.HTTP_404_NOT_FOUND)
logger.info(f"[GOAL] ✅ Team found - ID: {request_id}, team_name: '{team_name}', zekken: {entry.zekken_number}, entry_id: {entry.id}")
# チームがスタートしているか確認 # チームがスタートしているか確認
if not hasattr(entry, 'start_info'): if not hasattr(entry, 'start_info'):
logger.warning(f"Team {team_name} has not started yet") logger.warning(f"Team {team_name} has not started yet")
@ -609,7 +658,7 @@ def goal_from_rogapp(request):
scoreboard_url=scoreboard_url scoreboard_url=scoreboard_url
) )
logger.info(f"Team {team_name} reached goal at {goal_time} with score {score}") logger.info(f"[GOAL] ✅ SUCCESS - Team: {team_name}, Zekken: {entry.zekken_number}, Event: {event_code}, Goal Time: {goal_time}, Score: {score}, Has Image: {bool(image_url)}, Client IP: {client_ip}, User: {user_info}")
return Response({ return Response({
"status": "OK", "status": "OK",
@ -621,7 +670,7 @@ def goal_from_rogapp(request):
}) })
except Exception as e: except Exception as e:
logger.error(f"Error in goal_from_rogapp: {str(e)}") logger.error(f"[GOAL] ❌ ERROR - team_name: {team_name}, event_code: {event_code}, Client IP: {client_ip}, Error: {str(e)}")
return Response({ return Response({
"status": "ERROR", "status": "ERROR",
"message": "サーバーエラーが発生しました" "message": "サーバーエラーが発生しました"