💸

メール通知統合を使って Snowflake の消費クレジットを通知させる

2023/07/12に公開

つくるもの

次のオブジェクトを使って、Snowflake アカウントでの前日のウェアハウス・クラスタリングによる消費クレジットを毎日朝 9:00 にメールで通知するやーつを作ります。
外部のコンポーネント(AWS Lambda とか)にまったく頼らずやってみます。

  • メール通知統合
  • ストアドプロシージャ
  • タスク

やってみた

メール通信統合

まずメール通知統合を作成します。

通知統合Notification Integration)とは、Snowflake とサードパーティのメッセージング・メールサービスを連携させるためのインタフェースを提供するオブジェクトです。AWS SQS など指定のクラウド上のサービスを利用できるほか、メールサービスであれば Snowflake 側でサービスをホストさせることもできます。今回は後者のパターンを利用します。

次のクエリでメール通知統合を作成します。

create notification integration test_email
    type = EMAIL
    enabled = true
    allowed_recipients = ('your.email@example.com');

allowed_recipients に送信対象となるメールアドレスを登録します。ここに入るアドレスはユーザーによってアクティベートされていることが前提で、そうでないものを登録しようとすると作成時にエラーとなります。

作成したメール通知統合の詳細を確認してみます。

desc notification integration test_email;

descの結果

実際にメール通知統合からメール送信テストを行ってみます。
送信はストアドプロシージャ SYSTEM$SEND_EMAIL を叩くだけで OK です(引数についてはドキュメントを参照してね)。

call system$send_email(
    'test_email', -- メール通知統合の名前
    'your.email@example.com', -- 宛先メールアドレス
    'Email test',  -- メール件名
    'send from snowflake' -- 本文
);

メール送信に成功すると、 no-reply@snowflake.net からメールが届いているはずです。

受信メール

ストアドプロシージャ

どこか適当なスキーマに次のプロシージャを作成します。
クレジットの集計には SNOWFLAKE データベース内の METERING_DAILY_HISTORY ビューを利用します。このビューから現在のアカウントを対象に集計日前日の消費クレジットを引っ張ってきます。

ちなみに SELECT ... INTO ... を使うと、スクリプト変数に SELECT 文で返された行の値をそのまま代入できます。便利。

create or replace procedure daily_warehouse_usage()
    returns varchar
    language sql
    as
    $$
    declare
        credits_billed varchar;
        account_name varchar;
        usage_date varchar;
        msg varchar;
    begin
        select account_name, usage_date, round(sum(credits_billed),3)
        into :account_name, :usage_date, :credits_billed
        from SNOWFLAKE.ORGANIZATION_USAGE.METERING_DAILY_HISTORY
        where account_locator = current_account()
        and usage_date = convert_timezone('Asia/Tokyo',current_timestamp())::date - interval '1 day'
        group by all
        order by usage_date desc
        limit 1;
        msg := :usage_date || 'の利用クレジットは ' || :credits_billed || 'です。';
        call system$send_email(
            'test_email',
            'your.email@example.com',
            :account_name || ': Daily Compute Usage',
            :msg
        );
    end;
    $$
;

プロシージャを作成し、実際に呼び出してみます。

call daily_warehouse_usage();

次のようなメールが送信されるはずです。

sprocの結果

タスク

作成したプロシージャを定期実行させるため、同じスキーマに新たにタスクを定義します。

create or replace task notify_daily_credit_usage
    warehouse = <warehouse_name>
    schedule = 'using cron 0 9 * * * Asia/Tokyo'
as
    call daily_warehouse_usage();

タスクは初期状態で中断(suspend)状態となっているので、以下のクエリで実行可能な状態に変更しておきましょう。

alter task notify_daily_credit_usage resume;

終わりに

通知関連となると、lambda 関数を追加したりメッセージングサービスを立てたりといった作業が入り込んでちょっぴり億劫になってしまいます。Snowflake の場合はそれらがすべて 1 つのエコシステムで完結してしまうので、簡単な通知であればこれで十分そうです。

リソースモニターも活用しつつ、Snowflake のコスト最適化を目指していきましょ〜。

Discussion