Mackerel の1分粒度メトリックデータをCSVでバックアップする

私が現在運用しているシステムではシステム・サービス監視やキャパシティ管理のツールとして Mackerel https://mackerel.io/ というSaaS型のサービスを使っています。 各サーバのCPU利用率やメモリ利用率といったホストメトリック情報はもちろん、特定のサーバには紐付かない情報、例えばサービス利用ユーザ数やお問い合わせの件数といった値もサービスメトリックとしてMackerelに投稿し、Mackerel上でグラフ化したりしきい値を設定してアラートを上げたりできるので便利です。

サーバについてはパブリッククラウド上でインスタンスがぽこぽこ入れ替わるので、ホストメトリックを永続的に保管したい要求はあまりないのですが、ユーザ数の推移といったサービス運営状況に関わるデータは Mackerelのデータ保持期間( 2018年10月13日現在では460日間) を超えた長期間分のデータを確認したい場合があるため、常にMackerelと自分たちで管理できる他のDBの両方にデータを登録し続けるか、データを登録するのはMackerelのみにして定期的にMackerelからデータをバックアップするか、といった対処が必要になります。

今回は後者の、Mackerelから定期的にメトリックデータをバックアップする方法について調べてみました。 といっても、サービスメトリックもホストメトリックもデータを取得するためのAPIが公開されていますので、それをいかに効率よく叩くかだけを考えればOKです。

mackerel.io mackerel.io

APIドキュメントを参考にパラメータを変えながらAPIを叩いていると、from と to で指定するデータ取得対象期間の長さによって取得できるメトリックデータの粒度が変わることを発見しました。

例えば from = 1538319600 (epoch秒。日本時間で2018/10/01 00:00:00) 、to = 1538362800 (日本時間で2018/10/01 12:00:00) として12時間分のデータを取得した場合は60秒間隔のメトリック値が返ってきますが、from = 1538319600 (日本時間で2018/10/01 00:00:00) 、to = 1538406000 (日本時間で2018/10/02 00:00:00) として24時間分のデータを取得した場合は300秒間隔のメトリック値(おそらく60秒間隔のメトリック値5個分の平均値) が返ってきていました。1年前から今日までの1年間分データを取得した場合は86,400秒間隔、つまり1日間隔のメトリック値が返ってきました。

そこでもう少しいろいろ試して調べてみたところ、どうもサービスメトリック、ホストメトリック共に、以下のような仕様になっているようでした。

取得できるメトリックデータの粒度(秒) 最大データ取得期間(秒) 備考
60 72,239 1,204分(≒20時間強)未満までは1分粒度のデータを返す。
300 599,999 1,204分以上 10,000分(≒7日間弱)未満では5分平均のデータを返す。
600 866,999 10,000分以上 14,450分(≒10日間強)未満では10分平均のデータを返す。
3,600 7,199,999 14,450分以上 120,000分(≒2,000時間≒12週間弱)未満では1時間平均のデータを返す。
7,200 14,399,999 120,000分以上 240,000分(≒4,000時間≒約5.5ヶ月間)未満では2時間平均のデータを返す。
14,400 20,807,999 240,000分以上 346,800分(=5,780時間≒約8ヶ月間)未満では4時間平均のデータを返す。
86,400 20,808,000~ 346,800分以上の期間のデータを要求すると1日平均のデータを返す。

サービスメトリックで記録するようなデータのうち、ユーザ数の推移などは長期期間で眺める場合は1日間隔のデータで全く問題ないのですが、もし仮に最も細かい粒度である1分間隔のメトリックデータを長期期間分保存しておかなければならなくなった場合はどうやるのが良いか、を考えてみました。
上の表で見てわかるとおり、fromからtoまでの間隔が 72,239秒以内であればAPIは1分間隔のメトリック値を返してくれるので、このfrom とto を72,239秒づつずらしながらAPIを叩くようなバッチを作れば良さそうです。
また、APIのレスポンスはJSON形式なのでそのまま非エンジニアである企画・営業系のメンバーに共有しても集計やグラフ化などを行うにあたって扱いにくいため、CSV形式で保存できるようにします。

というわけで書いてみたスクリプトがこちら。curl コマンドと jq コマンドがインストールされている必要があります。

gist.github.com

いたってシンプルに、curlAPIを叩いてそのレスポンスをjqでCSVに変換する という処理をwhile文で繰り返しているだけです。 ここではMackerel のAPI Keyや各種パラメータをコード内にべた書きにしていますが、実際は環境変数コマンドライン引数として渡せるようにしてcronで定期実行させるのが楽かと思います。

あとは注意点として、2017年12月1日以前のデータについては1分粒度のメトリックデータは取得できないようです。

mackerel.io