バッチステータス確認

コマンドシグネチャ

php artisan specific-viewpoint:check-batch-status {--chunk=10}

目的

specific-viewpoint:check-batch-statusコマンドは、OpenAIのバッチ処理操作を監視し、完了した結果を取得し、分類された視点の関連付けをデータベースに保存します。このコマンドは、保留中のバッチログを特定し、OpenAI APIでステータスを確認し、完了した分類結果をダウンロードし、それらをトレンド分析と顧客インサイト生成のために構造化されたデータベースレコードに処理します。コマンドは継続的な監視とAI分類結果のタイムリーな処理を確保します。

シーケンス図

ステップ1:コマンド初期化とログ取得

sequenceDiagram
    participant System
    participant StatusCommand as specific-viewpoint:check-batch-status
    participant BatchLogRepo as BatchJobViewpointLogRepository
    participant AnalyzerDB[(gb_analyzer.batch_jobs_vp_logs)]
    participant Logger
    participant Slack
    
    Note over System,Slack: コマンド初期化(5分毎)
    
    rect rgb(200, 255, 200)
    Note right of System: 正常ケース - コマンド起動
    System->>StatusCommand: コマンド実行
    StatusCommand->>Logger: チャンクパラメータ付きでコマンド開始をログ
    
    StatusCommand->>BatchLogRepo: getPendingBatchLogs(chunk_limit)
    BatchLogRepo->>AnalyzerDB: WHERE status = 1 (保留中) LIMIT chunkをクエリ
    AnalyzerDB-->>BatchLogRepo: 保留中のバッチログを返す
    BatchLogRepo-->>StatusCommand: 保留中のバッチログコレクションを返す
    StatusCommand->>Logger: 見つかった保留中ログ数をログ
    end
    
    rect rgb(255, 200, 200)
    Note right of System: エラーハンドリング
    rect rgb(255, 230, 230)
    alt データベース接続エラー
        BatchLogRepo->>Logger: データベース接続エラーをログ
        BatchLogRepo->>Slack: データベースエラー通知を送信
    else 保留中ログなし
        StatusCommand->>Logger: 監視するログがないことをログ
    end
    end
    end

ステップ2:ジョブディスパッチとステータス監視設定

sequenceDiagram
    participant StatusCommand as specific-viewpoint:check-batch-status
    participant StatusJob as CheckBatchStatusJob
    participant QueueSystem as Laravel Queue
    participant Logger
    participant Slack
    
    Note over StatusCommand,Slack: バッチステータスジョブディスパッチプロセス
    
    rect rgb(200, 255, 200)
    Note right of StatusCommand: 正常ケース - ジョブ処理
    
    rect rgb(200, 230, 255)
    Note right of StatusCommand: ジョブディスパッチループ
    loop 各保留中バッチログに対して
        StatusCommand->>QueueSystem: CheckBatchStatusJob(batch_log)をディスパッチ
        QueueSystem->>StatusJob: 処理のためにジョブをキューに入れる
        StatusCommand->>Logger: batch_log ID付きでジョブディスパッチをログ
    end
    end
    
    StatusCommand->>Logger: 監視統計をログ
    StatusCommand->>Slack: コマンド完了サマリーを送信
    end
    
    rect rgb(255, 200, 200)
    Note right of StatusCommand: エラーハンドリング
    rect rgb(255, 230, 230)
    alt キューシステムエラー
        StatusCommand->>Logger: キューディスパッチエラーをログ
        StatusCommand->>Slack: キューエラー通知を送信
    else ジョブ作成エラー
        StatusCommand->>Logger: ジョブ作成エラーをログ
        StatusCommand->>Slack: ジョブ作成エラー通知を送信
    end
    end
    end

ステップ3:OpenAIバッチステータス確認

