CloudFrontログのHTTP ステータスコード000について、どのような場合に発生するか調べてみました。
CloudFrontログでHTTP ステータスコードが000のモノをよく見るけど、これはどういった時に発生するのか、無視していいモノなのか分かりませんでしたので、調べましたーという内容になります!
公式ガイドでは、以下の記載があります。
000
。この値は、サーバーがリクエストに応答する前に、ビューワーが接続を閉じたことを示します。サーバーがレスポンスの送信を開始した後にビューワーが接続を閉じた場合、このフィールドには、サーバーが送信を開始したレスポンスの HTTP ステータスコードが含まれます。標準ログ (アクセスログ) の設定および使用 - Amazon CloudFrontログファイルを使用してオブジェクトに対するユーザーリクエストに関する情報を取得します。
「ビューワーが接続を閉じたこと = ブラウザを閉じた」と考えていいものかという疑問です。
Lambda@Edgeを使ってSleepを入れながら確認した結果、HTTP ステータスコードが000は、ブラウザを閉じた場合など接続が切れた場合に発生することが分かりました!
接続が切れた場合なので、基本的に無視して良い(どうしようも無い)ログということです。
<疑問>
CloudFrontログでHTTP ステータスコードが000のものは何者?
<調査方法>
Lambda@Edgeを使ってSleepを入れながら確認
<調査結果>
ブラウザを閉じた場合など接続が切れた場合に発生する
調査方法の詳細と調査結果を書いていきます!
調査方法
CloudFrontのオリジンをS3にして作成し、Lambda@Edgeを使ってSleepを入れながら確認しました。
まずは、調査の準備について記載します。
調査準備
CloudFrontとS3の作成
- S3バケットを作成
- CloudFrontのディストリビューションをオリジン:S3に設定して作成
次にSleepを入れるLambda@Edgeを作成します!
リクエスト時のLambda@Edge
以下のものを作成しておきます。
const sleep = (m) => {
return new Promise((resolve) => setTimeout(resolve, m));
};
export const handler = async(event) => {
await sleep(2000);
return event['Records'][0]['cf']['request'];
};
レスポンス時のLambda@Edge
以下のものを作成しておきます。
const sleep = (m) => {
return new Promise((resolve) => setTimeout(resolve, m));
};
export const handler = async(event, context, callback) => {
await sleep(2000);
callback(null, event.Records[0].cf.response);
};
調査実施
以下のイベントのタイミングで、上記で用意したLambda@Edgeを実行し、Sleepするようにします。Sleepしている間に接続を切ったら、どのようになるか確認していきます。
- ビューワーリクエスト
- オリジンリクエスト
- ビューワーレスポンス
- オリジンレスポンス
各イベントの詳細は以下をご参照ください。
ビューワーリクエスト
ビューワーリクエストに「リクエスト時のLambda@Edge」を設定して、CloudFrontにアクセスし、Sleep中に通信を切断します。
動作確認には「ブラウザ」と「curlコマンド」を使用しました。
アクセス中にブラウザのタブを閉じた場合の結果
HTTP ステータスコード(sc-status):000
x-edge-detailed-result-type:ClientCommError
curlコマンドのタイムアウトを1秒に設定して実行した場合の結果
<実行したコマンド>
curl --max-time 1 {url}
<結果>
HTTP ステータスコード(sc-status):000
x-edge-detailed-result-type:ClientCommError
次はオリジンリクエストです。
オリジンリクエスト
オリジンリクエストに「リクエスト時のLambda@Edge」を設定して、CloudFrontにアクセスし、Sleep中に通信を切断します。
アクセス中にブラウザのタブを閉じた場合の結果
HTTP ステータスコード(sc-status):000
x-edge-detailed-result-type:ClientCommError
curlコマンドのタイムアウトを1秒に設定して実行した場合の結果
<実行したコマンド>
curl --max-time 1 {url}
<結果>
HTTP ステータスコード(sc-status):000
x-edge-detailed-result-type:ClientCommError
次は、ビューワーレスポンスです。
ビューワーレスポンス
ビューワーレスポンスに「レスポンス時のLambda@Edge」を設定して、CloudFrontにアクセスし、Sleep中に通信を切断します。
アクセス中にブラウザのタブを閉じた場合の結果
HTTP ステータスコード(sc-status):000
x-edge-detailed-result-type:ClientCommError
curlコマンドのタイムアウトを1秒に設定して実行した場合の結果
<実行したコマンド>
curl --max-time 1 {url}
<結果>
HTTP ステータスコード(sc-status):000
x-edge-detailed-result-type:ClientCommError
次は、オリジンレスポンスです。
オリジンレスポンス
オリジンレスポンスに「レスポンス時のLambda@Edge」を設定して、CloudFrontにアクセスし、Sleep中に通信を切断します。
アクセス中にブラウザのタブを閉じた場合の結果
HTTP ステータスコード(sc-status):000
x-edge-detailed-result-type:ClientCommError
curlコマンドのタイムアウトを1秒に設定して実行した場合の結果
<実行したコマンド>
curl --max-time 1 {url}
<結果>
HTTP ステータスコード(sc-status):000
x-edge-detailed-result-type:ClientCommError
調査結果
以下のイベントのタイミングで接続を切った場合、結果は同じで、全てのケースで「HTTP ステータスコード000」が発生しました。
- ビューワーリクエスト
- オリジンリクエスト
- ビューワーレスポンス
- オリジンレスポンス
HTTP ステータスコード000の正体は、ブラウザの接続が切れたケースという結果となります。
ついでに、オリジンにALBを指定して、接続を切った場合、ALBのログがどうなるかについても調査しました!
オリジンにALBを指定して、接続を切った場合のALBログ調査
CloudFrontの調査と同様Lambda@EdgeでSleepを入れて調査しました。
ビューワーリクエスト中に接続が切れた場合
ログ出力されない
→オリジン(ALB)にリクエストが届いていない
オリジンリクエスト中に接続が切れた場合
ログ出力されない
→オリジン(ALB)にリクエストが届いていない
ビューワーレスポンス中に接続が切れた場合
HTTP ステータスコード200でログ出力
→ALB自体は正常終了
オリジンレスポンス中に接続が切れた場合
200
→ALB自体は正常終了
まとめ
以下の結果となりましたー!
CloudFrontログのHTTP ステータスコード000は何者?の疑問が解消されましたー!
<疑問>
CloudFrontログでHTTP ステータスコードが000のものは何者?
<調査方法>
Lambda@Edgeを使ってSleepを入れながら確認
<調査結果>
ブラウザを閉じた場合など接続が切れた場合に発生する