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') ...
Java 처리기 코드에서
com.snowflake.telemetry
패키지를 가져옵니다.import com.snowflake.telemetry.Telemetry;
추적 이벤트 추가하기¶
Telemetry.addEvent
메서드를 호출하고 이벤트 이름을 전달하여 추적 이벤트를 추가할 수 있습니다. 선택적으로 특성(키-값 페어)을 이벤트와 연결할 수도 있습니다.
addEvent
메서드에는 다음 서명이 있습니다.
public static void addEvent(String name)
public static void addEvent(String name, Attributes attributes)
다음 예제의 코드는 testEvent
라는 이벤트를 추가하여 이벤트에 key
및 result
라는 두 가지 특성과 연결합니다.
// 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);
이러한 이벤트를 추가하면 이벤트 테이블에 두 개의 행이 생기는데, RECORD 열의 값이 각각 다릅니다.
{
"name": "testEvent"
}
{
"name": "testEventWithAttributes"
}
testEventWithAttributes
이벤트 행의 RECORD_ATTRIBUTES 열에 다음 특성을 포함합니다.
{
"key": "run",
"result": 123
}
범위 특성 추가하기¶
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)
범위에 대한 자세한 내용은 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");
이러한 특성을 설정하면 이벤트 테이블의 RECORD_ATTRIBUTES 열에 다음 내용이 표시됩니다.
{
"example.boolean": true,
"example.long": 2,
"example.double": 2.5,
"example.string": "testAttribute"
}
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";
}
}
$$;
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;
}
}
$$;
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();
}
}
$$;