sequenceDiagram
    participant StatusJob as CheckBatchStatusJob
    participant BatchHandler as BatchProcessingHandler
    participant OpenAI as OpenAI Batch API
    participant Logger
    participant Slack
    
    Note over StatusJob,Slack: OpenAIバッチステータス検証
    
    rect rgb(200, 255, 200)
    Note right of StatusJob: 正常ケース - ステータス確認
    
    StatusJob->>Logger: batch_log詳細付きでジョブ開始をログ
    
    rect rgb(200, 230, 255)
    Note right of StatusJob: APIステータスリクエスト
    StatusJob->>BatchHandler: checkBatchStatus(batch_id)
    BatchHandler->>OpenAI: GET /v1/batches/{batch_id}
    OpenAI-->>BatchHandler: バッチステータスとメタデータを返す
    BatchHandler->>BatchHandler: validateStatusResponse()
    BatchHandler-->>StatusJob: 処理されたステータスを返す
    StatusJob->>Logger: ステータス確認結果をログ
    end
    end
    
    rect rgb(255, 200, 200)
    Note right of StatusJob: エラーハンドリング
    rect rgb(255, 230, 230)
    alt API認証エラー
        BatchHandler->>Logger: 認証失敗をログ
        BatchHandler->>Slack: API認証エラーを送信
        BatchHandler->>StatusJob: 認証エラーを返す
    else レート制限エラー
        BatchHandler->>Logger: リトライ情報付きでレート制限をログ
        BatchHandler->>BatchHandler: 指数バックオフを実装
        BatchHandler->>StatusJob: 遅延付きで再試行をスケジュール
    else APIサービスエラー
        BatchHandler->>Logger: レスポンス付きでAPIサービスエラーをログ
        BatchHandler->>Slack: APIサービスエラー通知を送信
        BatchHandler->>StatusJob: サービスエラーを返す
    else バッチが見つからない
        BatchHandler->>Logger: バッチが見つからないエラーをログ
        BatchHandler->>Slack: バッチが見つからない通知を送信
        BatchHandler->>StatusJob: 見つからないエラーを返す
    end
    end
    end

ステップ4:完了したバッチ結果処理

sequenceDiagram
    participant StatusJob as CheckBatchStatusJob
    participant FileHandler as BatchFileHandler
    participant ResultHandler as BatchResultHandler
    participant OpenAI as OpenAI Files API
    participant Logger
    participant Slack
    
    Note over StatusJob,Slack: 完了したバッチ結果処理
    
    rect rgb(200, 255, 200)
    Note right of StatusJob: 正常ケース - ステータスが完了
    
    rect rgb(200, 230, 255)
    Note right of StatusJob: 結果ファイルダウンロード
    StatusJob->>FileHandler: downloadResultFile(output_file_id)
    FileHandler->>OpenAI: GET /v1/files/{file_id}/content
    OpenAI-->>FileHandler: 結果ファイル内容(JSONL)を返す
    FileHandler->>FileHandler: validateFileFormat()
    FileHandler-->>StatusJob: 解析された結果を返す
    StatusJob->>Logger: サイズ付きでファイルダウンロード成功をログ
    end
    
    rect rgb(255, 255, 200)
    Note right of StatusJob: 結果処理と検証
    StatusJob->>ResultHandler: processClassificationResults(results)
    ResultHandler->>ResultHandler: parseJSONLResults()
    ResultHandler->>ResultHandler: validateClassificationData()
    ResultHandler->>ResultHandler: mapSentencesToViewpoints()
    ResultHandler-->>StatusJob: 視点マッピングを返す
    StatusJob->>Logger: 結果処理完了をログ
    end
    end
    
    rect rgb(255, 200, 200)
    Note right of StatusJob: エラーハンドリング
    rect rgb(255, 230, 230)
    alt ファイルダウンロードエラー
        FileHandler->>Logger: file_id付きでダウンロードエラーをログ
        FileHandler->>Slack: ダウンロードエラー通知を送信
        FileHandler->>StatusJob: ダウンロードエラーを返す
    else 無効なファイル形式
        ResultHandler->>Logger: ファイル形式検証エラーをログ
        ResultHandler->>Slack: 形式エラー通知を送信
        ResultHandler->>StatusJob: 形式エラーを返す
    else 分類データエラー
        ResultHandler->>Logger: 分類検証エラーをログ
        ResultHandler->>Slack: 検証エラー通知を送信
        ResultHandler->>StatusJob: 検証エラーを返す
    end
    end
    end

