AI事業本部 Dynalystの黒崎(kuro_m88)です。
DatadogのSnowflakeインテグレーションが発表されたのでさっそく試してみました。また、自分の環境だとうまく動作しなかったため、回避方法を紹介します。 Monitor Snowflake with Datadog

Snowflake integrationのスクリーンショット
Snowflake integrationのスクリーンショット

どんな機能なのか

冒頭の画像のように、Snowflakeの各種メトリクスがDatadogに連携できます。
しくみとしては、Datadogが直接Snowflakeに接続してデータを取得するのではなく、サーバ等にインストールしたdatadog-agentからSnowflakeへ定期的(デフォルトは1時間)にクエリをなげてメトリクスを取得します。
取得できるデータはたくさんあり、メトリクスの一覧はドキュメントに記述されています。
ひととおりのメトリクスが自動で取得されるため、普段はクレジットとストレージの利用状況をダッシュボードやアラート設定によりモニタリングしておき、定期的に効率の悪いクエリやウェアハウスのサイズの見直しのために貯蓄したデータを分析する環境がすぐに作れます。

カスタムクエリ

標準で取得できるデータ以外に、自分でクエリを定義して、その結果をメトリクスにするという機能があります。これによりクエリで取得できるデータはなんでもメトリクスにできそうです。
Snowpipeを使ってログを自動で取り込んでいるのですが、カスタムクエリを用いると、取り込み件数の推移やエラー件数の状況が確認できます。

Snowpipeの時系列のメトリクス
Snowpipeの取り込み件数を時系列で

Snowpipeのパイプごとのメトリクス
Snowpipeのパイプごとの流量を表示

custom_queries:    
  - query: |     
      SELECT    
          PIPES.PIPE_NAME,    
          SUM(HISTORY.ROW_COUNT) as ROW_COUNT,    
          SUM(HISTORY.ERROR_COUNT) as ERROR_COUNT     
      FROM    
          SNOWFLAKE.ACCOUNT_USAGE.PIPES PIPES    
          LEFT JOIN    
              SNOWFLAKE.ACCOUNT_USAGE.COPY_HISTORY HISTORY    
          ON  PIPES.PIPE_NAME = HISTORY.PIPE_NAME    
          AND PIPES.PIPE_NAME = HISTORY.PIPE_NAME    
      WHERE    
          PIPES.DELETED IS NULL    
      AND PIPES.IS_AUTOINGEST_ENABLED = 'YES'    
      AND HISTORY.LAST_LOAD_TIME >= DATEADD('HOUR', - 3, CURRENT_TIMESTAMP)    
      AND HISTORY.LAST_LOAD_TIME < DATEADD('HOUR', - 2, CURRENT_TIMESTAMP)    
      GROUP BY    
          PIPES.PIPE_NAME    
      ;     

    columns:    
    - name: pipe_name    
      type: tag    
    - name: snowpipe.last_hour_row_count    
      type: gauge    
    - name: snowpipe.last_hour_error_count    
      type: gauge    

SNOWFLAKE.COPY_HISTORYはドキュメントによると最大2時間の反映の遅延があるようです。そのため、3時間前〜2時間前のデータを最新の値として取得してみました。ほかにもシステムテーブル以外にもアプリケーション固有なDatadogのメトリクスにしたい項目もyamlファイルを更新するだけで追加ができるので非常に便利そうでした。

ここからは、検証した環境や手順、遭遇したエラーとその対処について紹介していきます。

検証環境

  • クラウド: AWS (東京リージョン)
  • VM: Amazon EC2 t3.micro
  • OS: Amazon Linux2
  • Snowflake: AWS (東京リージョン)

Snowflakeにモニタリング用のユーザとロールを作成する

Snowflakeでアカウント全体のモニタリングができるのは初期状態だとACCOUNTADMINというロールを持ったユーザだけです。このユーザは全てのSnowflakeのユーザの中で一番強い権限を持っており、モニタリングの用途で使うには権限が強すぎるので、モニタリングのみできるロールとユーザと、データ取得のためのウェアハウスを別途作成しました。

ロール作成

CREATE ROLE ACCOUNT_MONITOR;  -- モニタリング用のロール, Snowflakeに格納された実データにはアクセスできない

GRANT
  MONITOR EXECUTION, -- 所有していないタスクの実行履歴が取得できる
  MONITOR USAGE, -- アカウントレベルの機能やクレジットの利用状況が取得できる
ON ACCOUNT TO ROLE ACCOUNT_MONITOR;

GRANT
  IMPORTED PRIVILEGES
ON DATABASE SNOWFLAKE TO ROLE ACCOUNT_MONITOR; -- SNOWFLAKEというDBにアクセスできるようにする(ここに各種利用状況のviewなどがある)

GRANT ROLE ACCOUNT_MONITOR TO ROLE ACCOUNTADMIN; -- ACCOUNTADMINを持っている人はロールを切り替えられる, SYSADMINなどでもよさそう

ウェアハウス作成

CREATE WAREHOUSE ACCOUNT_MONITOR_WH WITH WAREHOUSE_SIZE = 'XSMALL' WAREHOUSE_TYPE = 'STANDARD' AUTO_SUSPEND = 60 AUTO_RESUME = TRUE;  -- ウェアハウスの最小課金期間は60秒なので60秒で一時停止するようにする

