JavaScriptメインでクライアント開発してると、利用者の操作とかのちょっとしたログを取りたいなぁと思ってもなかなか面倒です。
- ロギングのためだけにサーバを立てるのはしんどい
- リアルタイムにログを参照したいわけではない
- 統計的に把握できればよく、ログの完全性の保証は必要ない
といったような、ナンチャッテな機能で十分な場合は、S3を使った簡易ロギングが行けるのでは、と思い、実験。
大きな流れは以下の通りです。
- ロギングは、JavaScriptで$.ajax等を用いたGETリクエストを送信することで行う
- データはGETリクエストに全て含める
- ログ飛ばし先のURLはS3 bucket URL
- rewriteで特定ステータスコードを返す設定を行う
- CORSの設定を行う
- アクセスログを別bucketに残す設定を行う
ロギング用、アクセスログ保管用のS3 bucket作成
2つbucketを作成します。1つはアクセスを受けてrewriteするための半ばダミーのもので、もう1つはS3へのアクセスログを保管するためのものです。
S3へのアクセスログは定期的にAWSによりbucketの所定の位置に設置されますが、それ自体がS3へのHTTPアクセスになっています。ロギング用とログ保管用を同一にしてしまうと、ログ設置用のアクセスがロギング対象となり、無駄なログが増えてしまうため、2つに分けています。
- ロギング用 -> logging-sample
- ログ保管用 -> logging-sample-log
として進めます。
bucket:logging-sampleの設定を行う
bucketのPropertiesを開き、以下の項目の設定を行います。
Static Website Hosting
Website Hostingを有効にし、全てのリクエストに対して304を返すように設定します。
304にする理由は、responseデータが不要なためと、XMLHttpRequestがredirectして2度アクセスが発生しないようにするためです。
- 「Enable website hosting」にチェックします。
- 「Index Document」には、適当に「index.html」等を設定します。
- 「Edit Redirection Rules」で、以下の様なXMLを入力します。
<RoutingRules>
<RoutingRule>
<Condition>
<KeyPrefixEquals>state/</KeyPrefixEquals>
</Condition>
<Redirect>
<ReplaceKeyWith/>
<HttpRedirectCode>304</HttpRedirectCode>
</Redirect>
</RoutingRule>
</RoutingRules>
これで、http(s)://logging-sample.s3-website-xxx.amazonaws.com/state/***** という任意のURLにアクセスした際に、304を返すようになります。
Permissions
CORS(Cross-Origin Resource Sharing)は、ドメインを跨いだAJAXアクセスを行うための設定です。
ブラウザのJavaScriptからHTTPアクセスを行う場合、基本的にはSame-Origin Policyが働くため、外部のリソースにはアクセス出来ませんが、CORS設定を行うことでこれが可能になります。
スマホアプリ等、ブラウザ以外からロギングを行う場合はこの設定は必要ありません。
「Permissions」の「Add CORS Configuration」をクリックし、以下のXMLを入力します。
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
これで、任意のOriginからGETアクセス可能になります。
アクセス元のサイトが決まっている場合は、AllowedOriginを限定したほうが安全です。
Logging
BucketのPropertiesで、
- Enabledにチェック
- Target Bucketに「logging-sample-log」を指定
- Target Prefixは空
とします。これで、アクセスログがbucket:logging-sample-logに蓄積されていきます。
JavaScriptでログ用リクエストを送ってみる
後は、単にURLを生成して$.ajax等で送るだけです。
$.ajax('http://logging-sample.s3-website-xxx.amazonaws.com/state/YOUR/LOGGING/PARAMS/HERE');
これで、1時間〜数時間後には、ログ保管用bucketにアクセスログが出力されます。
お手軽にロギングしたい場合には使えるかもしれません。
IE8/9の場合、CORS対応するにはXDomainRequestを用いないといけないため、jQueryそのままでは厳しいです。
自力で実装するか、ajaxHooksのxdr.jsを使う等の対策が必要です。
注意点
S3 Developer Guide:Server Access Logging参照
S3のロギング機能はBest Effort方式です。
- 全てのアクセスログが記録される保証はない
- アクセスログが配置されるまでには数時間かかる可能性がある
という点を理解しておく必要があります。