Javaでのトレースイベントの出力

テレメトリ API ライブラリの com.snowflake.telemetry.Telemetry クラスを使用して、Javaで記述された関数またはプロシージャハンドラーからトレースイベントを出力できます。 Telemetry クラスはSnowflakeに含まれています。

注釈

Snowflakeテレメトリライブラリを使用すると、関数またはプロシージャの実行環境に他のライブラリが追加されます。詳細については、 Snowflakeテレメトリパッケージの依存関係 をご参照ください。

Mavenでコードをパッケージ化するときにテレメトリライブラリを含める方法については、 テレメトリクラスを使用するためのJavaおよびScala環境の設定 をご参照ください。

イベントテーブルで SELECT コマンドを実行すると、格納されたトレースイベントデータにアクセスできます。詳細については、 トレースデータへのアクセス をご参照ください。

注釈

トレースイベントを追加する際に留意すべきガイドラインについては、 トレースイベントを追加するための一般的なガイドライン をご参照ください。

Snowflakeでのログの設定とメッセージの取得に関する一般的な情報については、 関数とプロシージャからのメッセージのログ をご参照ください。

コードからログする前に、次を実行する必要があります。

  • ハンドラーコードからログされたメッセージを収集するイベントテーブルを設定します。

    詳細については、 イベントテーブルの設定 をご参照ください。

  • 必要なデータがイベントテーブルに格納されるようにトレースレベルが設定されていることを確認してください。

    詳細については、 トレースレベルの設定 をご参照ください。

テレメトリ API のサポートの追加

Telemetry メソッドを使用するには、Snowflakeに含まれるSnowflakeテレメトリライブラリをハンドラーコードで使用できるようにする必要があります。

  • CREATE PROCEDURE または CREATE FUNCTION ステートメントの PACKAGES 句に、 com.snowflake:telemetry パッケージを含めます。PACKAGES 句により、含まれているSnowflakeテレメトリ API がコードで使用できるようになります。

    次の例のコードでは、 PACKAGES 句を使用してテレメトリライブラリとSnowparkライブラリ(Javaで記述されたストアドプロシージャに必要です。詳細については、 Javaでのストアドプロシージャの記述 をご参照ください)を参照します。

    CREATE OR REPLACE PROCEDURE MYPROC(...)
      RETURNS ...
      LANGUAGE JAVA
      ...
      PACKAGES = ('com.snowflake:snowpark:latest', 'com.snowflake:telemetry:latest')
      ...
    
    Copy
  • Javaハンドラーコードに com.snowflake.telemetry パッケージをインポートします。

    import com.snowflake.telemetry.Telemetry;
    
    Copy

トレースイベントの追加

トレースイベントを追加するには、 Telemetry.addEvent メソッドを呼び出してイベントの名前を渡します。オプションで、属性(キーと値のペア)をイベントに関連付けることもできます。

addEvent メソッドには次の署名があります。

public static void addEvent(String name)
public static void addEvent(String name, Attributes attributes)
Copy

次の例のコードは、 testEvent というイベントを追加し、そのイベントに2つの属性 keyresult を関連付けます。

// Adding an event without attributes.
Telemetry.addEvent("testEvent");

// Adding an event with attributes.
Attributes eventAttributes = Attributes.of(
  AttributeKey.stringKey("key"), "run",
  AttributeKey.longKey("result"), Long.valueOf(123));
Telemetry.addEvent("testEventWithAttributes", eventAttributes);
Copy

これらのイベントを追加すると、イベントテーブルに2つの行が作成され、それぞれの RECORD 列に異なる値が含まれます。

{
  "name": "testEvent"
}
Copy
{
  "name": "testEventWithAttributes"
}
Copy

testEventWithAttributes イベント行には、行の RECORD_ATTRIBUTES 列に次の属性が含まれています。

{
  "key": "run",
  "result": 123
}
Copy

スパン属性の追加

Telemetry.setSpanAttribute メソッドを呼び出すと、スパンに関連付けられた属性(キーと値のペア)を設定できます。

setSpanAttribute メソッドには次の署名があります。

public static void setSpanAttribute(String key, boolean value)
public static void setSpanAttribute(String key, long value)
public static void setSpanAttribute(String key, double value)
public static void setSpanAttribute(String key, String value)
Copy

