aws-sdk-goのリファレンスを見てGetMetricStatisticsを使う

スポンサーリンク

はじめに

前回より一歩踏み込んでaws-sdk-goのリファレンスを見てGetMetricStatisticsを使ってみます。

aws-sdk-goを使用するのに注意することとして、こちらのサイト様が参考になりました。

ちなみに私はgolang歴2ヶ月程度のド素人かつにわかです。↓で偉そうに書いてますがそんなやつが書いてると思ってください。

さらに私はぷろぐらむを書くのが上手ではありませんorz

リファレンスを見てみる

cloudwatchのGetMetricStatisticsについてリファレンスを見てみます。前回使ったやつですね。

該当箇所を見るとこんな風に書いてあります。

func (c *CloudWatch) GetMetricStatistics(input *GetMetricStatisticsInput) (*GetMetricStatisticsOutput, error)

*GetMetricStatisticsInput型を用意してGetMetricStatisticsを呼び出せば*GetMetricStatisticsOutput型とerrorが返ってくるということでしょうかね。メソッドとして使えばいいのか。

GetMetricStatisticsInputを見てみる

GetMetricStatisticsを使うのに*GetMetricStatisticsInputが必要だとわかったので*GetMetricStatisticsInputを見てみます。

ちょっと長いのでコメントアウト箇所を割愛したものがこちら
※このコメントアウトが大事なことがたくさん書いてあるので使うときは熟読した方がいいです。特にStartTimeとPeriod。

type GetMetricStatisticsInput struct {

Dimensions []*Dimension type:"list"

EndTime *time.Time type:"timestamp" required:"true"

ExtendedStatistics []*string min:"1" type:"list"

MetricName *string min:"1" type:"string" required:"true"

Namespace *string min:"1" type:"string" required:"true"

Period *int64 min:"1" type:"integer" required:"true"

StartTime *time.Time type:"timestamp" required:"true"

Statistics []*string min:"1" type:"list"

Unit *string type:"string" enum:"StandardUnit"
}

Dimensionsなら[]*Dimension型
EndTimeなら*time.Time型
飛んで
Unitなら*string型をそれぞれ用意してあげればいいということでしょうかね。

最低限required:"true"の項目だけでもOKっぽい。

Dimensionsは[]*DimensionなのでDimensionのstructも確認します。

type Dimension struct {

// The name of the dimension.
//
// Name is a required field
Name *string min:"1" type:"string" required:"true"

// The value representing the dimension measurement.
//
// Value is a required field
Value *string min:"1" type:"string" required:"true"
// contains filtered or unexported fields
}

Nameという*string型とValueという*string型がそれぞれrequired:"true"だから必須ですね。

結果であるGetMetricStatisticsOutputを見てみる

inputの次は取得できるoutputを見てみます。

type GetMetricStatisticsOutput struct {

// The data points for the specified metric.
Datapoints []*Datapoint type:"list"

// A label for the specified metric.
Label *string type:"string"
// contains filtered or unexported fields
}

DatapointsとLabelが入ったstructがもらえるということですかね。

これDatapointの中身も見ないとわからないな。。ということで↓

type Datapoint struct {

// The average of the metric values that correspond to the data point.
Average *float64 type:"double"

// The percentile statistic for the data point.
ExtendedStatistics map[string]*float64 type:"map"

// The maximum metric value for the data point.
Maximum *float64 type:"double"

// The minimum metric value for the data point.
Minimum *float64 type:"double"

// The number of metric values that contributed to the aggregate value of this
// data point.
SampleCount *float64 type:"double"

// The sum of the metric values for the data point.
Sum *float64 type:"double"

// The time stamp used for the data point.
Timestamp *time.Time type:"timestamp"

// The standard unit for the data point.
Unit *string type:"string" enum:"StandardUnit"
// contains filtered or unexported fields
}

いろんなmetricがあるけどとりあえずAverageだけでいいや。

試してみる

コード1

前回のものから一部変更したものがこちら。

追記

session部分を公式のものに変更しました。

cloudwatch.goと名づけました。DimensionsにあるValueはEC2のインスタンス IDなのでぼかしています。

params := &cloudwatch.GetMetricStatisticsInput{}でGetMetricStatisticsInputを作っている。MetricNameはstring型で渡すのでaws.Stringにstringを渡して*stringに変換している様子。

ちなみに上の例だと5分前(StartTimeが5分前)から60秒間隔(Period)でデータを取ろうとしてます。

コード1結果

go run cloudwatch.goで実行した結果がこちら。

?LabelがあるけどDatapointsがない?

そんなばな(ry

データ取得できる間隔の違いがあることを知る

EC2の基本モニタリングだと5分ごとにしかデータポイントが出来ないそうで、お金払って詳細モニタリングにすれば1分間隔でデータポイントが出来るらしい。

そしてこのデータポイントをまたがないといけないそうで。

火の車家計の我が家に詳細モニタリングを試す余裕があるわけないので詳細モニタリングは却下。取得間隔を長くしてみます。

先ほどのcloudwatch.goのStartTimeを5分から10分に変更し、periodも60秒から300秒に変更して再トライ。

Datapointsの中にAverageがあり数値も取れてますね!やったぜ。

魔改造版

10分に変更すると↓こんな感じで2つデータが取れてしまうことがありました。

1つだけデータが欲しいときにこれだと困るので魔改造してみることに。

コード2

ちょっとお遊びでデータが1個だけ取れるようにしてみたのがこちら

resp, _ := svc.GetMetricStatistics(params)以下を変更しました。resp.Datapointsの大きさが1以下になるまで15分から1分ずつStartTimeを下げてみました。continueはforを次のループに進めてくれる便利なやつです。少しでもnestしないようにこの頃愛用してます。

実は初めはStartTime5分くらいからresp.Datapointsがnilじゃなくなるまで1分ずつStartTimeを上げるものを作ったんですが、もしも「forループの条件式とかミスしている」だとか「別の理由でresp.Datapointsがずーとnil」だと、青天井で永遠にAPIを叩くことになりawsの請求金額がやばいことになりそう?だったのでこんな形にしてみました。

そういう意味ではクラウドのAPIを叩くものにforループを使うのは危険極まりない気もするのでやろうとする方は十分気をつけて自己責任でお願いします。

GetMetricStatistics、ListMetrics、PutMetricData、GetDashboard、ListDashboards、PutDashboard、DeleteDashboards のリクエスト 1,000 件あたり 0.01 USD

やっぱお金かかるよね。不具合で高額請求された方もいらっしゃるようなので注意。

コード2結果

こちらを実行した結果がこちら。

StartTime10分で1つだけのデータが取れたことがわかります。

補足

このデータポイントのプッシュ間隔はserviceやmetricsごとに変わようです。

dynamodbだとmetricsにより1分間隔と5分間隔がある様子。

ConsumedReadCapacityUnits、ConsumedWriteCapacityUnitsは1分間隔
ProvisionedReadCapacityUnits、ProvisionedWriteCapacityUnitsは5分間隔

kinesisは1分間隔

RDSも1分間隔

最後に

cloudwatchのGetMetricStatisticsについてリファレンスを見て色々試してみました。

やっぱりAPIは便利ですけどfor使うときは怖いですね。。皆さんどうしてるんですかね?forとかループ系使わないものなんですかね。

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする