9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Google Cloud】Google Cloudの課金データを日次でSlackで通知する

Last updated at Posted at 2022-06-03

はじめに

Google Cloudの課金データを日次でSlackに通知する仕組みを作成してみたため、まとめてみました。

下記のサイトを参考にしています。
BigQuery 破産で泣かないために。。GCP 利用料金を bot で Slack に通知してみた
GASで手軽に SlackへのKPI通知Botを作る
BigQuery課金情報をslackへの通知機能を作る

1. 使用したもの

  • Cloud Billing
  • BigQuery
  • Google Apps Script
  • Slack

2. 仕組み

2-1. 構成図

image.png

2-2. 処理の流れ

① Google Cloudの課金データをBigQueryのデータセットにエクスポートする
② BigQueryに対しGoogle Apps Scriptを使用してクエリを実行する
③ クエリの結果をSlackに通知する

3. 設定内容

サービスごとの設定内容を説明します。
※Google CloudのCloud BillingやBigQueryのアクセス権限がある前提で説明します。

3-1. Cloud Billing、BigQuery

GCPコンソールのナビゲーションメニューの「お支払い」から「課金データのエクスポート」を選択します。
image.png

BigQueryにエクスポートする課金データは下記の3タイプがあります。
・標準の使用料金データ
・詳細な使用料金データ
・料金データ
それぞれの課金データの説明はCloud Billingのドキュメントを参照ください。

今回は標準の使用料金データをBigQueryのデータセットにエクスポートします。
「標準の使用料金」の「設定を編集」を選択します。
image.png

課金データをエクスポートするプロジェクトと、エクスポート先のBigQueryのデータセットを指定します。
既に課金データをエクスポートする際に使用するデータセットを作成済みの場合は、そちらを選択してください。

今回は課金データのエクスポート設定の中でデータセットを作成します。
「データセット」から「新しいデータセットの作成」を選択します。
image.png

「データセットID」と「データのロケーション」を選択します。
今回はテーブルの有効期限や詳細オプションの暗号化は設定しません。
image.png

データセットの作成後、作成したデータセットが課金データのエクスポートに設定されていることを確認し、保存します。

すると、課金データのエクスポート設定が有効になることを確認できます。
image.png

GCPコンソールのナビゲーションメニューの「BigQuery」から「SQLワークスペース」を選択し、前述した手順で作成したデータセットが存在することを確認できます。
課金データのエクスポートの設定後、しばらく放置してから確認すると、課金データがエクスポートされているはずです。
※今回は3時間ほどかかりました。
image.png

データセットに対しクエリを実行し、サービスごとの課金データを参照してみます。

▼クエリ

SELECT
	DATE(TIMESTAMP_ADD(usage_start_time, INTERVAL 9 HOUR)) AS query_date,
	service.description,
	SUM(cost) AS cost,
	currency
FROM
	`プロジェクトID.データセット名.テーブル名`
GROUP BY 
	query_date,
	service.description,
	currency
HAVING
	query_date =  DATE_ADD(DATE(TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 9 HOUR)), INTERVAL -1 DAY)
ORDER BY
	query_date;

▼実行結果
image.png

3-2. Slack

先に、課金データを通知するためのSlackチャンネルを作成します。
今回は下記のように作成してみました。
image.png

チャンネルを作成したら、slack apiにてSlackに通知するためのアプリを作成します。

「From scratch」を選択します。
image.png

作成するアプリの名前を入力し、連携先のSlackワークスペースを選択した後、「Create App」を選択します。
image.png

作成したSlackチャンネルにアプリを連携していきます。

「Incoming Webhooks」を選択します。
image.png

Incoming Webhooksを有効にします。
image.png

通知先のワークスペースを選択します。
image.png
image.png

アプリとSlackチャンネルが連携されると、Slackチャンネルに下記のメッセージが表示されます。
image.png

3-3. Google Apps Script

前述した方法で、Google Cloudの課金データをBigQueryのデータセットにエクスポートできるようにしました。
Google Apps ScriptからBigQueryに対しクエリを実行して、Google Cloudの課金データを取得し、結果をSlackに通知します。

Google Apps Scriptのサイトで「Start Scripting」を選択します。
image.png