ステップ5:データベース保存とステータス更新

sequenceDiagram
    participant StatusJob as CheckBatchStatusJob
    participant ReviewVPRepo as ReviewSentenceSpecificViewpointRepository
    participant BatchLogRepo as BatchJobViewpointLogRepository
    participant AnalyzerDB[(gb_analyzer)]
    participant Logger
    participant Slack
    
    Note over StatusJob,Slack: データベース保存とステータス管理
    
    rect rgb(200, 255, 200)
    Note right of StatusJob: 正常ケース - データ保存
    
    rect rgb(200, 230, 255)
    Note right of StatusJob: 視点関連付け作成
    StatusJob->>ReviewVPRepo: bulkInsertViewpointAssociations(mappings)
    ReviewVPRepo->>AnalyzerDB: BEGIN TRANSACTION
    ReviewVPRepo->>AnalyzerDB: INSERT INTO review_sentences_wl_spec_vp (一括)
    AnalyzerDB-->>ReviewVPRepo: 挿入されたレコード数を返す
    ReviewVPRepo->>AnalyzerDB: COMMIT TRANSACTION
    ReviewVPRepo-->>StatusJob: 関連付け作成を確認
    StatusJob->>Logger: 数付きで一括挿入成功をログ
    end
    
    rect rgb(200, 230, 255)
    Note right of StatusJob: バッチログステータス更新
    StatusJob->>BatchLogRepo: updateBatchLogStatus(batch_log_id, COMPLETED)
    BatchLogRepo->>AnalyzerDB: UPDATE batch_jobs_vp_logs SET status = 2
    AnalyzerDB-->>BatchLogRepo: ステータス更新を確認
    BatchLogRepo-->>StatusJob: 更新確認を返す
    StatusJob->>Logger: ステータス更新完了をログ
    end
    
    rect rgb(230, 200, 255)
    Note right of StatusJob: 成功監視
    StatusJob->>Logger: 統計付きで処理成功をログ
    StatusJob->>Slack: メトリクス付きで完了通知を送信
    end
    end
    
    rect rgb(255, 200, 200)
    Note right of StatusJob: エラーハンドリング
    rect rgb(255, 230, 230)
    alt データベーストランザクションエラー
        ReviewVPRepo->>AnalyzerDB: ROLLBACK TRANSACTION
        ReviewVPRepo->>Logger: トランザクションロールバックエラーをログ
        ReviewVPRepo->>Slack: データベースエラー通知を送信
        ReviewVPRepo->>StatusJob: トランザクションエラーを返す
    else 一括挿入制約エラー
        ReviewVPRepo->>Logger: 制約違反エラーをログ
        ReviewVPRepo->>Slack: 制約エラー通知を送信
        ReviewVPRepo->>StatusJob: 制約エラーを返す
    else ステータス更新失敗
        BatchLogRepo->>Logger: ステータス更新失敗をログ
        BatchLogRepo->>Slack: ステータス更新エラー通知を送信
        BatchLogRepo->>StatusJob: 更新エラーを返す
    end
    end
    end

ステップ6:失敗したバッチ処理

