AI生成アプリにとってなぜ監視が重要か
AI生成アプリが本番稼働したら、3つの層に対する可視性が必要です。アプリケーションヘルス、インフラ負荷、ユーザー体験です。監視がなければ、メモリリークや遅いデータベースクエリは、ユーザーが苦情を言うまで表面化しません。AI生成コードは特に微妙なパフォーマンス問題を起こしやすい傾向があります。モデルはコンパイルされ動作するコードを書きますが、最適なアルゴリズムを使用していない可能性、データベース接続をリークする可能性、OpenAIのような高額なサービスに冗長なAPI呼び出しを行う可能性があります。監視を後回しではなくデプロイの第一級のステップとして扱うことが、プロトタイプと本番品質システムを分かつ要素です。
このレッスンで扱う4つの柱:構造化ロギング、エラートラッキング、パフォーマンスメトリクス、自動スケーリング設定。これらを組み合わせることで、問題の検出、根本原因の診断、負荷への自動対応が可能になります。
構造化ロギング
単なるprint文は検索できず、フィルタもできず、コンテナの再起動で消えてしまいます。構造化ロギングとは、ログを一貫したフィールド(timestamp、level、route、user_id、duration_ms、status_code)を持つJSONオブジェクトとして出力することです。Loki、CloudWatch Logs、Datadogのような集約ツールがそれらをインデックス化し、クエリできます。
PythonのFastAPIでは、`print`に頼るのではなく、`logging`モジュールにJSONフォーマッターを組み合わせて使用します。
これで各ログ行がJSONオブジェクトになり、集約ツールがフィールドでフィルタリングできます。Node.jsでは`pino`、Goでは`zap`または`slog`がこれに該当します。重要なのは一貫性です。1つのフォーマットを選び、バックグラウンドワーカーやcronジョブのログも含め、すべての箇所にそれを適用してください。
エラートラッキング
ログは「何が起きたか」を伝えます。エラートラッカーは「いつ、どれくらいの頻度で何が壊れたか」を完全なスタックトレースと集計と共に伝えます。最も一般的なツールはSentryとRollbarの2つです。どちらもアプリケーションをラップするSDKをインストールし、未処理の例外をキャプチャし、繰り返されるエラーをissueに集約します。
Node.jsのExpressアプリの場合、初期化は2行です。
PythonのFlaskでは、同様に`FlaskIntegration`と共に`sentry-sdk`を使用します。一度初期化すれば、すべての未処理例外が完全なスタックトレース、リクエストヘッダー、アプリのリリースバージョンと共に自動的に報告されます。重要な設定:プロダクション環境では`tracesSampleRate`を0.1〜0.3の間に設定してください。トレースの100%サンプリングはコストが高く、必要になることは稀です。`tags`(例:`plan: pro`)でビジネス上有意義なコンテキストをキャプチャし、ユーザーセグメントごとにエラーをフィルタできるようにします。
よくある間違い:メインプロセスだけでエラーをトラッキングすること。バックグラウンドワーカー(Celery、BullMQ、Sidekiq)を実行している場合、それぞれに独自のSDK初期化が必要です。静かに動くワーカーのエラーは、そうしなければ決して表面化しません。
パフォーマンス監視とFour Golden Signals
Googleの「Four Golden Signals」フレームワークは、あらゆるパフォーマンスダッシュボードの出発点です。レイテンシ:リクエストにかかる時間(p50、p95、p99 — 平均値だけでなく)。トラフィック:1秒あたりのリクエスト数。エラー:失敗したリクエストの割合。飽和度:容量に対してどれだけ逼迫しているか(CPU、メモリ、キュー深度)。
実際にはこれらをPrometheus + Grafana(セルフホスト)またはDatadog / New Relic(マネージド)で測定します。Kubernetes環境の場合、Prometheusのnode-exporterとアプリケーションクライアントライブラリ(例:`prometheus-fastapi-instrumentator`、Node用は`prom-client`)が`/metrics`エンドポイントを公開し、Prometheusが15秒ごとにそれらをスクレイプします。Grafanaはそれらを可視化し、アラートルールを設定します(例:p95レイテンシが2秒を5分間超えたらオンコールを呼ぶ)。
AIを多用するアプリケーションでは、カスタムメトリクスを追加してください:リクエストごとの外部APIコスト。各リクエストで消費したトークン数または消費したUSDを追跡します。これは無限ループや誤設定のプロンプトによる暴走コストを検知する唯一の方法です。
自動スケーリングルール
自動スケーリングは負荷メトリクスに基づいてコンピュート容量を追加または削減します。KubernetesではHorizontal Pod Autoscaler(HPA)を使用します。AWSではECS Service Auto ScalingまたはEC2 Auto Scaling Groupsを使用します。サーバーレスプラットフォーム(Vercel、Cloud Run、Lambda)ではスケーリングは通常自動ですが、同時実行数とメモリを制御できます。
設定の基本はどの環境でも同じです:監視するメトリクス(CPU、メモリ、ポッドあたりのリクエスト、キュー深度)と目標とする閾値です。以下は典型的なKubernetes HPAの例です。
このHPAは2〜20ポッド間でスケーリングし、CPUが60%を超えた場合、またはポッドあたりの平均リクエスト数が100/秒を超えた場合に容量を追加します。`minReplicas: 2`(1ではない)を設定することで、デプロイメントやローリングアップデート中のダウンタイムを防ぎます。`maxReplicas`が低すぎるとスパイク時にスロットリングが発生し、高すぎるとクラウドコストが暴走します。平均ではなく、最も高くつく現実的なシナリオに基づいてサイズを設定してください。
AIワークロードの場合、CPUのみでのスケーリングは誤解を招きます。ボトルネックは多くの場合、OpenAIを待つ外部API呼び出しまたはデータベースクエリだからです。代わりにキュー深度(タスクキュー内の保留中リクエスト数)でスケールするか、CPUとキュー深度のメトリクスを組み合わせてください。コールドスタートレイテンシも要因です:ユーザー向けレイテンシが重要な場合は、少なくとも1つのウォームポッドを稼働させ続けてください。
まとめ
監視と自動スケーリングは別々のフェーズではなく、フィードバックループを形成します。メトリクスはいつスケールすべきかを示し、ログとエラートラッカーは負荷下で何が壊れているかを示し、自動スケーリングはその破損を防ぎます。特にAI生成アプリケーションの場合、固有のリスクは外部APIコストの暴走とモデル呼び出しからの予測不能なレイテンシなので、それらを明示的に追跡してください。シンプルに始めましょう:構造化ロガー1つ、エラートラッカー1つ(Sentry)、基本的なCPUベースのHPA。ダッシュボードが必要性を示したときだけ複雑さを追加してください。
レッスンのチェックポイント
学んだ内容を復習し、回答へのフィードバックを受けましょう。