GRANT USAGE ON WAREHOUSE ACCOUNT_MONITOR_WH TO ROLE ACCOUNT_MONITOR;

ユーザ作成

CREATE USER monitor_user DEFAULT_ROLE = 'ACCOUNT_MONITOR' DEFAULT_WAREHOUSE = 'ACCOUNT_MONITOR_WH' DEFAULT_NAMESPACE = 'SNOWFLAKE';

GRANT ROLE ACCOUNT_MONITOR TO USER account_monitor;

ALTER USER account_monitor SET PASSWORD = 'password12345';

datadog-agentのインストール

DD_API_KEYはDatadogのAPIキーを設定してください。

[ec2-user@ip-172-16-10-23 ~]$ DD_AGENT_MAJOR_VERSION=7 DD_API_KEY=xxxxxxxxxxxxx DD_SITE="datadoghq.com" bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script.sh)"

Snowflake integrationのインストール

標準ではdatadog-agentにSnowflake integrationは入っていないので、追加でインストールします。

[ec2-user@ip-172-16-10-23 ~]$ sudo -u dd-agent datadog-agent integration install datadog-snowflake==2.1.2

設定ファイルをコピーします。

[ec2-user@ip-172-16-10-23 ~]$ sudo -u dd-agent cp /etc/datadog-agent/conf.d/snowflake.d/conf.yaml{.example,}

設定ファイルを編集する

/etc/datadog-agent/conf.d/snowflake.d/conf.yamlを編集します。

init_config:
instances:
  - account: ab12345.ap-northeast-1.aws
    user: monitor_user
    password: password_12345
    role: ACCOUNT_MONITOR

datadog-agentを再起動する

[ec2-user@ip-172-16-10-23 ~]$ sudo systemctl restart datadog-agent

本当はこれで動くはずだった

追記: 2020/11/09 datadog-snowflake 2.1.1 で紹介したワークアラウンドが採用されたため、datadog-snowflake 2.1.1以降を使えばこの問題には遭遇しません。

本当はこれで動くはずだったのですが、今回検証した環境ではうまく動きませんでした。以下のようなエラーが出ます。

2020-11-04 03:02:21 UTC | CORE | DEBUG | (pkg/collector/python/loader.go:141 in Load) | Unable to load python module - datadog_checks.snowflake: unable to import module 'datadog_checks.snowflake': Traceback (most recent call last):
  File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/datadog_checks/snowflake/__init__.py", line 5, in 
    from .check import SnowflakeCheck
  File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/datadog_checks/snowflake/check.py", line 6, in 
    import snowflake.connector as sf
  File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/snowflake/connector/__init__.py", line 21, in 
    from .connection import SnowflakeConnection
  File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/snowflake/connector/connection.py", line 16, in 
    from .incident import IncidentAPI
  File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/snowflake/connector/incident.py", line 15, in 
    from .network import REQUEST_ID
  File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/snowflake/connector/network.py", line 42, in 
    from .description import (
  File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/snowflake/connector/description.py", line 20, in 
    PLATFORM = platform.platform()
  File "/opt/datadog-agent/embedded/lib/python3.8/platform.py", line 1205, in platform
    libcname, libcversion = libc_ver(sys.executable)
  File "/opt/datadog-agent/embedded/lib/python3.8/platform.py", line 193, in libc_ver
    with open(executable, 'rb') as f:
IsADirectoryError: [Errno 21] Is a directory: '/opt/datadog-agent/embedded/lib/python3.8/site-packages'

今回はDatadogのSnowflakeインテグレーションについての記事なので詳細は割愛しますが、どうやらPython3.8以降の標準ライブラリの挙動が関係していそうです。
Python本体へのissueの起票とプルリクエスト、ワークアラウンドとしてdatadogのSnowflakeインテグレーションへこのエラーを回避する実装のプルリクエストを上げてあります。

datadog-snowflakeが動くようにするための修正

恒久的にどう対応すればよいのかは、前述のIssue等で相談して考えようと思っていますが、まずは動かして機能の検証がしたかったので、とりあえず動く方法を紹介します。
修正内容はこのプルリクエストの通りなのですが、Snowflakeインテグレーションのインストール後に編集したほうが動作検証としては楽です。
/opt/datadog-agent/embedded/lib/python3.8/site-packages/datadog_checks/snowflake/__init__.py を以下のように編集します。

# (C) Datadog, Inc. 2020-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)

import sys
if not sys.executable:
    sys.executable = None

from .__about__ import __version__
from .check import SnowflakeCheck

__all__ = ['__version__', 'SnowflakeCheck']

編集したらdatadog-agentを再起動します。これで動くようになるはずです。

まとめ

DatadogのSnowflakeインテグレーションが出たのでさっそく触ってみましたが、とても便利そうです。元々はTableauを使って自前で作り込んだり、メトリクスをDatadogに送信するバッチを作ったりしようかと思っていたのですが、今回のリリースによりその必要がなくなりました。カスタムクエリを実行して、それがそのままメトリクスになるのはとても便利そうで、期待以上の機能でした。
欲を言えば、Snowflakeは公開鍵認証に対応していて、パスワードを使わずに認証することも可能なので、公開鍵認証にも対応してほしいと思いました。OSSなのでコントリビュートすることも可能です。
Snowflakeのモニタリングのためだけにサーバを用意するのはもったいないので、そのままインストールしても動かない件が解決できればコンテナ化して本番運用に載せようと思います。