koudenpaのブログ

趣味のブログです。株式会社はてなでWebアプリケーションエンジニアをやっています。職業柄IT関連の記事が多いと思います。

IoTデバイスとMackerel

この記事はMackerel Advent Calendar 2020の3日目です。

2日目は id:cohalz さんの 2020年におけるmackerel-plugin-jsonの使い方 、4日目は id:hnw さんの Raspberry Pi+Mackerelで気軽に温度監視できるようにした話*1です。

このブログにIoTというカテゴリがある通り、ちょいちょいモノをインターネットに繋いで遊んでいる。

モノは主にRaspberry PiArduino互換機*2、特にESP32(や8266)が載っているマイコンボードを使っている。

今回はそのモノ、IoTデバイスとMackerelの関係について思ったりやったりしたことを書きたいと思う。

IoTデバイスとMackerelのホスト

Mackerelは『直感的サーバー監視サービス』と銘打っている通り、主な監視対象はサーバーであって、IoTデバイスではない。

f:id:koudenpa:20201202192140p:plain
2020年12月現在のMackerelのトップページの煽り文句

しかし、温度など刻一刻と変化する値を送り付けるといい感じに可視化してくれるというサービスの特性上、IoTデバイスで収集した値を送り付ける先としてもなかなか便利だ。おまけに閾値を指定してアラートも通知できる。実際やっている人も多い。

そうした便利さを得るためにMackerelと繋ぐための手法がRaspberry PiArduino互換機では明確に違う。

Raspberry PiあるいはLinuxが動いているIoTデバイス

これに関しては特に難しいことはない。MackerelエージェントをインストールしてデバイスをMackerelにホスト登録することは容易だ。

参照 Raspberry PiでMackerelを使うのが楽になったよ! - Qiita

Raspberry PiなどのIoT向けのマシンのCPUはArmが主流で、多くのサーバーが動作しているx86/amd64とはアーキテクチャが違う。そのためMackerelエージェントのインストールが多少面倒くさい時期もあったが、最近では公式にArm向けビルドが提供されるようになるなど、より簡単安心になりつつある。

何にしてもこのクラスのハードでは普通にLinuxが動作しているので、他のLinuxホストと変わることはあまりない。

Arduino互換機あるいはMackerelエージェントが動作しないIoTデバイス

他方、そうしたMackerelエージェントがインストールできるようなリッチなOSではないハードウェアの場合は、独自にMackerelのAPIを呼び出す必要がある。

特にArduino IDEC言語っぽく開発する場合、HTTPSのリクエストを送ることすら面倒くさい*3。それでも既にメトリックをMackerelに送っている例は沢山ある。

1000円以下で買えるWiFiモジュールESP-WROOM-02でMackerelにメトリクスを送る - Qiita ではサービスメトリックを送っているし、SabaBox (mackerel-agent on M5Stack) を作った - ぶていのログでぶログ ではM5StackというIoTデバイスをMackerelにホスト登録している。

あるデバイスをMackerelのホストにするには当然ホスト登録のAPIを呼び出さなくてはならない。面倒くささが増す。しかし、Mackerelはホスト、ロール、サービスという単位でいい感じに管理するサービスなので、ホストにしておくと可視化や監視の便利さは向上する。

特に制約が無いならホスト登録したいのだ。

f:id:koudenpa:20201201230754p:plain
便利さの例、複数ホストのメトリックをロールでまとめて見られる

OSのないIoTデバイスをMackerelのホストにする

どうすればいいのか。

Mackerelはホスト登録のAPIも公開されている。これでホスト登録し、登録されたホストIDでホストメトリックを送ってやればいい。それでMackerel上のホストになる。

Mackerelエージェントはそうしたことをやってくれているアプリケーションなだけだ。

Mackerelエージェントがインストールできなくても、同じようなことを独自にすればよい。

MackerelArduinoClient

