Fastly のログを BigQuery に取り込んでみる

[Fastly のログを AWS Athena で分析する](http://qiita.com/Satoshi-Ishii/items/ac8175f0aab3d4a30bdb)で AWS への取り込みをやってみたので、GCP でもと思い、BigQuery への取り込みについても書いてみます。

# Google Cloud Storage(GCS) へのログ保存設定
Fastly のログを GCS に保存するために、GCS にバケット等の設定を行います。
## Project の作成
はじめにログを保存する GCS を使うために、プロジェクトの作成を行います。GCP にログオン後、下記のメニューからプロジェクトの作成をします。名前は任意で問題ありません。

![Screen_Shot_0029-02-24_at_00_20_40.png](https://qiita-image-store.s3.amazonaws.com/0/149542/f3fb6bf9-8b70-d175-650a-42eb7e11c6b4.png)

## GCS バケットの作成
Google Cloud Platform のメニューから `Storage` を選択し、`Create bucket` からバケットの作成を行います。ここで名前は `fastly-log` としておきます。
また、作成したバケットの配下に `bigquery` というフォルダを作っておきます。
## Service Account の作成
作成した GCS にアクセスするためのアカウントを作成します。
Google Cloud Platform のメニューから `IAM & Admin` を選択し、`Service Account` から `CREATE SERVICE ACCOUNT` を選択すると下記の画面が開きます。

<img width="508" alt="Screen_Shot_0029-02-25_at_13_40_41.png" src="https://qiita-image-store.s3.amazonaws.com/0/149542/f9dda866-aa5a-d353-d304-9fabbff93fa6.png">

必要な情報を入力しますが、ここでは Role を `Project - Owner` とし、名前や Service Account ID 任意で設定してください（実際には環境に応じて適切なロールを設定してください）。`Furnish a new private key` にチェックを入れ、Key type は JSON とします。これで CREATE すると 下記のような JSON 形式のファイルがダウンロードされます。

```
{
  "type": "service_account",
  "project_id": "<PJ NAME>",
  "private_key_id": "....",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMII...\n-----END PRIVATE KEY-----\n",
  "client_email": "<SERVICE ACCOUNT ID>@<PJ NAME>.iam.gserviceaccount.com",
  "client_id": "...",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/<SERVICE ACCOUNT ID>%40<PJ NAME>.iam.gserviceaccount.com"
}
```

上記の `private_key` および `client_email` は Fastly ログ設定で利用します。

# Fastly ログの設定

## GCS へのログ保存設定

基本的なログ設定の流れは[Fastly S3 Log の設定](http://qiita.com/Satoshi-Ishii/items/1ec701a5d823807a3a78#fastly-s3-log-%E3%81%AE%E8%A8%AD%E5%AE%9A)を参照して下さい。ここでは GCS なので、作成時には GCS のアイコンを選択します。

<img width="155" alt="Screen Shot 0029-02-25 at 14.17.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/149542/020a9d62-5c7d-ebe4-3d59-9085501ea9db.png">

表示される設定画面で各種設定を行います。

<img width="804" alt="Screen_Shot_0029-02-25_at_15_51_36.png" src="https://qiita-image-store.s3.amazonaws.com/0/149542/71c2d4b3-62f0-e394-fcd9-6caa6b56f38c.png">

Name: ログの名前を設定します。
Log Format: ログに出力する項目を設定します。フォーマットは [Custom log formats](https://docs.fastly.com/guides/streaming-logs/custom-log-formats) を参照してください。ここでは BigQuery 取り込み用に csv の形式にするために `,` 区切りに
します。ここでは以下のように設定します。
`%{%Y-%m-%d}t,%{%H-%M-%S.000}t,%h,%{req.request}V,%{req.http.host}V,%{req.url}V,%>s,%{resp.response}V,%{fastly_info.state}V,%{geoip.country_code}V,%O`
Email: GCP の Service Account で設定した client_email を設定します。GCP の実際のアカウントで使う e-mail ではないので注意して下さい。
Bucket Name: GCS で設定したバケット名を設定します。ここでは fastly-log となります
Secret key: GCP の Service Account で取得した pricate_key を入力します。文字列に含まれる改行コード `\n` もそのまま入力して下さい
Period: ファイルのローテーション間隔です。 288000 秒（8時間）としています。

さらに `Advanced Options` をクリックすると、さらに設定項目が表示されるので、Path の設定をここで行います。

Path: バケット内にフォルダがある場合には設定します。末尾に"/"をつけるのを忘れないでください。ここでは `bigquery/` とします
Gzip Level: 圧縮する場合にはこの数値を設定します。非圧縮がデフォルトで 0 となっています

以上の項目を入力し、「CREATE」をクリックします。

## メッセージタイプの変更およびログの設定
これについては[Fastly V2 ログへのアップグレードおよびメッセージタイプの変更](http://qiita.com/Satoshi-Ishii/items/ac8175f0aab3d4a30bdb#fastly-v2-%E3%83%AD%E3%82%B0%E3%81%B8%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89%E3%81%8A%E3%82%88%E3%81%B3%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%BF%E3%82%A4%E3%83%97%E3%81%AE%E5%A4%89%E6%9B%B4)と基本同じなのでそちらを参照してください。

これらが終了したら、設定を有効化するために「ACTIVATE」します。
以上で、GCS に Fastly ログが csv で出力されるようになります。

# BigQuery への取り込み
ここまでの設定で GCS にログが出力されるようになりました。次に `bq` コマンドを用いて BigQuery に取り込みます。
はじめに SDK のインストールが必要です。手順については、ここでは割愛しますが、
https://cloud.google.com/sdk/docs/quickstarts
で紹介されているので、参照して下さい。
## 認証とプロジェクトの選択
bq コマンドを使うために、認証とプロジェクトの選択を行います。

```
$ gcloud auth login
```
によりブラウザ上で認証をします。その後

```
$ gcloud config set project <PROJECT>
```
によりプロジェクトの選択を行います。\<PROJECT\> には「Project の作成」で作成したプロジェクトの名前を入れます。
これで GCS 上のログを bq コマンドで操作する準備が整いました。

## データセットおよびテーブルの作成
はじめにデータセットの作成、その後、そのデータセットにテーブルの作成を行います。
データセットを `fastly`、テーブルを `fastly_log_table` とします。

```
$ bq mk fastly
```
続けて

```
$ bq mk fastly.fastly_log_table
```
確認するには下記の `ls` を利用します。

```
$ bq ls
  datasetId  
 ----------- 
  fastly     
$ bq ls fastly
      tableId        Type   
 ------------------ -------  
  fastly_log_table   TABLE  
```

## データのロード
テーブルが作成できたらデータのロードを行います。カラムの作成も含めて `load` で行うことが可能です。ここでは 2017年2月22日のファイルをまとめて取り込むために以下のコマンドを実行します。

```
$ bq load fastly.fastly_log_table gs://fastly-log/bigquery/2017-02-22T* date:string,time:string,clientip:string,method:string,host:string,url:string,status:string,message:string,infostate:string,country:string,size:integer
```
このコマンドをバッチで日付部分を変えながら実行すれば、自動的に作成されたデータを読み込むことが可能となります。

## 補足：クエリでのデータ確認
Fastly では fastly_info.state という変数で HIT/MISS/PASS などの情報を取得することができます。どの URL で MISS が多く、キャッシュヒット率をどうやって上げられるかなどは、この情報を解析することが有効です。
例えば、下記のようなクエリを使うと MISS の多い URL を抽出することが可能です。

```
bq query "select url,count(url) as count from fastly.fastly_log_table where infostate contains 'MISS' group by url order by count desc;"

+-------------+-------+
|     url     | count |
+-------------+-------+
| /           |   432 |
| /index.html |    25 |
+-------------+-------+
```