Fastly での配信帯域データを保存する

Fastly の STATS 画面では過去の Byte per minutes の情報を取得することは可能ですが、さらに細かい秒単位での帯域 (bit per seconds) を確認することができません。
ここでは、秒単位での配信容量の取得および保存方法について紹介します。

# STATS
過去データについては基本的に STATS 画面にて確認することができます。ただし、STATS 画面にて確認可能なデータは `Sample by` 選択した単位での値となります。選択できるのは表示範囲にもよりますが、Minute, Hour, Day となるため、秒間での値を表示することはできません。
![Screen_Shot_0029-04-25_at_19_49_14.png](https://qiita-image-store.s3.amazonaws.com/0/149542/c45da697-0fea-d4b8-44bc-3920185c56e9.png)


# DASHBOARD
現在のデータの状況は DASHBOARD の BANDWIDTH より確認することができます。しかしながら、このデータはリアルタイムに表示確認することが目的のため、過去データを遡って確認することができません。

<img width="1023" alt="Screen Shot 0029-04-24 at 21.50.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/149542/fcad31fa-f571-5b85-06c8-8b8d9fe1ae9f.png">

# Real-time Analytics
API を利用することにより、秒単位での配信量を取得することが可能です。この数値を継続的に取得することにより、bps の値を収集することが可能になります。
それでは具体的な取得方法を紹介します。

## Real-time Analytics API
API は下記を利用します。その他、詳細については [Real-time Analytics](https://docs.fastly.com/api/analytics) を参照してください。この API により各秒間における、配信量やリクエスト数などのデータを JSON 形式で出力されます。

```
curl -s -H 'Fastly-Key: <API TOKEN>' -H 'Content-Type: application/json' 'https://rt.fastly.com/v1/channel/<SERVICE ID>/ts/<TIMESTAMP>'
```

* API TOKEN: Fastly API Token です。API Token の発行方法については　[API tokens](https://docs.fastly.com/api/auth#tokens) で発行します。
* SERVICE ID: データを取得したいサービス ID
* TIMESTAMP: UNIX 時間（1970年1月1日からの経過秒数）。ここで指定した時刻以降のデータが出力されます。

## データの収集手順

### 1. Timestamp の取得
API を利用して最初に設定すべき Timestamp を UNIX 時間で取得します。

```
$ curl -s -H "Fastly-Key: <API TOKEN>"  -H "Content-Type: application/json" "https://rt.fastly.com/v1/channel/<SERVICE ID>/ts/0"|jq '.Timestamp'
```
### 2. API の出力を保存
API をコールし、結果を保存します。TIMESTAMP には 1 で取得した値を利用します。

```
$ curl -s -H "Fastly-Key: <API TOKEN>"  -H "Content-Type: application/json" "https://rt.fastly.com/v1/channel/<SERVICE ID>/ts/1493039557" > rt_1493039557.json
```

### 3. 各秒の配信容量を取得
ここでは JSON のパース、フィルタに jq コマンドを利用しています。帯域計算に必要な resp_header_bytes (配信ヘッダ容量)、resp_body_bytes (配信ボディ容量) およびタイムスタンプを bw_service.json に追記していきます。

```
$ cat rt_1493039557.json | jq '.Data[]|{Recorded:.recorded, Header: .aggregated.resp_header_bytes, Body: .aggregated.resp_body_bytes}' >> bw_service.json
```
実際に追記されているデータは下記のようになります。

```
{
  "Recorded": 1493039563,
  "Header": 1100,
  "Body": 137
}
...
{
  "Recorded": 1493039578,
  "Header": 618,
  "Body": 137
}
{
  "Recorded": 1493039581,
  "Header": 618,
  "Body": 137
}
```

このデータの Recorded が対象時間、Header と Body の和が配信容量となります。配信がなかった時間は Recorded として表示されません。この場合、1493039581 の bps は 
(618 + 137) * 8 = 6,040 bps (6.04Kbps)
となります。一方、1493039580 などはデータが存在しない（配信データがなかった）ため、0 bps であったといえます。

### 4. Timestamp の取得
2 で取得した API の結果には次に指定すべきタイムスタンプが含まれているため、その値を取得します。

```
$ cat rt_1493039557.json | jq '.Timestamp'
1493039590
```

### 5. 2 に戻る
2 に戻り繰り返し処理を行います。2 で用いられる TIMESTAMP は 4 で取得した値とします。また、不要であれば、rt_1493039557.json を削除します。

## サンプルスクリプト
参考までにサンプルスクリプを紹介します。ここでは API の出力結果をファイルではなく変数に挿入しています。
`rtstats.sh`：スクリプトファイル
`config`：実行に必要な情報を記載。スクリプトファイルと同じ場所に配置。 
rtstats.sh を実行すると、DURATION で記載した回数分約1分ごとにデータを取得します。

### rtstats.sh ファイル
エラー処理は省略しているので、必要に応じて挿入してください。

```
#!/bin/bash

CMDNAME=`basename $0`
DIRNAME=`dirname $0`

### Get Key/SID from config file ###
Key=`cat $DIRNAME"/"config| grep Key| cut -d":" -f2`
SID=`cat $DIRNAME"/"config| grep ServiceID| cut -d":" -f2`
BWFILE=`cat $DIRNAME"/"config| grep BWFILE| cut -d":" -f2`
DURATION=`cat $DIRNAME"/"config| grep DURATION| cut -d":" -f2`

### Get Now ###
i=0
while [ $i -lt $DURATION ]
do

  ### Set Timestamp ###
  if [ $i -eq  0 ]; then

    ### Get initial TIMESTAMP ###
    TIMESTAMP=`curl -s -H "Fastly-Key: $Key" -H "Content-Type: application/json" "https://rt.fastly.com/v1/channel/$SID/ts/0"|jq '.Timestamp'`
  else
    TIMESTAMP=$LATEST_TS
  fi

  ### Store realtime json ###
  RT_STATS_JSON=`curl -s -H "Fastly-Key: $Key" -H "Content-Type: application/json" "https://rt.fastly.com/v1/channel/$SID/ts/$TIMESTAMP"`

  ### Get Header/Body volume ###
  echo -e "$RT_STATS_JSON"|jq '.Data[]|{Recorded:.recorded, Header: .aggregated.resp_header_bytes, Body: .aggregated.resp_body_bytes}' >> $BWFILE   

  ### Get Latest Timestamp ###
  LATEST_TS=`echo -e "$RT_STATS_JSON"|jq '.Timestamp'` 

  i=`expr $i + 1`
  sleep 60
done
exit 0
```

### config ファイル

```
Key:<API TOKEN>
ServiceID:<SERVICE ID>
BWFILE:<FILE NAME>
DURATION:<NUMBER OF REPEAT>
```
Key: API Token
ServiceID: データを取得するサービス ID
BWFILE: 最終的な結果ファイルを出力するファイル名
DURATION: データを収集する期間（約 DURATION 分）

上記は Linux コマンドラインによる処理を例としていますが、perl, ruby などでも同様の処理でデータの収集は可能なので、ご自身にあった環境をご利用ください。