sequenceDiagram
    participant StatusJob as CheckBatchStatusJob
    participant BatchLogRepo as BatchJobViewpointLogRepository
    participant AnalyzerDB[(gb_analyzer.batch_jobs_vp_logs)]
    participant Logger
    participant Slack
    
    Note over StatusJob,Slack: 失敗したバッチ処理
    
    rect rgb(255, 255, 200)
    Note right of StatusJob: ステータスが失敗
    
    StatusJob->>BatchLogRepo: updateBatchLogStatus(batch_log_id, FAILED, error_details)
    BatchLogRepo->>AnalyzerDB: UPDATE batch_jobs_vp_logs SET status = 9, log_details = error
    AnalyzerDB-->>BatchLogRepo: エラーステータス更新を確認
    BatchLogRepo-->>StatusJob: エラーログを確認
    
    StatusJob->>Logger: OpenAIエラー付きでバッチ失敗詳細をログ
    StatusJob->>Slack: batch_id付きで失敗通知を送信
    end
    
    rect rgb(200, 230, 255)
    Note right of StatusJob: ステータスが進行中
    
    StatusJob->>Logger: 推定完了時間付きでバッチがまだ処理中であることをログ
    StatusJob->>Logger: 進行中バッチに対してアクションが不要であることをログ
    end

ステップ7:ジョブ完了とシステム監視

sequenceDiagram
    participant StatusJob as CheckBatchStatusJob
    participant StatusCommand as specific-viewpoint:check-batch-status
    participant QueueSystem as Laravel Queue
    participant Logger
    participant Slack
    
    Note over StatusJob,Slack: ジョブ完了とシステム監視
    
    rect rgb(200, 255, 200)
    Note right of StatusJob: 正常ケース - 正常完了
    
    rect rgb(230, 200, 255)
    Note right of StatusJob: ジョブ最終化
    StatusJob->>Logger: 処理メトリクス付きでジョブ完了をログ
    StatusJob->>Logger: OpenAI APIレスポンス時間と統計をログ
    StatusJob->>QueueSystem: ジョブを完了としてマーク
    QueueSystem-->>StatusCommand: ジョブ完了ステータスを更新
    end
    
    rect rgb(230, 200, 255)
    Note right of StatusCommand: コマンドサマリー
    StatusCommand->>Logger: 全体統計付きでコマンド完了をログ
    StatusCommand->>Logger: 処理されたログの合計と成功率をログ
    StatusCommand->>Slack: メトリクス付きでコマンド完了サマリーを送信
    end
    end
    
    rect rgb(255, 200, 200)
    Note right of StatusJob: エラーハンドリングと回復
    rect rgb(255, 230, 230)
    alt ジョブ処理失敗
        StatusJob->>Logger: エラー詳細付きでジョブ失敗をログ
        StatusJob->>QueueSystem: 再試行のためにジョブを失敗としてマーク
        StatusJob->>Slack: ジョブ失敗通知を送信
    else APIタイムアウト問題
        StatusJob->>Logger: APIタイムアウトエラーをログ
        StatusJob->>QueueSystem: 遅延付きで再試行のためにジョブをリリース
        StatusJob->>Slack: タイムアウトエラー通知を送信
    else 重大なシステムエラー
        StatusJob->>Logger: 重大なシステムエラーをログ
        StatusJob->>Slack: 重大なエラーアラートを送信
        StatusJob->>StatusCommand: 以降の処理を停止
    end
    end
    end

詳細

パラメータ

  • {--chunk=10}: 1回の実行で処理されるバッチログ数を制限するためのオプションパラメータ
    • デフォルト値: 10
    • 1回のコマンド実行で確認する保留中バッチログの最大数を制御
    • APIレート制限を防ぎ、システムリソース使用量を管理するのに役立つ
    • より速い処理のために増加したり、リソース制約のある環境のために減少したりできる

頻度

  • スケジュール実行: 5分毎
    • Laravelのスケジューラを使用してroutes/console.phpで設定
    • 例: Schedule::command('specific-viewpoint:check-batch-status')->everyFiveMinutes();
  • 手動実行: 即時ステータス確認のために手動でトリガー可能
    • デバッグや緊急結果処理に使用