スパンの詳細については、 Snowflakeがトレースイベントを表す方法 をご参照ください。

次の例のコードは4つの属性を作成し、それらの値を設定します。

// Setting span attributes.
Telemetry.setSpanAttribute("example.boolean", true);
Telemetry.setSpanAttribute("example.long", 2L);
Telemetry.setSpanAttribute("example.double", 2.5);
Telemetry.setSpanAttribute("example.string", "testAttribute");
Copy

これらの属性を設定すると、イベントテーブルの RECORD_ATTRIBUTES 列が次のようになります。

{
  "example.boolean": true,
  "example.long": 2,
  "example.double": 2.5,
  "example.string": "testAttribute"
}
Copy

Javaの例

ストアドプロシージャの例

CREATE OR REPLACE PROCEDURE do_tracing()
RETURNS STRING
LANGUAGE JAVA
RUNTIME_VERSION = '11'
PACKAGES=('com.snowflake:snowpark:latest', 'com.snowflake:telemetry:latest')
HANDLER = 'ProcedureHandler.run'
AS
$$
import com.snowflake.snowpark_java.Session;
import com.snowflake.telemetry.Telemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;

public class ProcedureHandler {

  public String run(Session session) {

    // Set span attribute.
    Telemetry.setSpanAttribute("example.proc.do_tracing", "begin");

    // Add an event without attributes.
    Telemetry.addEvent("run_method_start");

    // Add an event with attributes.
    Attributes eventAttributes = Attributes.of(
      AttributeKey.stringKey("example.method.name"), "run",
      AttributeKey.longKey("example.long"), Long.valueOf(123));
    Telemetry.addEvent("event_with_attributes", eventAttributes);

    // Set span attribute.
    Telemetry.setSpanAttribute("example.proc.do_tracing", "complete");

    return "SUCCESS";
  }
}
$$;
Copy

UDF の例

CREATE OR REPLACE FUNCTION add_two_numbers(A FLOAT, B FLOAT) RETURNS FLOAT
LANGUAGE JAVA
PACKAGES=('com.snowflake:telemetry:latest')
HANDLER = 'ScalarFunctionHandler.run'
AS
$$
import com.snowflake.telemetry.Telemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;

class ScalarFunctionHandler {

  public static Double run(Double d0, Double d1) {

    // Set span attribute.
    Telemetry.setSpanAttribute("example.func.add_two_numbers", "begin");

    // Add an event without attributes.
    Telemetry.addEvent("run_method_start");

    // Add an event with attributes.
    Attributes eventAttributes = Attributes.of(
      AttributeKey.stringKey("example.method.name"), "run",
      AttributeKey.longKey("example.long"), Long.valueOf(123));
    Telemetry.addEvent("event_with_attributes", eventAttributes);

    Double response = d0 == null || d1 == null ? null : (d0 + d1);

    // Set span attribute.
    Telemetry.setSpanAttribute("example.func.add_two_numbers.response", response);
    Telemetry.setSpanAttribute("example.func.add_two_numbers", "complete");

    return response;
  }
}
$$;
Copy

UDTF の例

CREATE OR REPLACE FUNCTION digits_of_number(x int)
RETURNS TABLE(result int)
LANGUAGE JAVA
PACKAGES=('com.snowflake:telemetry:latest')
HANDLER = 'TableFunctionHandler'
AS
$$
import com.snowflake.telemetry.Telemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import java.util.stream.Stream;

public class TableFunctionHandler {

  public TableFunctionHandler() {
    // Set span attribute.
    Telemetry.setSpanAttribute("example.func.digits_of_number", "begin");
  }

  static class OutputRow {
    public int result;

    public OutputRow(int result) {
      this.result = result;
    }
  }

  public static Class getOutputClass() {
    return OutputRow.class;
  }

  public Stream<OutputRow> process(int input) {

    // Add an event with attributes.
    Attributes eventAttributes = Attributes.of(
      AttributeKey.longKey("example.received.value"), Long.valueOf(input));
    Telemetry.addEvent("digits_of_number", eventAttributes);

    Stream.Builder<OutputRow> stream = Stream.builder();
    while (input > 0) {

      stream.add(new OutputRow(input %10));
      input /= 10;
    }

    // Set span attribute.
    Telemetry.setSpanAttribute("example.func.digits_of_number", "complete");

    return stream.build();
  }
}
$$;
Copy