在 Java 中发出跟踪事件

您可以使用 遥测 API (https://javadoc.io/doc/com.snowflake/telemetry/latest/index.html) 库中的 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 的事件,并为事件关联了两个属性: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

添加这些事件会在事件表中添加两行,每行在列中 RECORD 具有不同的值:

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

testEventWithAttributes 事件行包含行的 RECORD_ATTRIBUTES 列中的以下属性:

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

添加 Span 属性

您可以通过调用 Telemetry.setSpanAttribute 方法来设置与 span 关联的属性(键值对)。

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

有关 Span 的详细信息,请参阅 Snowflake 如何表示跟踪事件

以下示例中的代码创建四个属性并设置其值:

// 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
语言: 中文