re:dashのpythonデータソースでCloudWatchのメトリクス取得してみる


re:dashはデータソースにpythonが使えるとは書いてあるものの、あまりドキュメントには情報が載っていないため、簡単な実行例を書いてみようと思います。

# 概要
基本的には、”result”という名前の辞書型の変数に
http://docs.redash.io/en/latest/dev/results_format.html
で指定されたフォーマット通りに値を入れておけば勝手に認識してくれます。

# データソースの追加
データソースの追加画面に行って、typeをPythonにし、importを許可するmoduleをカンマ区切りで入力します。
後で使うため、boto3とdatetimeを入力しています。

## サンプルクエリの記述
クエリのデータソースを、先程追加したデータソースにし、以下のクエリを入力します。

```
result = {}

add_result_row(result, {'name':'hoge', 'count':5, 'countf':6.3})
add_result_row(result, {'name':'bar', 'count':11, 'countf':3.14159})
add_result_row(result, {'name':'foo', 'count':0, 'countf':99.9999})

add_result_column(result, 'name', '', 'string')
add_result_column(result, 'count', '', 'integer')
add_result_column(result, 'countf', '', 'float')
```

add_result_rowと、add_result_columnというヘルプメソッドがデフォルトで用意されているので、
カラム定義や行の定義はこれらを用いています。

add_result_rowは行の追加を行います。
カラム名とvalueがペアになった辞書型を第二引数に渡してやれば、いいようにresultに追加してくれます。

add_result_columnはカラム定義の追加をします。
第二引数にカラム名(add_result_rowに追加する辞書型に対応した名前)
第三引数に表示用の名前
第四引数に型(string,integer,float,boolean,date,datetimeに対応)
を指定します。

実行すると以下の様な結果が得られます。
![スクリーンショット 2015-12-25 17.52.46.png](https://qiita-image-store.s3.amazonaws.com/0/1412/743b1e75-8f2f-bf1c-01fd-4fc931dace86.png)

## 外部データを参照するクエリの記述
先ほどのクエリだとデータがソースにベタ書きされて面白く無いので、外部データを取得するクエリを記述してみます。

今回は、Amazon CloudWatchでインスタンスのCPU使用率を取得してみます。

### 準備
OSは公式で配布されているubuntuのAMIを用います。


予め、```sudo pip install boto3```でboto3をインストールしておきます。
また、IamRoleでCloudWatchへのアクセスを許可しておきます。

## クエリの作成
新規にクエリを作成し、以下の様なコードを記述します。
```'Value': 'target-instanceId'```の所には、取得したいインスタンスのIDを書いておきます。

また、re:dashのグラフは日付より細かい単位で表示することが出来ないため、```Period=3600```とし、1時間単位の平均を取るようにしています。

cloud_watch.get_metric_statisticsの帰り値をループで回し、CPU使用率と日付をrowに追加していっています。

cloud_watch.get_metric_statisticsの詳しい返り値に関しては、[クラスメソッドさんのブログ](http://dev.classmethod.jp/cloud/aws/get_value_of_cloudwatch_using_boto3/)を参照して下さい。


```Python3
import boto3
import datetime

result = {}

cloud_watch = boto3.client('cloudwatch', region_name='ap-northeast-1')

get_metric_statistics = cloud_watch.get_metric_statistics(
                            Namespace='AWS/EC2',
                            MetricName='CPUUtilization',
                            Dimensions=[
                                {
                                    'Name': 'InstanceId',
                                    'Value': 'target-instanceId'
                                }
                            ],
                           StartTime=datetime.datetime.now() - datetime.timedelta(days=1),
                           EndTime=datetime.datetime.now(),
                           Period=3600,
                           Statistics=['Average'])

for d in get_metric_statistics['Datapoints']:
    add_result_row(result, {'average':d['Average'], 'datetime':d['Timestamp']. isoformat()})

add_result_column (result, 'average', 'aaaaa', 'float')
add_result_column (result, 'datetime', '', 'datetime')
```

これを実行すると、以下の様な結果が得られます。
![スクリーンショット 2015-12-25 18.11.46.png](https://qiita-image-store.s3.amazonaws.com/0/1412/3034d545-3788-8b01-928b-e6683abfa192.png)


また、折れ線グラフにするとこういうデータになります。
![スクリーンショット 2015-12-25 18.12.32.png](https://qiita-image-store.s3.amazonaws.com/0/1412/8c66d16d-79dc-a42a-a7de-23f45d04ad12.png)


最新のデータを取得し、アラートを設定するようにすれば監視サーバのように使うことも出来ます。