先にも挙げた SabaBox (mackerel-agent on M5Stack) を作った - ぶていのログでぶログ ではMicroPythonで簡易なMackerelエージェントを作成している。

同じことをしても仕方ないというわけではないけれど*4、自分はArduino IDEでの開発の方が好きなので、それ向けにライブラリ(GitHub - 7474/ArduinoMackerelClient)を作りつつホスト登録したり、ホストメトリックを送ってみている。

ホストIDの永続化など試行錯誤しつつ、今のところ以下のようなスケッチ*5でホストメトリックを送れるような感じにしている。

#include <EEPROM.h>
#include "MackerelClient.h"
MackerelHostMetric hostMetricsPool[10];
MackerelServiceMetric serviceMetricsPool[10];
MackerelClient mackerelClient(hostMetricsPool, 10, serviceMetricsPool, 10, mackerelApiKey);

// EEPROM
const int eepromSize = 1000;
const int hostIdVersionAddress = 0;
const char currentHostIdVersion[4] = "001";
char hostIdVersion[4];
const int hostIdAddress = 4;
char hostId[32];

void setup() {
  setupWiFi();

  EEPROM.begin(eepromSize)
  EEPROM.get(hostIdVersionAddress, hostIdVersion);
  if (!strcmp(currentHostIdVersion, hostIdVersion)) {
    // 永続化されたホストIDを読む
    EEPROM.get(hostIdAddress, hostId);
    Serial.print("loadedHost: ");
    Serial.println(hostId);
  } else {
    // ホストIDがなければ登録する
    mackerelClient.registerHost("register-by-m5", hostId);
    Serial.print("registerHost: ");
    Serial.println(hostId);
    EEPROM.put(hostIdVersionAddress, currentHostIdVersion);
    EEPROM.put(hostIdAddress, hostId);
    EEPROM.commit();
  }

  mackerelClient.setHostId(hostId);
}

void loop() {
  float batVoltage = M5.Axp.GetBatVoltage();
  float batCurrent = M5.Axp.GetBatCurrent();
  mackerelClient.addHostMetric("custom.battery.voltage", batVoltage);
  mackerelClient.addHostMetric("custom.battery.current", batCurrent);
  
  delay(60 * 1000);
}

スケッチ全部はこの辺りに置いてある。

小さいホスト

こうしたIoTデバイスはMackerelが主なターゲットとしているサーバーと比べるととても小さなホストだ。カタカナにするとマイクロホストといったところだろうか。

Mackerelでのマイクロホストクラウドインテグレーションで登録されるリソースやコンテナ向けで、APIからは登録できない。

個々のIoTデバイスをMackerelのスタンダードホストとして登録するのはマッチするユースケースがほとんどないだろうし、ユーザーの立場からは『マイクロホスト登録のAPI提供されるといいのになぁ』と思う。うまくハマればIoTデバイス監視の1手段になるのではなかろうか。

オチ

元々は大分前から話題のM5Stackを買ったのでMackerelにメトリック送ろう*6。どうせならホストに登録してバッテリーレベル監視しておけば、充電が必要なタイミングでアラート通知できるんじゃない? のようなことを書くつもりだった。

が、毎分インターネットに情報を送るような用途では長時間バッテリー駆動は難しそうなので企画倒れになってしまった。

大人しく電源を繋いで動かすことにした。

……電源抜けちゃった位はチェック監視で出来るかもしれない。一つ宿題ができた。

*1:この記事の内容絡みでググっていたらそれっぽいプラグインリポジトリを見かけたので楽しみ

*2:厳密にはちょっと違うのだろうけれどこの表現で許して

*3:Let's Encryptが切り替えることで話題になっているルート証明書を自分で管理するなどの手間がある

*4:そもそも先に事例があるかとか気にしないでモノを作っている

*5:Arduino向けのプログラムはスケッチという、はず

*6:これは達成していて、室温とか見られていて便利