平常運転

アニソンが好き

過去記事とかは記事一覧で見れます

Google Apps Script で DropBox の使用量を Mackerel のサービスメトリックに投稿する

Mackerel のサービスメトリックを投稿する環境についていろいろ考えると投稿スクリプトを動かし続ける環境を用意するのが面倒になりがちなのだけど、外部の Web サービスなどからさっと API で取れる情報であれば Google Apps Script (以下 GAS)で動かすのが便利そうだということに気付いた。

ということで、自分の DropBox の使用量を Mackerel のサービスメトリックに投稿するスクリプトを GAS で書いたのでその話をする。

立場の表明

この記事自体は個人の趣味で書かれた記事だけれど、ぼくは Mackerel の開発チームにおります。
mackerel.io
一応立場の表明ということで。特に立場を活かした知見などは出てきません。

サービスメトリックの送信環境

スクリプトで値を取得/集計してサービスメトリックを送る環境を考えると、ざっくりと以下のような要件が多分ある:

  • 自分の書いたスクリプトを動かすことができる
  • 数分おきに24時間動き続ける
  • 動かし続けることにあまりコストを払いたくない

たとえば Heroku の無料 Dyno だと24時間動かし続けられないので厳しいということになる。また、動かし続けることから考えると、その辺の適当な Mac で動かしてると移動中や電源切ってるときにメトリックが送れなくなる。

ということで、今回は GAS を使うことにした。ちなみに AWS Lambda にも無料枠があって似たようなことできそうなので、Lambda が好きな人はそっちでもいいと思う。

developers.google.com

特長は:

  • JS っぽいものが動く
  • (定められた Quota の範囲で)無料で動かせる
  • 最短で毎分間隔で動かすことができる

というところがある。 Google Docs. との連携や拡張の話が目立つけど、ふつうにスクリプトを書いて定期的に実行することもできて便利。

サービスメトリックに記録する物

今回は DropBox のディスク使用量を記録することにした。最近は落ち着いているけど、一時は適当にデータを入れてたらあれよあれよと容量埋まってしまったことがあった。
DropBox は OAuth 2.0 で認証する HTTP API を提供しているのでそれが使える。

www.dropbox.com

DropBox の OAuth API にはざっくりこういう特徴がある:

  • アプリケーションを登録すれば、自分用のアクセストークンは(認可フローを通らなくても)管理画面で取得できる
  • アクセストークンは、明示的に revoke しない限り expire しない*1

なので、自分一人で使うアプリケーションであれば、管理画面で自分用のアクセストークンを払い出すことで OAuth のややこしい認可フローを使わずに API リクエストできる。便利。
認可フローが必要無いなら、App 登録時の callback url の登録とかも要らないので楽。

f:id:astj:20160929210722p:plain

Mackerel の API

サービスメトリックの投稿 API を使う。使ってる人にとっては言わずもがなだけど、 Mackerel の API は、払い出したアクセスキーをX-Api-Keyヘッダにつけてリクエストすれば使える。

mackerel.io

やっていく

ということでいきなりスクリプト

gist.github.com

UrlFetchAppっていうちょっと見慣れない物があるけど、これは GAS で HTTP 叩くための物: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app
多分この GAS を実際に動かそうとすると外部 HTTP リクエストするための権限が求められるのでそれは許可しないといけない。

やりかた

まずスクリプト本体を GAS の画面で書く。

この段階で一度スクリプトを実行して、 Mackerel にお望みのサービスメトリックが投稿されていればひとまず OK 。
指定したサービスに dropbox.useddropbox.allocatedというサービスメトリックが送信されているはず。

後は、メニューの "Resources" => "Current project's triggers" から定期的に実行するトリガを設定すれば完成。

ついでにグラフの設定でラベルをいい感じにして、単位を Bytes にするとこういう感じになる:

f:id:astj:20160929210358p:plain

見所

見所というほどでもないけれど感想みたいなのをいくつか書く。

DropBox

今回 DropBox で使った APIContent-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'
)

f:id:astj:20160929211512p:plain

適当な閾値(0.7 とか 0.9 とか)を設定しておくことで安心できる。

感想

GAS は最初ちょっと戸惑ったけれど、なんだかんだと素朴な JS が書けるので便利。他の用途で使ってないなら GAS の Quota も結構余裕があると思う。
今回はお遊びという感じだけど、サーバレスで Mackerel にメトリックを投稿したいユースケースはまあまああると思っていて、そういう時の選択肢として GAS (や AWS Lambda など) から API を叩くのは割と便利だと思う。