AWS SDK for Python (Boto3)を使ってCloudWatchの値を取得してみた

2015.07.07

サーモン大好き横山です。 今回は AWS SDK for Python (Boto3)がリリースされたということで、CloudWatchのlist-metricsget-metric-statisticsの結果を取得します。

はじめに

EC2のAmazon Linux 2015.03t2.microPowerUserAccessのRoleを適用したインスタンスを使用します。 そして、Python2.7のvirtualenv+pipでboto3をインストールしていきます。

$ mkdir -p /tmp/boto3
$ cd !:2
$ virtualenv venv27
$ . venv27/bin/activate
(venv27)$ pip install -U pip
(venv27)$ pip install boto3

boto3.clientの作成について

boto3.clientの作成ですがおおまかに2パターン作成手順があります。 インスタンスにRoleがPowerUserAccessのRole以上があたってる場合や、~/.aws/credentialsに認証情報記載の場合、以下のように書けます。 さらに、~/.aws/configにデフォルトで使用するregion情報が記載されていれば、region_nameも省略出来ます。

import boto3

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

上記以外ですと、access_key_idとsecret_access_key、default_regionを引数で設定をし、以下のように書けます。 (参考: 「AWS SDK For Python (Boto3)がリリースされました!」)

from boto3.session import Session

accesskey = os.environ.get("AWS_ACCESS_KEY_ID")
secretkey = os.environ.get("AWS_SECRET_ACCESS_KEY")
region = os.environ.get("AWS_DEFAULT_REGION")

session = Session(aws_access_key_id=accesskey,
aws_secret_access_key=secretkey,
region_name=region)

cloud_watch = session.client('cloudwatch')

今回はインスタンスにPowerUserAccessのRoleを当てて取得するので、前者を使って書いていきます。

list-metricsを取得する

CloudWatch用のクライアントを取得し、AWS CLIにもあるlist-metricsを呼び出し、 pprintモジュールを使って、取得したデータをPythonの辞書形式で整形し表示しています。

  • list_metrics.py
#!/usr/bin/env python
# coding: utf-8

import boto3
import pprint

pp = pprint.PrettyPrinter(indent=4)

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

list_metrics = cloud_watch.list_metrics()

pp.pprint(list_metrics)

実行結果

(venv27)$ python list_metrics.py
{ u'Metrics': [ { u'Dimensions': [ { u'Name': 'InstanceId',
u'Value': 'i-xxxxxxxx'}],
u'MetricName': 'CPUUtilization',
u'Namespace': 'AWS/EC2'},
{ u'Dimensions': [ { u'Name': 'InstanceId',
u'Value': 'i-xxxxxxxx'}],
u'MetricName': 'NetworkIn',
u'Namespace': 'AWS/EC2'},
{ u'Dimensions': [ { u'Name': 'InstanceId',
u'Value': 'i-xxxxxxxx'}],
u'MetricName': 'NetworkOut',
u'Namespace': 'AWS/EC2'},
... (省略) ...
{ u'Dimensions': [ { u'Name': 'InstanceId',
u'Value': 'i-xxxxxxxx'}],
u'MetricName': 'StatusCheckFailed',
u'Namespace': 'AWS/EC2'}],
'ResponseMetadata': { 'HTTPStatusCode': 200,
'RequestId': '107d4f1d-xxxx-xxxx-a1ca-cfebb41df0fb'}}

もし、namespacemetric_nameを指定して絞りこみたい場合、 適宜該当する以下のパラメータを引数に代入すると絞り込むことが出来ます。

response = cloud_watch.list_metrics( Namespace='string', MetricName='string', Dimensions=[ { 'Name': 'string', 'Value': 'string' }, ], NextToken='string' )

引用元: Boto 3 Docs 1.0.1 documentation(CloudWatch.Client.list_metrics)

get-metric−statisticsを取得する

CloudWatch用のクライアントを取得し、AWS CLIにもあるget-metric-statisticsを呼び出し、 pprintモジュールを使って、取得したデータをPythonの辞書形式で整形し表示しています。

先ほどの list-metrics に比べ、必須引数が多いです。

  • get_metric_statistics.py
#!/usr/bin/env python
# coding: utf-8

