Emissão de eventos de rastreamento em Java¶
É possível usar a classe com.snowflake.telemetry.Telemetry
na biblioteca da API de telemetria Snowflake para emitir eventos de rastreamento de um manipulador de função ou procedimento escrito em Java. A classe Telemetry
está incluída no Snowflake.
Nota
O uso da biblioteca de telemetria do Snowflake adiciona outras bibliotecas ao ambiente de execução de sua função ou procedimento. Para obter mais informações, consulte Dependências do pacote de telemetria do Snowflake.
Para obter informações sobre como incluir a biblioteca Telemetry ao empacotar seu código com o Maven, consulte Configuração do ambiente Java e Scala para usar a classe de telemetria.
Você pode acessar os dados de eventos de rastreamento armazenados executando um comando SELECT na tabela de eventos. Para obter mais informações, consulte Visualização dos dados de rastreamento.
Nota
Para obter diretrizes a serem lembradas ao adicionar eventos de rastreamento, consulte Diretrizes gerais para adicionar eventos de rastreamento.
Para obter informações gerais sobre como configurar o registro e recuperar mensagens no Snowflake, consulte Registro de mensagens de funções e procedimentos.
Antes de fazer o registro a partir do código, você deve:
Configurar uma tabela de eventos para coletar mensagens registradas do código do manipulador.
Para obter mais informações, consulte Visão geral da tabela de evento.
Certifique-se de que o nível de rastreamento esteja definido para que os dados desejados sejam armazenados na tabela de eventos.
Para obter mais informações, consulte Definição de níveis para registro, métricas e rastreamento.
Adição de suporte à API de telemetria¶
Para usar os métodos Telemetry
, você deve tornar a biblioteca de telemetria do Snowflake, que está incluída no Snowflake, disponível para o seu código manipulador.
Na cláusula PACKAGES de sua instrução CREATE PROCEDURE ou CREATE FUNCTION, inclua o pacote
com.snowflake:telemetry
. A cláusula PACKAGES torna a API de telemetria do Snowflake incluída disponível para o seu código.O código no exemplo a seguir usa a cláusula PACKAGES para referenciar a biblioteca Telemetry, bem como a biblioteca Snowpark (que é necessária para procedimentos armazenados escritos em Java – para mais informações, consulte Como escrever procedimentos armazenados em Java).
CREATE OR REPLACE PROCEDURE MYPROC(...) RETURNS ... LANGUAGE JAVA ... PACKAGES = ('com.snowflake:snowpark:latest', 'com.snowflake:telemetry:latest') ...
Importe o pacote
com.snowflake.telemetry
em seu código de manipulador Java.import com.snowflake.telemetry.Telemetry;
Adição de eventos de rastreamento¶
Você pode adicionar eventos de rastreamento chamando o método Telemetry.addEvent
, passando um nome para o evento. Opcionalmente, você também pode associar atributos - pares chave-valor - a um evento.
O método addEvent
tem as seguintes assinaturas:
public static void addEvent(String name)
public static void addEvent(String name, Attributes attributes)
O código no exemplo a seguir adiciona um evento chamado testEvent
, associando dois atributos ao evento: key
e 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);
A adição desses eventos resulta em duas linhas na tabela de eventos, cada uma com um valor diferente na coluna RECORD:
{
"name": "testEvent"
}
{
"name": "testEventWithAttributes"
}
A linha de evento testEventWithAttributes
inclui os seguintes atributos na coluna RECORD_ATTRIBUTES da linha:
{
"key": "run",
"result": 123
}
Adição de atributos de span¶
Você pode definir atributos - pares chave-valor - associados aos spans chamando o método Telemetry.setSpanAttribute
.
O método setSpanAttribute
tem as seguintes assinaturas:
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)
Para obter mais detalhes sobre spans, consulte Como o Snowflake representa eventos de rastreamento.
O código no exemplo a seguir cria quatro atributos e define seus valores:
// Setting span attributes.
Telemetry.setSpanAttribute("example.boolean", true);
Telemetry.setSpanAttribute("example.long", 2L);
Telemetry.setSpanAttribute("example.double", 2.5);
Telemetry.setSpanAttribute("example.string", "testAttribute");
A configuração desses atributos resulta no seguinte na coluna RECORD_ATTRIBUTES da tabela de eventos:
{
"example.boolean": true,
"example.long": 2,
"example.double": 2.5,
"example.string": "testAttribute"
}
Adição de spans personalizados¶
Nota
O suporte para spans personalizados é um recurso de versão disponível para todas as contas.
É possível adicionar spans personalizados separados do span padrão criado pelo Snowflake. Para obter detalhes sobre spans personalizados, consulte Adição de spans personalizados a um rastreamento.
O código no exemplo a seguir usa a API OpenTelemetry e a API de propagação de contexto OpenTelemetry para criar um novo span my.span
. Em seguida, ele adiciona um evento com atributos ao novo span. Por fim, o código encerra o span para que os dados do evento do span sejam capturados na tabela de evento. Se o código não chamar o método, os dados não serão capturados na tabela de evento Span.end
.
CREATE OR REPLACE FUNCTION customSpansJavaExample() RETURNS STRING
LANGUAGE JAVA
PACKAGES = ('com.snowflake:telemetry:latest')
HANDLER = 'MyJavaClass.run'
as
$$
import com.snowflake.telemetry.Telemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope;
class MyJavaClass {
public static String run() {
Tracer tracer = GlobalOpenTelemetry.getTracerProvider().get("my.tracer");
Span span = tracer.spanBuilder("my.span").startSpan();
try (Scope scope = span.makeCurrent()) {
// Do processing, adding events that will be captured in a my.span.
// Add an event with attributes.
Attributes eventAttributes = Attributes.of(
AttributeKey.stringKey("key"), "run",
AttributeKey.longKey("result"), Long.valueOf(123));
span.addEvent("testEventWithAttributes", eventAttributes);
span.setAttribute("testAttribute", "value");
} finally {
span.end();
}
return "success";
}
}
$$;
Exemplos de Java¶
Exemplo de procedimento armazenado¶
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";
}
}
$$;
Exemplo de 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;
}
}
$$;
Exemplo de 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();
}
}
$$;