share facebook facebook twitter menu hatena pocket slack

2014.10.29 WED

AWS 白帯シリーズ(18) CloudWatch のメトリクスを Ruby 使って Graphite に残しておくっぺ

川原 洋平

WRITTEN BY 川原 洋平

どうも、連投ですいません。cloudpackかっぱ@inokara)です。

はじめに

フワッとしか知らない CloudWatch の勉強を兼ねて AWS SDK for Ruby を使ってメトリクスを Graphite に残すようにしてみたのでメモです。

尚、下記の内容については個人の解釈となり実際の内容とは異なる可能性がありますのでご注意下さい。また、すごい今更二郎感半端ありませんがご容赦下さい…m(__)m

CloudWatch の基礎

参考

Amazon CloudWatch とは

  • AWS の各種リソースをモニタリングする為の Web サービス
  • サービス毎に定義されたメトリクス(=監視項目)
  • メトリクスをベースにアラームを設定する
  • カスタムメトリクス(独自のメトリクスを保存してモニタリング、グラフ化)
  • HTTP GET は最大 8KB
  • HTTP POST は最大 40KB
  • 監視の間隔は基本的には 5 分間隔だが有償($3.675/月)で 1 分間隔にすることも出来る(コレ重要)

理想と現実

  • 単一のデータだけではなく統計値を放り込むことが出来る
  • データは最大値、最小値、平均値、サンプル数、合計値を取得することが出来る
  • 普通の監視ツールとか API サーバーだと思って弄っていたのでハマった(コレ重要)

コレ重要

  • Statistics が Average の場合に取得出来るメトリクスは 5 分毎の平均値となる
  • 但し、実際に各メトリクスは 1 分毎にサンプリングしている

以下は根気よく画面を眺めていて取得したメトリクスの値。(時間が UTC になっているのはすんません…)

{:timestamp=>2014-10-10 16:06:00 UTC, :sample_count=>5.0, :unit=>"Bytes", :average=>652840.6}
{:timestamp=>2014-10-10 16:11:00 UTC, :sample_count=>5.0, :unit=>"Bytes", :average=>755028.4}

上記から解ることは…

  • 16:06 の次に平均値を取得出来たのが 16:11 となっている
  • sample_count は 5 となっており 1 分毎にサンプリングしている(ようだ)
  • average は 1 分毎のサンプリングの平均値を表している(はず)

この三点かなと。

AWS SDK for Ruby で CloudWatch をツンツクツンする

ちょっと CloudWatch のことが理解できたところで

AWS SDK for Ruby を使って CloudWatch をつついていきます。

過渡期

AWS SDK for Ruby V2 が出ているようですが、今回の記事は素の AWS SDK for Ruby を使ってます。なので `equire は…

require 'aws-sdk'

です。

基本形

以下は EC2 インスタンスの NetworkIn のメトリクスを取得するスクリプトです。

#!/usr/bin/env

require 'aws-sdk'

AWS.config(
  :access_key_id        => ACCESS_KEY_ID,
  :secret_access_key    => SECRET_ACCESS_KEY,
  :region => REGION
)

ec2_metrics = AWS::CloudWatch::Metric.new(
  'AWS/EC2',
  'NetworkIn',
  :dimensions  => [
    { :name => "InstanceId", :value => "#{instance}" },
  ]
)

stats = ec2_metrics.statistics(
  :start_time  => Time.now - 300,
  :end_time    => Time.now,
  :statistics  => ['Average'],
  :period      => 60
)

puts stats.datapoints

AWS.config はお決まりのおまじないですね。おまじないの後は CloudWatch::Metric クラスから新しいインスタンス(ec2_metrics)を生成します。その際に必要なパラメータは下記の通りです。

パラメータ 名称 用途
‘AWS/EC2’ ネームスペース メトリクスをまとめている単位で AWS ではサービス毎にまとめている
‘NetworkIn’ メトリクス datapoint の入れ物(datapoint = 時系列データ)
‘:dimensions’ ディメンジョン メトリクスをカテゴライズ(EC2 であれば InstanceID 等)

尚、:dimensionsInstanceId とその値をハッシュで指定している。

更に statistics メソッドの引数として以下を指定することで値(datapoint)を取得している。

パラメータ 名称 用途
‘:start_time’ 開始時間 値取得対象期間の開始時間
‘:end_time’ 終了時間 値取得対象期間の終了時間
‘:statistics’ スタティスティックス 値の取得方法(サンプル数、合計、平均、最大、最小値)
‘:period’ 周期(間隔) 値の取得間隔

上記の実行結果は…以下の通りになります。

[{:timestamp=>2014-10-10 01:02:00 UTC, :unit=>"Bytes", :average=>655.8}]

Graphite にぶっ込む為には

graphite-api という gem を使えば、割とカジュアルに Graphite にデータをぶっ込むことが出来ます。CloudWatch から取得した値は以下のようにぶっ込みました。

require 'graphite-api'

(中略)

if stats.datapoints != []
  graphite.metrics "cloudwatch.test.#{instance}.networkin" => stats.datapoints[0][:average].to_f
else
  puts "value doesn't exists."
end

datapoints[0] は不要かもしれませんが、シンボル付きのハッシュキー(:average)を指定して値を取り出します。to_f で小数点以下の値も解釈させます。

ぶっ込みの結果

以下のように表示されてます。
Amazon CloudWatch のデータを Ruby で Graphite に送った結果

こんな感じで残すことが出来れば、CloudWatch のメトリクスは二週間しから残らないという制限を気にすることが無くなると思います。(※Graphite の Retention の設定は二週間以上にしておく必要がありますな)

最後に

Graphite 等のように値を放り込んだら即座にメトリクスとして蓄積されるという間隔で CloudWatch に挑むと若干特殊に感じるメトリクスデータのレスポンス(結果の表示)に戸惑うことがあるかもしれません…(ちゃんと理解していれば何てことはないと思います)が、CloudWatch は EC2 だけではなく AWS の各種サービスのメトリクスを取得出来るので適材適所でうまく利用していきたいものです。

おしまい。

元記事はこちらです。
AWS 白帯シリーズ(18) CloudWatch のメトリクスを Ruby 使って Graphite に残しておくっぺ