Ingestly の計測エンドポイントを構成する (Fastly + BigQuery)

[Ingestly / リアルタイムウェブ解析](https://qiita.com/hsano/items/dcb4be5bd210b54390be) でIngestlyについては紹介しましたが、ここでは実際に環境を構築する流れを説明します。
Ingestlyは高性能なCDNである[Fastly](https://www.fastly.com)と、Googleのデータウェアハウスである[BigQuery](https://cloud.google.com/bigquery/)を組み合わせ、独自ドメイン（つまりファーストパーティ）で計測エンドポイントを構成できるのが特徴です。
FastlyもBigQueryも、フルマネージドサービスなので、一度構成してしまえば基本的にその後は手を付ける必要がなく、インフラの保守どころかキャパシティ調整のような作業も一切不要で、Google Analyticsのような既製ツールと同じように手放しで使えるようになっています。

※ 基本的には Ingestly-Endpoint の [README](https://github.com/ingestly/ingestly-endpoint/blob/master/README-JP.md) の通り。

# 前提
- 独自ドメインを保有している
- DNSを設定できる（Google Domainsやムームードメインのような一般的なドメイン登録サービスはDNSサービスも付いてくることが多い）
- Googleアカウントを持っていて、BigQueryが有効化されている
- まだFastlyに登録していない
- 無料枠を利用する
    - GCPはアカウント開設して1年以内、課金情報を登録していない（無料枠）
    - Fastlyは最初の$50分の利用が無料なのでその範囲内（独自ドメインでSSL証明書を設定するのが有料なので、非SSLの独自ドメイン運用か、共用SSLで非独自ドメイン運用かを決める）


# Google BigQuery

## Fastly用のサービスアカウントを作る

GCPのコンソールで「サービスアカウント」メニューを開く
<img width="497" alt="スクリーンショット 2019-07-13 23.38.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/e2fd6a3a-778f-c1e9-05d1-33e650fc541b.png">

（プロジェクトが未作成であれば適当に作り、既にあれば既存のプロジェクトを選択してもいい）

画面上部の「+ サービスアカウントを作成」を押して作成画面に入り…

<img width="446" alt="スクリーンショット 2019-07-13 23.40.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/f4701400-0775-af29-a901-4e42654be6f5.png">

「ingestly」等、適当な名前でサービスアカウントを作る。

<img width="579" alt="スクリーンショット 2019-07-13 23.40.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/b8927d72-983e-54c4-cd03-22525dfa376f.png">

権限として「BigQuery データオーナー」を付与する。

<img width="830" alt="スクリーンショット 2019-07-13 23.42.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/54a18167-696e-f3db-36db-0bd31a0e6f35.png">

そして次の画面で、「サービスアカウント」は特に操作せず、画面下部の「キーの作成（オプション）」から認証情報を生成する。

<img width="560" alt="スクリーンショット 2019-07-13 23.45.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/05df6637-f731-eb7b-b086-23cc6ab24635.png">

作成をクリックし、「JSON」形式で作成する。

<img width="555" alt="スクリーンショット 2019-07-13 23.45.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/11d3cc95-5f9b-2bee-493a-b706c36801f7.png">

作成が完了すると「秘密鍵がパソコンに保存されました」と表示され、json形式のファイルがダウンロードされる。
jsonファイルの中から、 `private_key` と `client_email` の値を控えておく。

<img width="561" alt="スクリーンショット 2019-07-13 23.48.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/478eb3d5-2e21-d1a7-876f-b94e2812a256.png">
 
## Ingestlyのデータ（ログ）を入れるテーブルを作成する

GCPのコンソールで「BigQuery」メニューを開く

<img width="307" alt="スクリーンショット 2019-07-13 23.52.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/c0536d63-fcdb-2c03-82e4-ed661067a2dc.png">

既存のデータセットを使う場合は選択、新たに構成する場合は Ingestly 等適当に作成する。
クエリーエディタの右下にある「データセットを作成」を開き…

<img width="192" alt="スクリーンショット 2019-07-13 23.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/5ebae57c-0e51-e141-3e14-71e0262ce90e.png">

データセットIDを入力すればOK。
ロケーションや有効期限については、各々のポリシーに従って適切に選べばよい。

<img width="291" alt="スクリーンショット 2019-07-13 23.54.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/27fcd0e1-d58a-25a5-70ed-2d48ae039d58.png">

左メニューの「リソース」に作成したデータセットが現れるので選択し…

<img width="288" alt="スクリーンショット 2019-07-13 23.58.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/1f36c542-06d1-b755-f187-c728ea066842.png">

クエリーエディタ右下の「テーブルを作成」をクリックしてテーブルを作る

<img width="200" alt="スクリーンショット 2019-07-13 23.58.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/94050181-4d38-a03f-bf31-dab72dbfda59.png">

テーブル名を指定したら、「スキーマ」セクションの「テキストとして編集」をオンに。

<img width="667" alt="スクリーンショット 2019-07-14 0.01.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/cf9363a8-6c7a-5aee-c5a9-5ed397f1c45b.png">

カラム追加のボタンがテキストエリアに切り替わるので、[Githubの Ingestly-Endpoint にあるテーブルスキーマ](https://github.com/ingestly/ingestly-endpoint/blob/master/table_schema)を、

<img width="397" alt="スクリーンショット 2019-07-14 0.02.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/5e3b6165-916d-d340-c2a4-45786fc8d627.png">

以下のように、コピー＆ペーストする。

<img width="454" alt="スクリーンショット 2019-07-14 0.07.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/86a8732e-8809-c8ee-2b7b-8a57ad994a54.png">

終わりに「パーティショニング」で `timestamp` を選択したら、「テーブルを作成」を押して完了。

<img width="245" alt="スクリーンショット 2019-07-14 0.08.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/0b7850b8-2415-1d84-22f8-ae444bfff410.png">


以上で、GCP側のIAMとBigQueryの設定が整う。
続いてFastly側の設定をする。

# Fastly

## アカウント開設

まず、[Fastlyのサイト](https://www.fastly.com)を開き、画面右上の「Sign up」と書かれた緑のボタンを押す。
フォームに必要事項を入力したら、「Sign up for Fastly」をクリック。

<img width="578" alt="スクリーンショット 2019-07-14 0.11.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/11d8ba93-33db-e786-c5c0-6cccc1bde6c3.png">

しばらく（10分以内とのこと。自分は10分ではメール来なかった…）すると確認メールが届く。アクティベーションを済ませてログインする。

<img width="373" alt="スクリーンショット 2019-07-14 0.40.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/858ee7ad-47cd-a179-645c-a3228725aa1e.png">

## バックエンドを設定する

まず、「Origins」メニューの 「Hosts」を開く。

<img width="271" alt="スクリーンショット 2019-08-06 0.40.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/f5496c89-3bb0-4638-7fd7-52a0e38b4c95.png">

最低限ここに何か値を入れないと進まないので、自サイトや自身の適当な（空でも可）S3を宛先に指定する。実際にアクセスできなくてもIngestlyの動作に影響はない。


## ドメインを設定する

次に、HOME画面右上の「+ CREATE SERVICE」を押してドメインの作成を開始する。

<img width="260" alt="スクリーンショット 2019-07-14 0.29.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/54d9671f-9adb-0112-5d91-9f3a37cddf99.png">

左メニューの「Domains」を開くと、「CREATE YOUR FIRST DOMAIN」ボタンが現れるので、これをクリック。

<img width="500" alt="スクリーンショット 2019-07-14 0.42.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/5d9f2f1b-f35f-4b2d-f465-907396de5656.png">

ドメイン名を入力するが、ここは2通りの方法を検討して決める。

<img width="798" alt="スクリーンショット 2019-07-14 0.56.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/7761e679-8fbd-1740-5e88-c9238dc466ba.png">


**A. 完全に独自ドメインにする（有償SSLオプション）**

- $100/月かかる
- ファーストパーティCookieが利用でき、ITP2.2でも安心
- 「Domain Name」として、好みのドメインに対してサブドメインを指定する（例：stat.example.com）
- DNSの設定で、CNAMEとしてサブドメインの宛先を別途Fastlyの有償SSLオプションを設定するときに通知される宛先にする

**B. HTTPのみ（HTTPSを使わない）前提で独自ドメインにする（無料枠）**

- 無料枠で利用できる
- ChromeがhttpsのCookieでないとブラウザの識別制度が落ちる問題がある
- サイトがhttpsの場合、mixed content警告が出る
- 「Domain Name」として、好みのドメインに対してサブドメインを指定する（例：stat.example.com）
- DNSの設定で、CNAMEとしてサブドメインの宛先を「nonssl.global.fastly.net.」にする

**C. fastly.net共有ドメインでHTTPS対応する（無料枠）**

- 無料枠で利用できる
- サーバーサイドCookie的にはサードパーティCookieになるので、Safariでのブラウザ識別制度が下がる可能性がある。Ingestlyの計測SDKはlocalStorageを組み合わせるので、サブドメインが同じであればフォールバック機構が働き影響は無い（将来的に使えなくなる可能性あり）
- 「Domain Name」として、fastly.net以下で運用する任意の空いているサブドメインを指定する（例：example.global.ssl.fastly.net）ただし、既に他で利用されているサブドメインだと「~ taken by another customer」エラーが発生するので別のサブドメインを検討する。


いずれの方法でも、ここで指定したドメインが計測エンドポイントとして機能するので、メモしておくこと。

## カスタムVCLの登録

計測SDKから送られてくるリクエストを捌き、Cookieやレスポンスを制御するために、カスタムVCLを使う。

左メニューの「Custom VCL」を開く。

<img width="321" alt="スクリーンショット 2019-07-14 0.57.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/c6bcc027-78d7-ea5a-b4bf-10cd3dbfc178.png">

「UPLOAD YOUR FIRST VCL FILE」を押すとVCLファイルのアップロード画面が開く。

<img width="411" alt="スクリーンショット 2019-07-14 0.57.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/3f5979fa-8c65-a17a-1618-ce586ae4e7d9.png">


[Githubの Ingestly-Endpoint にあるVCLファイル](https://github.com/ingestly/ingestly-endpoint/blob/master/ingestly.vcl)をダウンロードして、2行目の `cookie_domain` の値を、前の設定で決めたドメインにする。

<img width="296" alt="スクリーンショット 2019-07-14 22.38.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/69ac777d-d559-44a4-0220-2b6c75cd86f1.png">

ドメインを指定したら、ファイルを選択してアップロード、任意の名前を指定して「CREATE」をクリック。

<img width="716" alt="スクリーンショット 2019-07-14 0.59.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/41163a3f-8709-0ed6-4523-d1698755987a.png">

## BigQuery連携の設定

BigQuery連携は Logging 機能を使うので、左メニューから「Logging」を開く。

<img width="317" alt="スクリーンショット 2019-07-14 1.03.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/5f8350b4-8436-09ff-f889-1b7f24374fb0.png">

ゴミデータが入らないよう、ログをBigQueryに記録する条件を指定するので、「attach a condition」をクリックして条件指定に進む。

<img width="690" alt="スクリーンショット 2019-07-14 1.04.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/8b60b023-8119-5e1b-7499-b3a24e0efe85.png">

Conditionでは任意の名前を付けた上で、GithubのREADMEにもある通り以下の文字列をコピー＆ペーストで指定する。
意味は、http204かつ `/ingestly-ingest/` で始まるパスの場合と、http200かつ `/ingestly-sync/` で始まるパスの場合にログを残す、ということ。

```
(resp.status == 204 && req.url ~ "^/ingestly-ingest/(.*?)/\?.*" || resp.status == 200 && req.url ~ "^/ingestly-sync/(.*?)/\?.*")
```

Save and Apply を押して保存したら、[Githubの Ingestly-Endpoint にあるログフォーマットファイル](https://github.com/ingestly/ingestly-endpoint/blob/master/log_format)の内容を、「Log format」のテキストボックスにコピー＆ペーストする。

<img width="859" alt="スクリーンショット 2019-07-14 1.10.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/9c3a632a-09f8-f7e8-f818-2ff868f935fe.png">

さらにその下にある 「Email」には冒頭の「Fastly用のサービスアカウントを作る」のステップで控えておいた `client_email` の値を入力、「Secret Key」にも同 `private_key` の値を貼り付ける。

<img width="816" alt="スクリーンショット 2019-07-14 1.11.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/5934abd9-faa3-527a-9296-f8e85a06a0b3.png">

続いてテーブル情報として、Project ID、Dataset、Table をそれぞれBigQueryでテーブルを作成した際の情報に基づいて入力する。

<img width="572" alt="スクリーンショット 2019-07-14 1.14.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107873/4cd49c9c-ca48-d962-36eb-7b3a432644d5.png">

「Template」はテーブル名の書式だが、パーティションできるようになっているので今回は指定しない。
（時系列でテーブル分割をする場合はフォーマットを入れてもOK）

「CREATE」を押して設定完了。


# おわりに
- BigQuery側の設定は、慣れている人なら数分でできるような、ごく普通の設定のみ
- Fastlyはアカウント開設に少し戸惑うかもしれない（なかなか確認メールが届かないし）ものの、設定は一度やってしまえば変更することはないので落ち着いてすすめれば大丈夫
- Fastlyは日本語サポートがしっかりしていて、サポートチケットを作っても、Twitterでつぶやいても、しっかりフォローしてくれる
- すでにFastlyを使っている場合、既存の設定に対してカスタムVCLとログの設定を追加することで、即利用開始できる（パスによるフィルターを設定するのはこのため）