Fastly のログを AWS Athena で分析する

Fastly のログを AWS S3 に保存して、Athena に格納する方法をご紹介します。
Fastly のログは様々なログのエンドポイントをサポートしており、その中でよく使われているもののひとつが S3 です。ただ、多くのファイルが作成され、分析しようとするとファイルからログをマージするなど、一手間必要でしたが、Athena に取り込むことにより、全データを SQL で扱うことが可能となります。
# Fastly ログの設定
S3 への保存方法は[FastlyのログをS3に保存する](http://qiita.com/Satoshi-Ishii/items/1ec701a5d823807a3a78)で紹介しているため割愛します。
一方で、ログのフォーマット指定を容易にするため、Fastly V2 ログへのアップグレードおよびメッセージタイプの変更が必要となります。また、ログの区切り文字等の設定も行うため、この２点について説明をします。

## Fastly V2 ログへのアップグレードおよびメッセージタイプの変更
Fastly V2 ログでは apache のログフォーマットをサポートしており、V1 ではサポートしていなかったログを GUI で容易に設定できるようになっています。V2 にアップグレードすると、ダウングレードはできないので、その点には注意が必要です。（2017年2月23日時点でデフォルトが V2 になっているため、下記コマンドの `"format_version":"2"` の指定は不要です）
また、デフォルトでは Fastly のログにはプリフィックスが付加されます。Athena に読み込むために、これらは不要であるため、プリフィックスを付与しないフォーマットに変更します。
ここでは API での変更方法を紹介します。

```
curl -X PUT -H 'Fastly-Key: <Fastly-API-Token>' -H 'Content-Type: application/json' 'https://api.fastly.com/service/<Service ID>/version/<Version>/<Logtype(s3 or s3canary)>/<Logname>' --data-binary '{"format_version":"2","message_type":"blank"}'
```

API で設定を確認すると下記のような出力が得られるはずです。

```
curl -H 'Fastly-Key: <Fastly-API-Token>'  -H 'Content-Type: application/json' 'https://api.fastly.com/service/<Service ID>/version/<Version>/logging/<Logtype(s3 or s3canary)>/<Logname>'
...
"format_version": "2",
...
"message_type": "blank",
...
```

## ログの設定
V2 ログでは任意の文字をログとして挿入することが可能なので、区切り文字を容易に挿入することができます。ここではタブ(**\t**)を区切り文字として使用することとし、下記を Fastly 設定パネルの GUI にログとして設定します。実際のログ設定は [Version 2 log format](https://docs.fastly.com/guides/streaming-logs/custom-log-formats#version-2-log-format) を参照して、必要な項目を設定してください。

`%{%Y-%m-%d}t\t%{%H-%M-%S.000}t\t%h\t%{req.request}V\t%{req.http.host}V\t%{req.url}V\t%>s\t%{resp.response}V\t%{fastly_info.state}V\t%{geoip.country_code}V\t%O`

| ログ設定 | 設定内容 |
|:-----------|------------|
|%{%Y-%m-%d}t | 日付|
|%{%H-%M-%S.000}t | 時刻|
|%h | クライアント IP|
|%{req.request}V | リクエストメソッド|
|%{req.http.host}V | ドメイン名|
|%{req.url}V | リクエストパス|
|%>s | ステータスコード|
|%{resp.response}V | レスポンスのメッセージ|
|%{fastly_info.state}V | Fastly のキャッシュステータス情報|
|%{geoip.country_code}V | 接続元国コード|
|%O | レスポンスのサイズ|

これで Fastly 側のログ設定は完了です。

# Athena へのデータの取り込み
次に S3 に保存されたログを Athena に取り込む方法を説明します。
Athena は S3 のファイルをデータベースのテーブルに取り込むインターフェイスを提供しています。

例としてログが保存されているバケットを `fastly-s3log`、パスを `athena` とします。

1. Athena を選択すると下記の画面が現れるのでここでは `Get Started` 選択します。
![Screen Shot 0029-02-13 at 15.01.14.png](https://qiita-image-store.s3.amazonaws.com/0/149542/adb9795c-c198-01c6-b08b-5359a365aa56.png)
2. 下記のようなデータベースおよびテーブルを作成する画面が表示されるので、必要となる項目を入力します。
![Screen Shot 0029-02-13 at 14.57.20.png](https://qiita-image-store.s3.amazonaws.com/0/149542/e48c930d-e435-b788-7dee-d876f78a08c7.png)

ここではデータベースおよびテーブともに fastlylog としておきます。その場合の実際の設定値は
- Name of the new database : `fastlylog`
- Table name : `fastlylog`
- Location of Input Data Set : `s3://fastly-s3log/athena/` (*ここで、当初 s3 のエンドポイントが必要なのかと思い、s3://s3-us-west-2.amazonaws.com/fastly-s3log/athena/ としていて少しはまりました。ここで endpoint は不要なようです。*)
3. この画面では区切り文字を選択します。区切り文字はタブにしたので、ここでは TSV を選択します
![Screen Shot 0029-02-13 at 15.32.26.png](https://qiita-image-store.s3.amazonaws.com/0/149542/a14331f4-a016-00e6-20ff-2dc7cff016ed.png)
4. この画面ではテーブルのカラムを設定します。ログで設定したカラム分追加をしていきます（*date という型はあるのですが、なぜかこのリストには出てきません*）。面倒な場合にはここでは１つだけ設定して、最後のクエリ設定画面でテーブル作成のクエリをテキストで書いてしまうのも手です。
![Screen Shot 0029-02-13 at 15.33.39.png](https://qiita-image-store.s3.amazonaws.com/0/149542/4e36149a-12fd-b83f-8321-0d339c1564fb.png)
5. 設定が終了すると、自動的にデータベースおよびテーブル作成のクエリが実行され、テーブルの作成およびデータの読み込みがなされます。date の型はこの SQL 文を修正してテーブル作成を行うことができます。
![Screen Shot 0029-02-13 at 15.40.47.png](https://qiita-image-store.s3.amazonaws.com/0/149542/9a95afe4-3bdc-54e8-5927-a3c611660efd.png)

# Athena でのクエリ実行
テーブルが作成されるとデータに対して、クエリを投げることができます。また、**ログが追加された場合でも自動的にテーブルに読み込まれる**ようなので、取り込み処理をし直す必要がないのは非常に便利です。

下記は URL ごとに配信サイズを集計したクエリです。
![Screen Shot 0029-02-13 at 16.11.36.png](https://qiita-image-store.s3.amazonaws.com/0/149542/48528f65-0c00-90d7-1e7e-69664f729b8f.png)

Fastly ログを S3 に保存したものの、検索や集計に手間をかけているというケースには比較的容易に使えるサービスだと思います。