selmertsxの素振り日記

ひたすら日々の素振り内容を書き続けるだけの日記

Cloud FunctionsとCloud Schedulerを利用してDatadogで監視しているホスト数を通知させてみた

作ったもの

指定された期間のDatadogの監視台数について、最小,最大,合計(ホスト数×時間)を算出してSlackに通知してくれるCloudFunctionsを作成しました。そのCloudFunctionsはCloud Pub/Subで実行され、Cloud SchedulerはそのCloud Pub/SubのTopicを一日一度実行してくれます。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f32333630362f32306237373066382d356364322d323232312d363762302d6139623430663830616433382e706e67_censored.jpg

コードはこちらです。 https://github.com/selmertsx/datadog_slack_report

この資料に記載されていること

  • Cloud SchedulerからCloud Pub/Subを実行する方法
  • DatadogでのRollup functionの使い方
  • ※ Cloud Functionsに関する詳細な説明はしません。

CloudFunctionsを実行するための方法については、こちらの記事を参照してください。

https://qiita.com/selmertsx/items/31b10bfc4b72b05627e1 https://qiita.com/selmertsx/items/27686e51b4471eaf8c86

作った理由

  • 今いる企業では複数のプロダクトでDatadogを利用してリソースの監視を行っていません
  • Datadogでの監視はアカウントを分けていません
    • サーバーメトリクスは企業の資産であり、すべてのエンジニアが隣のプロダクトのサーバーメトリクスや監視方法を見て学ぶことができるように、敢えてアカウントは分けないようにしています
    • ちょっと声を掛けて見せて貰えばいいでないという声はあるかと思いますが、気になったときに誰の手も煩わせずに確認できるようにしたいという意図でそうしています
  • アカウントを分けないで運用をしていると、プロダクト毎のコストを集計する必要がある
  • コストの集計は自動でやってしまいたい
  • 最近でた Cloud Schedulerを使ってみたい

事前準備

タグ付けを行ったら次の準備に進んでください。

DatadogでのQueryの実行

DatadogではAPIを実行して、メトリクスを取得することができます。さらに、それらメトリクスに対して様々な計算処理を入れることも可能です。その実行方法については、こちらの資料に記載されています。

さて、シンプルに各プロダクト毎のホスト数をAPIで取得したい場合、count:system.cpu.user{*} by {product}のようなクエリになります。ECインスタンスのメトリクスは5分毎にagentから送信されているため、1日分のデータを取得してしまうと12 * 24 * プロダクト数分のデータが必要になってしまいます。Datadogの課金体系から考えても、1時間未満の粒度でのデータは取得する必要がありません。そのため、不要なデータを削ぎ落とす必要があります。今回はRollup関数を使って、データを1時間単位で丸め込んでから取得しました。これによって24*プロダクト数分のデータにすることができました。Rollup関数の説明はこちらになります。抜粋した文書が下記になります。

Rollup The function takes two parameters, method and time: .rollup(method,time) The method can be sum/min/max/count/avg and time is in seconds. You can use either one individually, or both together like .rollup(sum,120).

この説明通りにクエリを作成してみると、count:system.cpu.user{*} by {product}.rollup(count, 3600) という形になりました。TypeScriptのコードは下記のようになります。

// https://github.com/selmertsx/datadog_slack_report/blob/master/src/DatadogClient.ts#L28
  public async countHosts(from: string, to: string): Promise<DatadogHostMetrics[]> {
    const params: CountHostRequest = {
      api_key: API_KEY,
      application_key: APP_KEY,
      from,
      query: `count:system.cpu.user{*} by {product}.rollup(count, 3600)`,
      to,
    };

    const res: DatadogQueryReponse = await this.request.get("/query", { params });
    return res.data.series.map((product: SeriesMetrics) => {
      const pointlists: PointList[] = product.pointlist.map((point: number[]) => {
        return { unixTime: point[0], count: point[1] };
      });
      return { product: product.scope, pointlists }
    });
  }

僕のコードの中にDatadogのAPIで帰ってくるレスポンスの型(の一部)を記載しておきましたので、データの中身について気になる方は目を通されると良いでしょう。

Cloud Functionsのデプロイ

Google Cloud Pub/SubをトリガーにCloud Functionsを起動する設定をしていきます。Google Consoleからdatadog_reportというtopicを作成し、下記のコマンドでCloud Functionsをデプロイしましょう。

gcloud beta functions deploy datadog_handler \
  --region=asia-northeast1 \
  --stage-bucket=datadog_report \
  --trigger-event=google.pubsub.topic.publish \
  --trigger-resource=datadog_report \
  --runtime=nodejs8

Cloud FunctionsのトリガーとしてCloud Pub/Subを利用する方法については、このドキュメントに詳細が記載されています。

Cloud Schedulerの設定

GCPのConsoleから、cloud schedulerを開いてみましょう。そこでcreate jobを選び、下記のように設定をします。ここでFrequencyが実行頻度を設定する部分です。cronと同じフォーマットで実行する頻度を設定することができます。そしてTargetがトリガーの設定部分です。ここではApp Engineのアプリケーション、Cloud Pub/Sub, HTTP Requestの3つを設定することができます。今回のCloudFunctionsはPub/Subをトリガーにしているので、ここではPub/Subを指定しておきましょう。

スクリーンショット 2018-11-11 22.53.10.png

create ボタンを押せば終了です。気になるお値段ですが、こちらのドキュメントによると1人あたり3ジョブまで無料ということです。

動作確認

スクリーンショット 2018-11-11 22.59.31.png

すぐに動作確認をしたいので、上記画面のRun now ボタンをクリックし、Pub/SubのTopicに対してメッセージを送ってみましょう。するとSlackに下記のようにメッセージが送信されます。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f32333630362f32306237373066382d356364322d323232312d363762302d6139623430663830616433382e706e67_censored.jpg

以上で、Cloud FunctionsとCloud Schedulerを利用してDatadogで監視しているホスト数を通知させることができました。今後は、集計期間をpub/subのメッセージで設定できるようにするなど機能を追加していく予定です。もし、使ってくださる方がいて、追加で欲しい機能などございましたら、お気軽にIssue登録おねがいします〜