Mackerel のサービスメトリックを投稿する環境についていろいろ考えると投稿スクリプトを動かし続ける環境を用意するのが面倒になりがちなのだけど、外部の Web サービスなどからさっと API で取れる情報であれば Google Apps Script (以下 GAS)で動かすのが便利そうだということに気付いた。
ということで、自分の DropBox の使用量を Mackerel のサービスメトリックに投稿するスクリプトを GAS で書いたのでその話をする。
立場の表明
この記事自体は個人の趣味で書かれた記事だけれど、ぼくは Mackerel の開発チームにおります。
mackerel.io
一応立場の表明ということで。特に立場を活かした知見などは出てきません。
サービスメトリックの送信環境
スクリプトで値を取得/集計してサービスメトリックを送る環境を考えると、ざっくりと以下のような要件が多分ある:
- 自分の書いたスクリプトを動かすことができる
- 数分おきに24時間動き続ける
- 動かし続けることにあまりコストを払いたくない
たとえば Heroku の無料 Dyno だと24時間動かし続けられないので厳しいということになる。また、動かし続けることから考えると、その辺の適当な Mac で動かしてると移動中や電源切ってるときにメトリックが送れなくなる。
ということで、今回は GAS を使うことにした。ちなみに AWS Lambda にも無料枠があって似たようなことできそうなので、Lambda が好きな人はそっちでもいいと思う。
特長は:
- JS っぽいものが動く
- (定められた Quota の範囲で)無料で動かせる
- 最短で毎分間隔で動かすことができる
というところがある。 Google Docs. との連携や拡張の話が目立つけど、ふつうにスクリプトを書いて定期的に実行することもできて便利。
サービスメトリックに記録する物
今回は DropBox のディスク使用量を記録することにした。最近は落ち着いているけど、一時は適当にデータを入れてたらあれよあれよと容量埋まってしまったことがあった。
DropBox は OAuth 2.0 で認証する HTTP API を提供しているのでそれが使える。
DropBox の OAuth API にはざっくりこういう特徴がある:
- アプリケーションを登録すれば、自分用のアクセストークンは(認可フローを通らなくても)管理画面で取得できる
- アクセストークンは、明示的に revoke しない限り expire しない*1
なので、自分一人で使うアプリケーションであれば、管理画面で自分用のアクセストークンを払い出すことで OAuth のややこしい認可フローを使わずに API リクエストできる。便利。
認可フローが必要無いなら、App 登録時の callback url の登録とかも要らないので楽。
Mackerel の API
サービスメトリックの投稿 API を使う。使ってる人にとっては言わずもがなだけど、 Mackerel の API は、払い出したアクセスキーをX-Api-Key
ヘッダにつけてリクエストすれば使える。
やっていく
ということでいきなりスクリプト。
UrlFetchApp
っていうちょっと見慣れない物があるけど、これは GAS で HTTP 叩くための物: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app
多分この GAS を実際に動かそうとすると外部 HTTP リクエストするための権限が求められるのでそれは許可しないといけない。
やりかた
まずスクリプト本体を GAS の画面で書く。
- Apps Script – Google Apps Script で新しいスクリプトの作成を始める
- スクリプトの中身を 👆 の gist に書き換える
- アクセスキーとトークン、サービス名を埋める
この段階で一度スクリプトを実行して、 Mackerel にお望みのサービスメトリックが投稿されていればひとまず OK 。
指定したサービスに dropbox.used
とdropbox.allocated
というサービスメトリックが送信されているはず。
後は、メニューの "Resources" => "Current project's triggers" から定期的に実行するトリガを設定すれば完成。
ついでにグラフの設定でラベルをいい感じにして、単位を Bytes にするとこういう感じになる:
見所
見所というほどでもないけれど感想みたいなのをいくつか書く。
DropBox
今回 DropBox で使った API は Content-Type: application/json
で POST するのだけれど、 GAS の UrlFetchApp
では空の payload で POST することができないっぽい。また、かといって{}
のような適当な json を payload に入れるとパラメータが不正と言われて通らない。
なので、上のスクリプトでやってるように、'null'
を payload に渡す必要があった。
GAS
Google App Script の Quota はここで記載されている: Quotas for Google Services | Apps Script | Google Developers
これによると外部 HTTP リクエストは 20000/day ということになっているので、これを越えないように実行頻度を設定しないといけない。
このスクリプト1回の実行で Mackerel と DropBox に1回ずつ HTTP リクエストするので、仮に毎分実行しても1日あたりの HTTP リクエスト回数は 2 * 60 * 24 = 2880 回で、自分のアカウントでこのスクリプト以外動かさないなら毎分間隔でも大丈夫、ということになる。とはいえそんなに高頻度でなくてもいいかな、と思ったので5分おきの実行にしておいた。安心。
Mackerel
Mackerel にメトリックを送るからには監視したい。ということで、実験的機能の式監視を使って空き容量を監視することにした。
alias( divide( service("Kyoto",'dropbox.used'), service("Kyoto",'dropbox.allocated') ), 'DropBox Usage Rate' )
適当な閾値(0.7 とか 0.9 とか)を設定しておくことで安心できる。