チュートリアル: ログおよびトレース入門

概要

このチュートリアルでは、関数およびプロシージャハンドラーコードからのログとトレースデータの出力、収集、クエリの基本を紹介します。

このチュートリアルでは Snowsight ウェブインターフェイスを使用しますが、 SQL の実行をサポートする任意のSnowflakeクライアントを使用できます。 Snowsight の詳細については、 ワークシートをはじめるにあたりSnowsightでのワークシートの管理と使用 をご参照ください。

学習内容

このチュートリアルでは、次の方法を学習します。

  • ログとトレースデータを格納するイベントテーブルを作成します。

    Snowflakeは、テーブルの事前定義された構造でログとトレースデータを収集します。

  • ログメッセージとトレースデータをユーザー定義関数(UDF)から出力します。

    ハンドラー言語用に設計された API を使用して、ハンドラーコードからログメッセージとトレースデータを出力できます。

  • イベントテーブルをクエリして、収集されたログとトレースデータを表示します。

    SELECT ステートメントを使用してテーブルにクエリを実行し、収集されたデータを分析できます。

前提条件

  • セッションコンテキストが必要であるため、すべての SQL コマンドを同じ SQL コマンドセッションで実行する必要があります。

    たとえば、これを Snowsight で実行するには、作業をしながらすべてのコードを同じワークシートに貼り付けます。セクションからセクションに進むにつれて、各セクションは前のセクションに基づいて構築されます。

  • ACCOUNTADMIN ロールが使用できなければなりません。

    このチュートリアルでは、 ACCOUNTADMIN ロールを使用してすべてのステップを実行します。ただし、一般的には、実行するアクションに対して特別に定義された権限を持つロールを使用します。たとえば、 UDFs を作成する開発者、収集されたログやトレースデータをクエリするアナリストなどに個別のロールを割り当てることができます。

    ロールの詳細については、 アクティブなロールへの切り替えアクセス制御の考慮事項 をご参照ください。

データベース、ウェアハウス、アクセスの設定

このセクションでは、チュートリアルに必要なウェアハウスとデータベースを作成します。また、このチュートリアルの一部のステートメントを実行するために必要な ACCOUNTADMIN ロールの使用も開始します。

作成しているデータベースには、後でイベントテーブルとユーザー定義関数を作成します。データベースやウェアハウスなど、チュートリアルで作成したすべてのオブジェクトは、不要になったら削除できます。

チュートリアルで使用するデータベースとウェアハウスを作成するには、

  1. Snowsight にサインインします。

  2. ACCOUNTADMIN ロールに切り替えます

  3. Worksheets を開きます。

  4. + » SQL Worksheet を選択します。

  5. 新しいワークシートの名前Logging-tracing tutorial に変更します。

  6. 新しいワークシートに次のステートメントを貼り付けて実行し、データベースを作成します。新しいデータベースはこのチュートリアル専用です。

    CREATE OR REPLACE DATABASE tutorial_log_trace_db;
    
    Copy
  7. 次のステートメントを貼り付けて実行し、ウェアハウスを作成します。新しいウェアハウスは、このチュートリアル専用です。

    CREATE OR REPLACE WAREHOUSE tutorial_log_trace_wh
      WAREHOUSE_TYPE = STANDARD
      WAREHOUSE_SIZE = XSMALL;
    
    Copy

このセクションでは、チュートリアルに必要な要素を配置します。次のセクションでは、ログとトレースデータを保存するためのイベントテーブルを作成します。

イベントテーブルを作成する

このセクションでは、イベントテーブルを作成します。ハンドラーコードがログメッセージとトレースデータを出力すると、Snowflakeは出力されたデータをイベントテーブルの行に保存します。イベントテーブルをクエリしてデータを分析できます。

ログおよびトレースデータを収集するには、イベントテーブルを作成する必要があります。イベントテーブルは常に、Snowflakeによって 事前定義された構造 を使用します。

重要

このセクションを完了するには、 ACCOUNTADMIN ロールを使用できるようにする必要があります。これは、アカウントを調整して、新しいイベントテーブルをアカウントのアクティブなイベントテーブルにするときに必要です。

イベントテーブルを作成し、それをアカウントのアクティブなイベントテーブルにするには、

  1. 次のステートメントを貼り付けて実行し、イベントテーブルを作成します。

    CREATE OR REPLACE EVENT TABLE tutorial_event_table;
    
    Copy

    このテーブルは、Snowflakeがログとトレースデータを格納する場所です。

  2. 次のステートメントを貼り付けて実行し、作成したイベントテーブルがそのアカウントに対してアクティブになるようにアカウントを調整します。

    ALTER ACCOUNT SET EVENT_TABLE = tutorial_log_trace_db.public.tutorial_event_table;
    
    Copy

    このステートメントは、現在のアカウントにあるハンドラーからのログメッセージとトレースデータを保存するためにSnowflakeが使用するテーブルとして、新しいイベントテーブルを設定します。1つのアカウントに対してアクティブなイベントテーブルを1つだけ持つことができます。

このセクションでは、イベントテーブルを作成しました。次のセクションでは、Snowflakeがテーブルに格納するログメッセージの出力を開始します。

ログメッセージの出力

このセクションでは、ログメッセージを出力するPythonハンドラーコードを使用して、ユーザー定義関数(UDF)を作成します。コードがログメッセージを出力すると、Snowflakeはメッセージデータを収集し、作成したイベントテーブルに格納します。

Snowflakeは、サポートされている各ハンドラー言語からのメッセージをログするための APIs をサポートしています。Pythonで記述したハンドラーの場合は、Pythonの標準ライブラリの logging モジュールを使用できます。

ログメッセージを出力する UDF を作成するには、

  1. 次のステートメントを貼り付けて実行し、ログレベルを INFO に設定します。

    ALTER SESSION SET LOG_LEVEL = INFO;
    
    Copy

    これは、 UDF の実行時にSnowflakeがキャプチャする必要があるログメッセージの重大度を指定します。この場合、レベルは情報(INFO)から最も重大なメッセージ(FATAL)までのすべてのメッセージを許可します。

  2. 次のステートメントを貼り付けて実行し、ユーザー定義関数を作成します。

    CREATE OR REPLACE FUNCTION log_trace_data()
    RETURNS VARCHAR
    LANGUAGE PYTHON
    RUNTIME_VERSION = 3.8
    HANDLER = 'run'
    AS $$
    import logging
    logger = logging.getLogger("tutorial_logger")
    
    def run():
      logger.info("Logging from Python function.")
      return "SUCCESS"
    $$;
    
    Copy

    コード内の強調表示された行は次を実行します。

    • Python logging モジュールをインポートして、ハンドラーコードで使用できるようにします。

    • ロガーを作成します。これは、コードがメッセージをログするために使用するインターフェイスを公開します。

    • INFO レベルでメッセージをログします。

  3. 次のステートメントを貼り付けて実行し、作成した関数を実行します。

    SELECT log_trace_data();
    
    Copy

    これにより、次の出力が生成されます。さらに、関数が実行されると、Snowflakeがイベントテーブルに収集したログメッセージが出力されました。

    --------------------
    | LOG_TRACE_DATA() |
    --------------------
    | SUCCESS          |
    --------------------
    

このセクションでは、 UDF からログメッセージを出力しました。次のセクションでは、イベントテーブルにクエリを実行して、メッセージに関連するデータを取得します。

ログメッセージのクエリ

このセクションでは、前のセクションで実行した UDF によって出力されたログメッセージデータのイベントテーブルをクエリします。

注釈

ハンドラーコードによって出力されたログまたはトレースデータがイベントテーブルに記録されるまでに数秒かかる場合があります。結果がすぐに表示されない場合は、数秒後にもう一度試してください。

Snowflakeは、 事前定義されたイベントテーブル列 を使用して、次の種類のログとトレースデータを収集および格納します。

  • ハンドラーコードから出力されるデータ (ログメッセージやトレースイベントデータなど)。

    これらは、 RECORD_TYPE、 RECORD、 RECORD_ATTRIBUTES などの列にあります。

  • ログまたはトレースデータが出力された コンテキストに関するデータ (タイムスタンプ、データ出力元のハンドラーメソッドの名前など)。

    このデータは、 RESOURCE_ATTRIBUTES、 TIMESTAMP、 SCOPE などの列にあります。

ログメッセージデータのためにイベントテーブルをクエリするには、次を実行します。

  1. 次のステートメントを貼り付けて実行し、イベントテーブルをクエリします。

    SELECT
      TIMESTAMP AS time,
      RESOURCE_ATTRIBUTES['snow.executable.name'] as executable,
      RECORD['severity_text'] AS severity,
      VALUE AS message
    FROM
      tutorial_log_trace_db.public.tutorial_event_table
    WHERE
      RECORD_TYPE = 'LOG'
      AND SCOPE['name'] = 'tutorial_logger';
    
    Copy

    一部の列には、キーと値のペアとして表現された構造化データが含まれています。このクエリでは、 RECORD['severity_text'] などの 括弧表記 を使用して列内の属性キーを指定します。

    また、括弧表記(SCOPE['name'])は、ハンドラーコードで作成したPythonロガー tutorial_logger で、ログエントリが出力される列の値のみを選択することを指定する場合にも使用します。

  2. 出力を表示します。

    -----------------------------------------------------------------------------------------------------------
    | TIME                | EXECUTABLE                           | SEVERITY | MESSAGE                         |
    -----------------------------------------------------------------------------------------------------------
    | 2023-04-19 22:00:49 | "LOG_TRACE_DATA():VARCHAR(16777216)" | "INFO"   | "Logging from Python function." |
    -----------------------------------------------------------------------------------------------------------
    

    この出力は、 イベントテーブルの事前定義列 のそれぞれに、収集されたデータの一部がどのように含まれているかを示しています。 EXECUTABLESEVERITY の値については、括弧表記を使用して、必要な値を持つ属性を指定しました。

    出力列

    説明

    TIME

    エントリが作成された時刻(TIMESTAMP 列から)。

    EXECUTABLE

    UDF 名前とパラメーター(RESOURCE_ATTRIBUTES 列の snow.executable.name 属性から)。

    SEVERITY

    ログエントリの重大度(RECORD 列の severity_text 属性から)。

    MESSAGE

    ログメッセージ(VALUE 列から)。

このセクションでは、 SELECT ステートメントを使用してログデータをクエリしました。次のセクションでは、トレースデータを出力するように UDF を更新します。

トレースデータの出力

このセクションでは、トレースデータも出力されるように UDF ハンドラーコードを更新します。コードがトレースデータを出力すると、Snowflakeはデータを収集し、作成したイベントテーブルに格納します。

トレースデータには、スパンにグループ化されたイベントデータやキーと値のペアとしてキャプチャされたデータなどの構造的な性質があり、通常のログデータよりもコードのアクティビティの詳細な全体像を組み立てることができます。

Snowflakeは、サポートされている各ハンドラー言語からトレースデータを出力するための APIs をサポートしています。Pythonで記述したハンドラーの場合は、Snowflake telemetry パッケージを使用できます。

トレースデータを出力するように UDF を更新するには、

  1. 次のステートメントを貼り付けて実行し、キャプチャするトレースデータを指定します。

    ALTER SESSION SET TRACE_LEVEL = ON_EVENT;
    
    Copy

    これにより、トレースレベルが ON_EVENT に設定されます。これは、自分が作成したコードによって明示的に出力されたトレースデータのみをキャプチャするように指定します。

  2. 次のステートメントを貼り付けて実行し、トレースデータを出力する UDF を作成します。

    CREATE OR REPLACE FUNCTION log_trace_data()
    RETURNS VARCHAR
    LANGUAGE PYTHON
    PACKAGES = ('snowflake-telemetry-python')
    RUNTIME_VERSION = 3.8
    HANDLER = 'run'
    AS $$
    import logging
    logger = logging.getLogger("tutorial_logger")
    from snowflake import telemetry
    
    def run():
      telemetry.set_span_attribute("example.proc.run", "begin")
      telemetry.add_event("event_with_attributes", {"example.key1": "value1", "example.key2": "value2"})
      logger.info("Logging from Python function.")
      return "SUCCESS"
    $$;
    
    Copy

    このコードを実行すると、以前に作成した関数は、トレースデータを出力するコードを追加する関数に置き換えられます。強調表示された行は、次を実行します。

    • telemetry パッケージを含んでいる snowflake-telemetry-python を UDFの実行環境に追加します。

    • telemetry パッケージをインポートして、その関数を呼び出せるようにします。

    • コードの実行時に、Snowflakeが作成するスパンに属性と属性値を設定します。

      スパンは、プロシージャまたは UDFの実行単位を表し、その中には複数のイベントを追加できます。

    • スパンの一部として記録するイベント(独自の属性を持つ)を追加します。

  3. 次のステートメントを貼り付けて実行し、作成した関数を実行します。

    SELECT log_trace_data();
    
    Copy

    これにより、次の出力が生成されます。さらに、関数が実行されると、Snowflakeがイベントテーブルに収集したトレースデータが出力されました。

    --------------------
    | LOG_TRACE_DATA() |
    --------------------
    | SUCCESS          |
    --------------------
    