Google Apps Scriptのコンソール画面が開いたら、「新しいプロジェクト」を選択します。
image.png

下記の処理を実施するプログラムをJavaScriptで記載します。
・Google Cloudの課金データを取得する
・Slackメッセージを組み立て、ポストする

▼プログラム

// BigQueryに対しクエリ実行
function runQuery() {
    var projectId = "プロジェクトID";
    var request = {
      "query" : "SELECT DATE(TIMESTAMP_ADD(usage_start_time, INTERVAL 9 HOUR)) AS query_date, service.description, SUM(cost) AS cost, currency FROM `プロジェクトID.データセット名.テーブル名` GROUP BY   query_date, service.description, currency HAVING query_date =  DATE_ADD(DATE(TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 9 HOUR)), INTERVAL -1 DAY) ORDER BY query_date;", 
      "useLegacySql": false,
    };

    var queryResults = BigQuery.Jobs.query(request, projectId);
    var jobId = queryResults.jobReference.jobId;
    var sleepTimeMs = 500;
    while (!queryResults.jobComplete) {
      Utilities.sleep(sleepTimeMs);
      sleepTimeMs *= 2;
      queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
    }

    var rows = queryResults.rows;
    while (queryResults.pageToken) {
      queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
        pageToken: queryResults.pageToken
      });
      rows = rows.concat(queryResults.rows);
    }

    return rows
  }

// Slackメッセージの組み立て、ポスト
function postSlack(date, description, cost, currency) {
    // メッセージを組み立てる
    var body = {
      "attachments" : [
        {
          "color": "00FF00",
          "fields": [
            {
              "title": "日付",
              "value": date,
              "short": true
            },
            {
              "title": "サービス名",
              "value": description,
              "short": true
            },
            {
                "title": "金額",
                "value": cost + " [" + currency + "]",
                "short": true
            }
          ],
        }
      ]
    };

    // ポスト
    var webhookURL = 'Webhook URL';
    var options = {
        'method' : 'POST',
        'contentType' : 'application/json',
        'payload' : JSON.stringify(body),
    };
    UrlFetchApp.fetch(webhookURL, options);
}

// この関数を最初に実行する
function main(){
    var rows = runQuery();
    var date = "";
    var description= "";
    var cost= "";
    var currency= "";

    for (let i=0; i<rows.length; i++) {
      date = rows[i].f[0].v;
      description = rows[i].f[1].v;
      cost = rows[i].f[2].v;
      currency = rows[i].f[3].v;
      postSlack(date, description, cost, currency);
    }
}

注意点(つまづいた箇所)

1点目:プロジェクトを実行する際に、最初に実行する関数を選択してください。
ここで最初に実行する関数を指定し忘れていて、うまく動かなかったことがあります。
image.png

2点目:サービス「BigQuery API」を有効にしてください。
image.png
image.png

こちらを有効にしておかないと、BigQueryでクエリを実行する際に下記のようなエラーが発生します。
▼実行ログ
image.png

3-4. 動作確認

それでは、正常に動作するか確認してみます。
画面上部の「実行」ボタンをクリックして実行します。
ソースの気になる箇所にブレークポイントを貼り、デバッグ実行することもできます。
image.png

▼実行ログ
image.png
▼Slackの通知用チャンネル
image.png
動きました。
実行したのが2022-06-01で、前日(2022-05-31)の課金データがサービスごとに通知されました。

プログラムが動作することは確認できたため、これを定期的に実行するように設定します。

作成したプロジェクトの「トリガー」を選択します。
image.png

右下の「+トリガーを追加」ボタンを選択します。
image.png

今回はGoogle Cloudの課金データを日次で通知したいので、下記のように設定します。
image.png
設定が完了したら、「保存」を選択します。
指定した日時でSlackに通知されるのを待ちます。

翌日、午前9時~10時の間に実行するように設定していましたが、無事Slackチャンネルに通知されていることを確認できました。

▼実行数
image.png
▼Slackの通知用チャンネル
image.png

おわりに

今回はGoogle Cloudの課金データを通知するといったことをやってみました。
Google Cloudは最近触り始めて、今回使用したサービス以外の物はまだ使ったことがないので、
どんどん活用しながら学んでいきたいと思います。

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?