にゃみかんてっくろぐ

猫か百合を見守る壁になりたい

死活監視をFirebase Realtime Databaseでお手軽にやってみる

死活監視といえば,たとえば MackerelUptime Robot などが使えます.

ただし,こうしたサービスは「エージェントをインストールする」か「外部からサービスにアクセスできる」必要があるほか,無料版に制限があるなど少々ネックがあります.

そこで,Firebase Realtime Databaseで死活監視チャレンジしてみました.

監視対象の条件

  • インターネットに到達できる(外部公開は不要)
  • cron または 任意の定期実行可能なジョブ管理システム がある
  • cURL または 任意のHTTPクライアント がある

監視対象: REST APIを定期的に叩く

監視対象のホストから,定期的にハートビートを送信します. データの保存  |  Firebase に記載されている Realtime Database の REST API を用います.

crontab -eでcrontabに定義を追加します.

*/10 * * * * curl -X PUT -d "\"`date '+\%Y-\%m-\%d \%H:\%M'`\"" https://examples.firebaseio.com/heartbeats/`hostname`.json

Realtime Databaseにデータが追加されます.

f:id:no_clock:20190603232659p:plain
Firebase Realtime Databaseのようす

アラート: Cloud FunctionsからSlackに通知する

アラートも作ります.Cloud Functionsで定期実行するようにします.

Node.jsですが普段あまり書かないのでクオリティはお察しです.

export const scheduledFunction = functions.pubsub.schedule('every 5 minutes').onRun((context) => {
  request.get({
    url: "https://examples.firebaseio.com/heartbeats.json",
  }, function(error: any, response: any, body: any) {
    const info = JSON.parse(body)
    for (let hostname in info) {
      const diff = Date.now() - Date.parse(`${info[hostname]}+09:00`)
      if (diff < 1000 * 60 * 30) { continue; }

      const options = {
        url: 'https://hooks.slack.com/services/<fugafuga>',
        form: `payload={ "text": "${hostname}: ${info[hostname]} 以降 heartbeatがありません." }`,
        json: true
      }
      request.post(options)
    }
  });
  return 1
});

ためしにしきい値を1分とかにして毎分実行させると,ちゃんとSlackに通知されます.

f:id:no_clock:20190603235821p:plain
ゆかりん

注意事項

おわりに

Realtime Databaseとは… という感じですが,Realtime Databaseは課金対象がストレージとトラフィックのみで,リクエスト数に制限がないため,少量のデータを高頻度にやり取りするケースによく合います.もっとも,今回の規模であればFirestoreでも無料枠で済みますが…

めでたしめでたし.