ハンドラー・コードからメトリクス・データを出力する

プロシージャーや UDF 、メトリックス・データを出力させるために、ハンドラーにコードを追加する必要はありません。Snowflakeは収集したデータをイベントテーブルに生成します。

メトリクスの測定方法

JavaとPythonの実行環境が異なるため、収集されるメトリクス・データも異なります。収集したデータに関する参考情報は、 RECORD コラム リファレンス をご参照ください。

キャプチャされたデータが実行環境にどのように対応するかを以下に説明します。

Java:

JVM (Java Virtual Machine) CPU とメモリ・メトリクスが各クエリ ID についてレポートされます。

各ストアド・プロシージャには、独自の JVM が割り当てられます。以下は、収集された指標データについて説明したものです:

  • process.memory.usage: ストアドプロシージャハンドラを実行する JVM によって消費されるメモリ量(バイト)。

  • process.cpu.utilization: 論理的 CPU に対する実時間で分割された合計 CPU 時間、1.0は利用率100%を示すパーセンテージで測定。合計 CPU 時間は、アイドリング以外のタスクに費やされた時間の合計です。

クエリで呼び出されるJavaとScalaの UDF は、それぞれ単一の JVM を共有します。メトリック値は、クエリ内の各JavaまたはScala関数にわたって集約されます。以下は、収集された指標データについて説明したものです:

  • process.memory.usage: メモリ使用量。クエリで呼び出されるすべての関連Java関数の合計として表示される。

  • process.cpu.utilization: CPU 使用量。クエリで呼び出されるJavaとScalaの全関数の平均値で示される。

Python:

Pythonの各関数やプロシージャの CPU とメモリメトリクスが報告されます。

各ストアドプロシージャは1つのPythonプロセスでのみ実行されます。以下は、収集された指標データについて説明したものです:

  • process.memory.usage: Python プロセスがストアドプロシージャハンドラを実行する際に消費するメモリ量(バイト)。

  • process.cpu.utilization: 論理的 CPU に対する実時間で分割された合計 CPU 時間。パーセンテージで測定され、1.0は100パーセントの使用を示す。合計 CPU 時間は、アイドリング以外のタスクに費やされた時間の合計です。

それぞれの UDF は、複数のPython実行プロセス上で実行できます。値は複数のプロセスにまたがって集計されます。以下は、収集された指標データについて説明したものです:

  • process.memory.usage: メモリ使用量。 UDF の関連するPythonプロセスの合計として表示される。

  • process.cpu.utilization: 報告された CPU 、その UDF の関連するすべてのPythonプロセスの平均として示される。

Pythonの例

以下の手順を使用して、メトリクスのサンプル・データを生成します。

  1. セッションのメトリクス・レベルを設定します。 METRIC_LEVEL パラメータは、自動計測されたリソース・メトリクスのデータ・ポイントをイベント・テーブルに出力するかどうかを制御します。このパラメータは、 NONE または ALL に設定することができ、オブジェクト・レベルとセッション・レベルで設定することができます。詳細については、 ロギング、メトリクス、トレースのレベル設定 をご参照ください。

    ALTER SESSION SET METRIC_LEVEL = ALL;
    
    Copy
  2. ストアドプロシージャを作成します。

    CREATE OR REPLACE PROCEDURE DEMO_SP(n_queries number)
    RETURNS VARCHAR(16777216)
    LANGUAGE PYTHON
    RUNTIME_VERSION = '3.10'
    PACKAGES = ('snowflake-snowpark-python', 'snowflake-telemetry-python==0.2.0')
    HANDLER = 'my_handler'
    AS $$
    import time
    def my_handler(session, n_queries):
      import snowflake.snowpark
      from snowflake.snowpark.functions import col, udf
      from snowflake import telemetry
    
      session.sql('create or replace stage udf_stage;').collect()
    
      @udf(name='example_udf', is_permanent=True, stage_location='@udf_stage', replace=True)
      def example_udf(x: int) -> int:
        # This UDF will consume 1GB of memory to illustrate the memory consumption metric
        one_gb_list = [0] * (1024**3 // 8)
        return x
    
      pandas_grouped_df = session.table('snowflake.account_usage.query_history').select(
        col('total_elapsed_time'),
        col('rows_written_to_result'),
        col('database_name'),
        example_udf(col('bytes_scanned'))
      ).limit(n_queries)\
      .to_pandas()\
      .groupby('DATABASE_NAME')
    
      mean_time = pandas_grouped_df['TOTAL_ELAPSED_TIME'].mean()
      mean_rows_written = pandas_grouped_df['ROWS_WRITTEN_TO_RESULT'].mean()
    
      return f"""
      {mean_time}
      {mean_rows_written}
      """
    $$;
    
    Copy
  3. ストアドプロシージャを実行する

    CALL DEMO_SP(100);
    
    Copy
  4. クエリが完了したら、 メトリックス・データの表示 の説明に従ってメトリクス・データを表示します。