Fastlyを使ってオリジンレスでログを収集する


この記事の内容について

FastlyのBlogポスト Beacon termination at the edge で紹介されているように、Fastlyの特徴のひとつであるリアルタイムログストリーミング機能を利用して、たくさんの端末からのログを収集するためのプラットフォームとしてFastlyを利用することが出来ます。

この記事では、オリジンレスでログを収集するための設定を作成する手順をご紹介します。

特に記載がない限り本記事の記載内容はデフォルト設定での挙動となります。

作業のおおまかな流れとしては以下のようになります。
Step 1: サービスの作成
Step 2: ログ配信設定の作成
Step 3: カスタムレスポンスの作成
Step 4: サービスの有効化

それでは順番に手順を確認して見ましょう。

Step 1: サービスの作成

Fastlyのコントロールパネル( https://manage.fastly.com/ )にログインし、Configureタブを選択し、CREATE SERVICEをクリックして下さい。

Domain, Origin(backend)の設定

CREATE SERVICEをクリックすると以下のような画面が表示されます。

Name: このサービスの名称になります。サービスを識別可能な名前を英数字で入力して下さい
Domain: ログの送付先となるドメインを入力して下さい
Address: backend(いわゆるオリジンサーバー)のドメイン、またはIPアドレスを入力します。完全にログ収集が目的のサービスで、すべてのリクエストにFastlyが生成するレスポンスを返却する場合はアクセスが出来ないダミーの情報でも構いません。
Enable TLS: オリジンとの接続でTLSを利用するかどうかを指定します。サンプルの設定ではダミーのオリジンで、実際にオリジンとの通信は発生しませんのでNoで問題ありません。

Create ボタンをクリックするとサービスの作成が完了します。

Step 2: ログ配信設定の作成

正しくサービスが作成されると、以下のようにVersion.1が表示されているはずです。このバージョンはすでにActiveで編集が出来ないようにLockされているので、Cloneして編集可能なバージョンを作成します。

Cloneするには画面右上のConfigurationをクリックして、表示されるメニューからClone activeを選択して下さい。

サービスのVersion.2が生成されます。ログの配信設定を作成するためには左側のメニューからLoggingをクリックして下さい。以下のような画面が表示されます。


ダミーのオリジン情報を登録している場合、警告メッセージが表示されますが問題ありません

表示されたログのエンドポイントの中から、ログを送信したいエンドポイントを選択してログの配信設定を作成して下さい。
ログエンドポイントはどこでも構いませんが、送信するログの数に耐えうるエンドポイントである必要があります。ログのエンドポイントでも受け付けたトラフィックに応じて課金が発生するものもあるので注意して下さい。

具体的な設定手順はリモートログストリーミングの設定や、Qiita内にもFastlyのログ設定に関する記事がありますのでそちらを参照にして下さい。

ログを取得する条件やログフォーマットも自由に設定可能です。必要に応じてログフォーマットを変更して下さい。
ログビーコンの収集目的であれば、POST BODYやクエリストリング、リクエストヘッダなどを取得したいケースが多いかと思いますが、それらの情報をログに追加したい場合はLog format に以下のような内容をを追加することで取得することが出来ます。

指定したリクエストヘッダの値: %{req.http.X_special}V <- この場合は X_specialヘッダーの値を取得します
ポストボディの内容: %{req.postbody}V
クエリストリング全体: %{req.url.qs}V
指定したクエリストリングのValue: %{if(req.url.qs ~ "^.*key=([^&]*)", re.group.1, "none")}V <- この場合は keyパラメータのValueのみを取得します
指定したクエリストリングのKeyとValue: %{if(req.url.qs ~ "^.*(key=[^&]*)", re.group.1, "none")}V <- この場合は keyパラメータとValueを取得します

Step 3: カスタムレスポンスの作成

続いて、リクエストを受信時にクライアントに返却するカスタムレスポンスを作成します。

左側のメニューからContentを選択し、Create Your First Responseをクリックして下さい。

以下のCreate a synthetic response画面が表示されます。

Name: この設定の名称です。適当な名前を入力して下さい。
Status: 返却するレスポンスステータスです。ここでは「204 No Content」を選択します。
MIME Type, Response は通常空欄でも問題ありません。

上記の内容でCreateをクリックして下さい。

Step 4: サービスの有効化

上記の設定が完了したら、画面右上のActivateボタンをクリックして下さい。

この設定の挙動を改めて簡単に説明すると
・すべてのリクエストに無条件で「204 No Content」 レスポンスを返却します。
・すべてのリクエストに対して、指定したログエンドポイントに指定した内容を含むログを送信します。
・オリジンサーバーへのアクセスは発生しないので、オリジンサーバーはダミーでも問題ありません。

動作確認と注意事項

それでは以下のLog formatでログを取得した場合の結果を確認してみたいと思います。以下のcURLコマンドはクエリストリング付きのPOSTリクエストをドメインに対して送っています。

curl -svo /dev/null "http://log.xxxxxx.com?aaa=bbb&key=query_value&ccc=ddd" -H "X_special:header_value" -d '{"key":"post_value"}'
> POST /?aaa=bbb&key=query_value&ccc=ddd HTTP/1.1
> Host: log.xxxxxx.com
> User-Agent: curl/7.52.1
> X_special:header_value

< HTTP/1.1 204 No Content

正しく204 No Content レスポンスが返却されています。

それでは、このサービスのログフォーマットと、リクエストで発生したログを確認してみます。

ログフォーマット
%h %l %u %t "%r" %>s %b %{req.postbody}V %{req.url.qs}V %{req.http.X_special}V %{if(req.url.qs ~ "^.*key=([^&]*)", re.group.1, "none")}V %{if(req.url.qs ~ "^.*(key=[^&]*)", re.group.1, "none2")}V
出力されたログ
122.208.204.58 "-" "-" [27/Nov/2017:10:11:22 +0000] "POST /?aaa=bbb&key=query_value&ccc=ddd HTTP/1.1" 204 "-" {"key":"post_value"} aaa=bbb&key=query_value&ccc=ddd header_value query_value  key=query_value

ログフォーマットではクエリストリングとPOST BODYをログに含めるように設定されています。出力されたログでは指定したデータが正しく取得されていることが確認できます。

このようにFastlyのログストリーミング機能、カスタムレスポンス機能を活用することで、簡単にオリジンレスでログの収集プラットフォームを作成することが出来ます。
ログの送り先はBigQueryでもGCSでもS3でもどこでも大丈夫です。使い慣れた分析プラットフォームに直接送信することが可能です。

CDNというと、名前の通りコンテンツ配信のためのプラットフォームというイメージがあると思いますが、Fastlyではアイデア次第でこのように通常のCDNとは異なるユースケースにも利用することが出来ます。

注意事項

Fastlyのログ取得目的で利用する場合は、以下のような点に注意して下さい。

  • Fastly側ではお客様のログをディスクなどに保存はしていません。そのため、ログの受取先のサービスやネットワークの問題などでログの配信に失敗した場合も、Fastly側から失われたログを再送することは出来ません。
  • Fastly でログに記録可能なPOST BODYのサイズは最大2KB となっています。2KBを超えるPOST BODYはログに記録されません。

なお、少量のトラフィックに対して大量のリクエストが突然発生すると、Fastly ネットワークチームに DDoS トラフィックと誤認識される恐れがあります。本記事でご紹介したログの収集目的のような実装を大規模なトラフィックが想定されるプロダクション環境に実装される場合、念のため事前に [email protected] までご連絡下さい。