Undefined Title

CloudWatchのグラフをSlackへuploadするnode moduleを書いた

2016-02-08

先日うちの会社も某チャットサービスからSlackへ移行したんだけど、なんでか知らないけどSlackってHubotとかでいろいろやりたくなる魅力があるね。

で、以前からやりたかったのがCloudWatchのグラフのシェア。

チャットでトラブルシュートとかしてるときにCloudWatchのグラフみてあーだこーだ言うことがあるんだけど、同じグラフを表示してないと話が通じないし、スクショとってチャットに貼って、とかやってると表示範囲とか変えたときにまた貼り直したりするのがめんどくさい。

ということで、Hubotに貼らせるmoduleを書いた。
aws-cloudwatch-chart-slack

Hubotに対してcloudwatch <instance-id>とか指示するとそのチャートの画像を上のようにuploadする。 デフォルトでCPUUtilization, AWS/EC2のグラフを書く。 RDSのFreeableMemoryだったらcloudwatch <db-instance-id> FreeableMemory AWS/RDSでいける。EC2とRDS以外のnamespaceはまだ対応していない。

IDの部分は,で区切って複数並べられるのでcloudwatch i-xxxxxxxx,i-yyyyyyyyみたいに書くと、下のような感じで複数のグラフが出る。2つ以上の推移を比較したいときに便利じゃないかと。

グラフの範囲はデフォルトで実行したその時点から24時間前まで30分ごと。 範囲とx軸の区間はオプションで指定できる。--duration 2days --period 5minutesとかにすれば、直近2日間5分ごとだ。

エラーハンドリングもそこそこ真面目に書いたんで、ダメなときはHubotがエラーメッセージを教えてくれるはず。

How it works

かなり力技。

まずはAWS JavaScript SDKでグラフのデータを取得する、ここまではいい。

そのデータをどう画像(.png)にするか。いろいろ悩んだ末にc3.jsを使ってSVGとして描画するような.htmlと.jsを生成して、それをPhantomJSで.pngとして書き出すことにした。で、書きだした.pngをSlackのAPIでuploadしている。

PhantomJSを起動したり、テンポラリファイル3つくらい作って消したり。結構忙しいので、もうちょっとスマートにならんもんかと.pngをファイルを生成してファイル名を渡してuploadじゃなくて、画像をbase64を出力してupload処理へ渡せないか試したんだけどすぐに分からなくて諦めた。Node.jsのstreamをよく理解してないせいだな。

まあ、dataの取得、画像の生成、Slackへのuploadと明確に分かれているのはI/Fとしては分かりやすいと思うので、そこは悪くはないと思う。デバッグは楽だ。

ToDO

グラフを見たいインスタンスのIDを得るのがめんどくさいのでなんとかしたい。 やっぱりrole名などが指定できたほうが便利だ。

cloudwatch webapp

タグ名と値で指定できるといいのかな。

まとめ