CloudWatchからAWSの費用を視覚化してみた(の補足的情報だけ)

お久しぶりのエントリは、「Estimated Charge with CloudWatchを試してみました « サーバーワークス エンジニアブログ」こちらの記事をパクリ参考にさせていただきました。

詳しくは、サーバーワークスさんのブログエントリを参照してもらえば問題ないのですが、ちょっとはまったところがあるのでその点について触れておきます。

ハマったポイント

口座番号は整数で。

元記事やgistのソースでは、

ACCOUNT_NUMBER = 'YOUR_ACCOUNT_NUMBER'

のように示されているので、口座番号(Account Number)を文字列として定義してしまっていましたが、それではうまく動かずかなりハマりました。口座番号は整数で以下のように書きましょう。

ACCOUNT_NUMBER = 123456789012
dimentionsのLinkedAccountはConsolidated Billingを利用しており、かつ個別のアカウントの金額を取得したい場合のみ

こちらもハマった点。個人用アカウントは特に別アカウントがあるわけではなく、Consolidated Billing (複数アカウントの一括請求)を使っていないので、そもそも 「LinkedAccount」というdimentionは存在しないようだ。さらには、Consolidated Billingを使っている場合でも、全アカウントのトータルコストを取得したい場合には、LinkedAccountを指定してはいけない。

Consolidated Billingを使用していない、または、Consolidated Billingを使っていて合算した費用が知りたい場合

下のように、dimentionsには{"Currency"=>"USD"}のみを指定する。

data = acw.get_metric_statistics(options={:dimentions => {"Currency"=>"USD"},
                                          :measure_name => "EstimatedCharges",
                                          :namespace => "AWS/Billing",
                                          :start_time => starttime,
                                          :end_time => endtime,
                                          :period => 86400})
Consolidated Billingを利用していて、個別アカウントの費用が知りたい場合

こちらは、サーバーワークスさんの例の通り、LinkedAccountを指定する。

data = acw.get_metric_statistics(options={:dimentions => {"LinkedAccount"=>ACCOUNT_NUMBER, "Currency"=>"USD"},
                                          :measure_name => "EstimatedCharges",
                                          :namespace => "AWS/Billing",
                                          :start_time => starttime,
                                          :end_time => endtime,
                                          :period => 86400})

グラフを重ねる

元記事の方で使われているグラフライブラリのGruffは簡単にグラフを重ねられるので、トータル(LinkedAccount指定なし)と個別アカウント1と個別アカウント2をまとめてグラフ化なんてことも楽チン。

それぞれの金額遷移のリストを取得しておいて、以下のようにするだけ。

total_charge_list = 取得処理やらソート処理
acc1_charge_list = 取得処理やらソート処理
acc2_charge_list = 取得処理やらソート処理

graph_file = "#{Time.now.strftime('%Y-%m-%d')}-charge_graph.png"
g = Gruff::Line.new
g.title = "AWS Cost"
g.marker_font_size = 15
g.data("Total", total_charge_list)
g.data("account1", acc1_charge_list)
g.data("account2", acc2_charge_list)
g.labels = {0 => '5days ago', 1 => '4days ago', 2 => '3days ago', 3 => '2days ago', 4 => 'yesterday'}
g.write(graph_file)

これで、3つの線グラフを重ねたpngファイルが作成されます。簡単ですね。

最後に

参考にさせていただいたサーバーワークスさん、本当にありがとうございました!これで色々はかどります。

あと言いたいこととして、PythonのAWS APIライブラリのbotoは非常に素晴らしいのですが、CloudWatch周りだけはいかんせん弱い。というか、EC2用の機能の一部としてしか提供されていないので、EC2インスタンスに関する値しか取得できないのです。どうか、boto.ec.cloudwatchのような形ではなく、boto.cloudwatchのような感じで、全namespaceを扱えるようにしていただけると更にはかどって仕方なくなります。

CloudWatch周りの何かをするときだけPHPSDKを使ったり、今回はRubySDK(というよりはRightScaleのライブラリ)を使っているので、全く統一感がなくてよろしくないなあと思いつつも色々手を出してみているのが現状です。

それでは、botoがCloudWatchのすべてのnamespaceを扱えるようになることを祈りながら、今日はこのへんで。

※間違いなどありましたら、ご指摘ください。