このセクションでは、 UDF からトレースデータを出力しました。次のセクションでは、イベントテーブルにクエリを実行して、トレースに関連するデータを取得します。

トレースメッセージのクエリ

このセクションでは、前のセクションで実行した UDF によって出力されたトレースデータのイベントテーブルをクエリします。

注釈

ハンドラーコードによって出力されたログまたはトレースデータがイベントテーブルに記録されるまでに数秒かかる場合があります。結果がすぐに表示されない場合は、数秒後にもう一度試してください。

記述したクエリは、関数によって出力されたイベントに関するコンテキスト情報を取得します。そのコンテキストには、それを出力した関数の名前が含まれます。

トレースデータのイベントテーブルをクエリするには、次を実行します。

  1. 次のステートメントを貼り付けて実行し、トレースデータのイベントテーブルをクエリします。

    SELECT
      TIMESTAMP AS time,
      RESOURCE_ATTRIBUTES['snow.executable.name'] AS handler_name,
      RECORD['name'] AS event_name,
      RECORD_ATTRIBUTES AS attributes
    FROM
      tutorial_log_trace_db.public.tutorial_event_table
    WHERE
      RECORD_TYPE = 'SPAN_EVENT'
      AND HANDLER_NAME LIKE 'LOG_TRACE_DATA%';
    
    Copy

    一部の列には、キーと値のペアとして表現された構造化データが含まれています。これらの場合、コードに示すように、 括弧表記 を使用して列内の属性値を選択できます。

  2. 出力を表示します。

    -----------------------------------------------------------------------------------------------------------------------------------------------------
    | TIME                    | HANDLER_NAME                         | EVENT_NAME              | ATTRIBUTES                                             |
    -----------------------------------------------------------------------------------------------------------------------------------------------------
    | 2023-05-10 20:49:35.080 | "LOG_TRACE_DATA():VARCHAR(16777216)" | "event_with_attributes" | { "example.key1": "value1", "example.key2": "value2" } |
    -----------------------------------------------------------------------------------------------------------------------------------------------------
    

    この出力は、 イベントテーブルの事前定義列 のそれぞれに、収集されたデータの一部がどのように含まれているかを示しています。 EXECUTABLESEVERITY の値については、括弧表記を使用して、値が必要な属性を指定しました。

    出力列

    説明

    TIME

    エントリが作成された時刻(TIMESTAMP 列から)。

    HANDLER_NAME

    UDF 名前とパラメーター(RESOURCE_ATTRIBUTES 列の snow.executable.name 属性から)。

    EVENT_NAME

    add_event 関数で追加されたイベントの名前(RECORD 列の name 属性から)。

    ATTRIBUTES

    イベントに付随するために追加された属性(RECORD_ATTRIBUTES 列から)。

このセクションでは、作成した UDF によって出力されたトレースデータのイベントテーブルをクエリしました。最後のセクションでは、チュートリアル中に行ったことに関連する情報へのリンクが表示されます。

詳細

これで完了しました。上出来です。

このチュートリアルでは、ハンドラーコードからログとトレースデータを出力および格納し、格納されたデータのクエリ方法を端から端まで見渡すことができました。その際、次も学びました。