import boto3
import datetime
import pprint
pp = pprint.PrettyPrinter(indent=4)

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': 'i-xxxxxxxx'
}
],
StartTime=datetime.datetime.now() - datetime.timedelta(days=1),
EndTime=datetime.datetime.now(),
Period=300,
Statistics=['Average'])

pp.pprint(get_metric_statistics)

実行結果

(venv27)$ python get_metric_statistics.py
{ u'Datapoints': [ { u'Average': 6.14,
u'Timestamp': datetime.datetime(2015, 7, 7, 6, 0, tzinfo=tzlocal()),
u'Unit': 'Percent'},
{ u'Average': 0.1,
u'Timestamp': datetime.datetime(2015, 7, 7, 7, 35, tzinfo=tzlocal()),
u'Unit': 'Percent'},
... (省略) ...
{ u'Average': 0.034,
u'Timestamp': datetime.datetime(2015, 7, 7, 6, 45, tzinfo=tzlocal()),
u'Unit': 'Percent'}],
u'Label': 'CPUUtilization',
'ResponseMetadata': { 'HTTPStatusCode': 200,
'RequestId': '22417d15-xxxx-xxxx-a502-7d9343a00d69'}}

取得したデータは順序バラバラなので、状況に合わせてソートして使用することをオススメします。

response = client.get_metric_statistics( Namespace='string', MetricName='string', Dimensions=[ { 'Name': 'string', 'Value': 'string' }, ], StartTime=datetime(2015, 1, 1), EndTime=datetime(2015, 1, 1), Period=123, Statistics=[ 'SampleCount'|'Average'|'Sum'|'Minimum'|'Maximum', ], Unit='Seconds'|'Microseconds'|'Milliseconds'|'Bytes'|'Kilobytes'|'Megabytes'|'Gigabytes'|'Terabytes'|'Bits'|'Kilobits'|'Megabits'|'Gigabits'|'Terabits'|'Percent'|'Count'|'Bytes/Second'|'Kilobytes/Second'|'Megabytes/Second'|'Gigabytes/Second'|'Terabytes/Second'|'Bits/Second'|'Kilobits/Second'|'Megabits/Second'|'Gigabits/Second'|'Terabits/Second'|'Count/Second'|'None' )

引用元: Boto 3 Docs 1.0.1 documentation(CloudWatch.Client.get_metric_statistics)

Python3系で動くのか

気になるので少しやってみました。 デフォルトでPython3系が入っていませんので、yumでPython3.4を入れてvirtualenvで新規環境を作って動かしてみます。

準備

Python3系を指定する以外はコマンドはほぼ変わりません。

(venv27)$ deactivate
$ sudo yum install -y python34
$ virtualenv -p /usr/bin/python34 venv34
$ . venv34/bin/activate
(venv34)$ pip install -U pip
(venv34)$ pip install boto3

実行結果

Python3系でも問題なく動作しました。

(venv34)$ python -V
Python 3.4.3
(venv34)$ python list_metrics.py
... (前略) ...
{ 'Dimensions': [ { 'Name': 'InstanceId',
'Value': 'i-b8dfb04d'}],
'MetricName': 'StatusCheckFailed_Instance',
'Namespace': 'AWS/EC2'},
{ 'Dimensions': [ { 'Name': 'InstanceId',
'Value': 'i-b8dfb04d'}],
'MetricName': 'StatusCheckFailed',
'Namespace': 'AWS/EC2'}],
'ResponseMetadata': { 'HTTPStatusCode': 200,
'RequestId': '4d8d5fdb-xxxx-xxxx-8d60-93ad6f712859'}}
(venv34)$ python get_metric_statistics.py
... (前略) ...
{ 'Average': 0.0,
'Timestamp': datetime.datetime(2015, 7, 7, 7, 3, tzinfo=tzlocal()),
'Unit': 'Percent'},
{ 'Average': 0.034,
'Timestamp': datetime.datetime(2015, 7, 7, 6, 13, tzinfo=tzlocal()),
'Unit': 'Percent'}],
'Label': 'CPUUtilization',
'ResponseMetadata': { 'HTTPStatusCode': 200,
'RequestId': '7d74412b-xxxx-xxxx-93af-8bdf83074ff7'}}

まとめ

以前のバージョンに比べかなりシンプルにAWSを操作する部分を書けると感じました。 AWS CLIのコマンド名と互換性のある関数名ですので、関数名が分からなくても、 コマンド名から動作を予測すること出来ると思います。