依存関係

データベース依存関係:

  • バッチログと結果保存用のアナライザーデータベース(gb_analyzer)接続
  • 保留中ステータスのbatch_jobs_vp_logs内の既存レコード
  • アトミックな結果処理のためのトランザクションサポート
  • 視点関連付けのための適切な外部キー関係

外部サービス依存関係:

  • ステータスクエリとファイルダウンロード用のOpenAI APIサービスの可用性
  • 環境変数で設定された有効なAPI認証情報
  • OpenAIのAPIエンドポイントへのネットワーク接続
  • バッチステータスチェック用のAPIレート制限遵守

システム依存関係:

  • ジョブ処理用のキューシステム設定(config/queue.php
  • 一時的な結果ファイル処理用のストレージ
  • 処理設定のためのconfig/specific_viewpoint.php
  • 適切に設定されたエラー処理と通知システム

出力

テーブル

バッチステータス確認コマンドは複数のデータベーステーブルと相互作用します。完全なテーブル構造、フィールド定義、および関係については、データベーススキーマセクションを参照してください。

主要出力テーブル:

  • review_sentences_wl_spec_vp: 分類結果から視点関連付けを作成
  • batch_jobs_vp_logs: ステータスと処理統計を更新

コマンド固有の操作:

  • 作成: 文と視点をリンクするreview_sentences_wl_spec_vpに新しいレコードを作成
  • 更新: batch_jobs_vp_logsのステータス遷移(保留中 → 完了/失敗)
  • ログ: 文数と成功率を含む処理統計

サービス

OpenAI統合:

  • BatchProcessingHandlerInterface: OpenAI APIでバッチステータスを確認
  • BatchFileHandlerInterface: OpenAIから結果ファイルをダウンロード
  • BatchResultHandlerInterface: 分類結果を処理および解析
  • レート制限とエラー回復のための指数バックオフを実装

リポジトリサービス:

  • BatchJobViewpointLogRepositoryInterface: 保留中ログの取得とステータスの更新
  • ReviewSentenceSpecificViewpointRepositoryInterface: 視点関連付けの一括挿入
  • アトミックな結果処理のためのトランザクション管理
  • 大規模な結果セット用の最適化された一括操作

バックグラウンドジョブサービス:

  • CheckBatchStatusJob: ステータス確認を処理するために各保留中ログにディスパッチ
  • 非同期ステータス監視のためのキュー管理
  • 自動リトライメカニズムとバックオフ戦略によるジョブ失敗処理

エラーハンドリング

ログ

システムはステータス監視の問題をトラブルシューティングするための包括的なログを生成します:

API通信エラー:

  • 完全なエラーレスポンス詳細とステータスコード付きのOpenAI APIリクエスト失敗
  • リトライ試行情報とファイルID詳細付きのファイルダウンロード失敗
  • バックオフ戦略実装とタイミング付きのレート制限エラー
  • 認証情報検証提案付きの認証失敗

結果処理エラー:

  • 解析エラー詳細とサンプルデータ付きの無効な結果ファイル形式
  • 特定の視点マッピング問題付きの分類結果検証エラー
  • 一括挿入操作中のデータベース制約違反
  • 影響を受けたレコード数付きのトランザクションロールバックシナリオ

ログの場所:

  • コンテキスト的なバッチログ情報を持つアプリケーションログ: storage/logs/laravel.log
  • 実行統計とAPIレスポンス時間を持つコマンド固有のログ
  • 完全なスタックトレースとOpenAI APIリクエスト/レスポンス詳細を持つエラーログ

Slack

自動Slack通知は運用監視のためにAIBatchPredictSlackChannelを介して送信されます:

成功通知:

  • 処理統計とタイミングを持つバッチ完了通知
  • 視点関連付け数と成功率を持つ結果処理サマリー
  • APIレスポンス時間と処理スループットを含むパフォーマンスメトリクス

エラー通知:

  • エラーコードと提案された解決手順を持つOpenAI API通信失敗
  • リトライ情報とファイル可用性ステータス付きのファイルダウンロード失敗
  • 影響を受けたバッチログ詳細とロールバック情報を持つデータベース操作失敗
  • 即時管理者注意を必要とする重大なシステムエラー

通知形式:

  • 運用追跡用のコマンド名と実行タイムスタンプ
  • インシデント優先順位付けのためのエラータイプと重大度レベル
  • 調査用の影響を受けたバッチログIDとOpenAIバッチ詳細
  • 提案されたトラブルシューティング手順とドキュメント参照

トラブルシューティング

データを確認

保留中バッチログを検証:

-- ステータス更新を待っているバッチログを確認
SELECT id, batch_job_id, batch_id, total_sentences, processed_sentences, 
       status, log_details, created_at, updated_at
FROM batch_jobs_vp_logs
WHERE status = 1 -- 保留中
ORDER BY created_at ASC;

停滞しているバッチログを確認:

-- 保留中状態で停滞しているバッチログを見つける(2時間以上経過)
SELECT id, batch_job_id, batch_id, total_sentences, 
       TIMESTAMPDIFF(MINUTE, updated_at, NOW()) as minutes_stuck
FROM batch_jobs_vp_logs
WHERE status = 1 -- 保留中
AND updated_at < DATE_SUB(NOW(), INTERVAL 2 HOUR)
ORDER BY updated_at ASC;

最近の分類結果を確認:

-- 最近作成された視点関連付けを確認
SELECT COUNT(*) as new_associations, wl_spec_vp_id
FROM review_sentences_wl_spec_vp
WHERE created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY wl_spec_vp_id
ORDER BY new_associations DESC;

ログを確認

アプリケーションログ:

# 最近のcheck-batch-statusコマンドログを確認
tail -f storage/logs/laravel.log | grep -E "specific-viewpoint:check-batch-status"

# バッチステータス確認ログを確認
grep "CheckBatchStatusJob" storage/logs/laravel.log | tail -20

# OpenAI API通信ログを確認
grep "BatchProcessingHandler" storage/logs/laravel.log | tail -10

# エラーパターンを確認
grep -E "(ERROR|CRITICAL)" storage/logs/laravel.log | grep "check-batch-status" | tail -10

データベースログ:

-- 最近のステータス更新を確認
SELECT bjvl.*, 
       CASE bjvl.status 
           WHEN 1 THEN '保留中'
           WHEN 2 THEN '完了' 
           WHEN 9 THEN '失敗'
       END as status_name
FROM batch_jobs_vp_logs bjvl
WHERE bjvl.updated_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY bjvl.updated_at DESC;

-- 失敗したバッチ処理を確認
SELECT id, batch_job_id, batch_id, log_details, updated_at
FROM batch_jobs_vp_logs
WHERE status = 9 -- 失敗
AND updated_at > DATE_SUB(NOW(), INTERVAL 1 DAY)
ORDER BY updated_at DESC;

OpenAI API検証:

# OpenAIバッチステータスエンドポイントをテスト
curl -X GET "https://api.openai.com/v1/batches/BATCH_ID" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY"

# ファイルダウンロードエンドポイントを確認
curl -X GET "https://api.openai.com/v1/files/FILE_ID/content" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY"

# APIレート制限を確認
curl -I "https://api.openai.com/v1/batches" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY"

パフォーマンス監視:

  • パフォーマンス低下について命令実行時間を監視
  • OpenAI APIレスポンス時間とタイムアウト設定を確認
  • 大規模な結果セット用のデータベース一括挿入パフォーマンスを検証
  • ジョブディスパッチ効率についてキュー処理パフォーマンスを確認
  • 結果処理用のファイルダウンロード時間とストレージ使用量を監視