Emissão de eventos de rastreamento em Python

Você pode usar o pacote Snowflake telemetry para emitir eventos de rastreamento de um manipulador de função ou procedimento escrito em Python. O pacote está disponível no canal Anaconda Snowflake.

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:

Nota

Para obter diretrizes a serem lembradas ao adicionar eventos de rastreamento, consulte Diretrizes gerais para adicionar eventos de rastreamento.

Adição de suporte ao pacote de telemetria

Para usar o pacote de telemetria, você deve disponibilizar o pacote de telemetria de código aberto Snowflake, que está incluído no Snowflake, para o seu código de manipulador. O pacote está disponível no canal Anaconda Snowflake.

  • Para um procedimento ou função. na cláusula PACKAGES em sua instrução CREATE PROCEDURE ou CREATE FUNCTION, inclua o pacote snowflake-telemetry-python. A cláusula PACKAGES torna o pacote de telemetria do Snowflake incluído disponível para seu código.

  • Para um aplicativo Streamlit. Você pode adicionar o pacote snowflake-telemetry-python para seu aplicativo usando Snowsight ou um arquivo environment.yml..

    O código no exemplo a seguir usa a cláusula PACKAGES para referenciar o pacote de telemetria, bem como a biblioteca Snowpark (que é necessária para procedimentos armazenados escritos em Python – para mais informações, consulte Como escrever procedimentos armazenados em Python).

    CREATE OR REPLACE FUNCTION my_function(...)
      RETURNS ...
      LANGUAGE PYTHON
      ...
      PACKAGES = ('snowflake-telemetry-python')
      ...
    
    Copy
  • Importe o pacote telemetry em seu código.

    from snowflake import telemetry
    
    Copy

Adição de eventos de rastreamento

Você pode adicionar eventos de rastreamento chamando o método telemetry.add_event, passando um nome para o evento. Opcionalmente, você também pode associar atributos - pares chave-valor - a um evento.

O método add_event está disponível na seguinte forma:

telemetry.add_event(<name>, <attributes>)
Copy

onde

  • name é uma cadeia de caracteres Python que especifica o nome do evento de rastreamento.

  • attributes é um objeto de atributos de OpenTelemetry que especifica os atributos para esse evento de rastreamento. Este argumento é opcional. Omita o argumento se você não tiver nenhum atributo a ser especificado para esse evento de rastreamento.

O código do manipulador no exemplo a seguir adiciona dois eventos, FunctionEmptyEvent e FunctionEventWithAttributes. Com FunctionEventWithAttributes, o código também adiciona dois atributos: key1 e key2.

telemetry.add_event("FunctionEmptyEvent")
telemetry.add_event("FunctionEventWithAttributes", {"key1": "value1", "key2": "value2"})
Copy

A adição desses eventos resulta em duas linhas na tabela de eventos, cada uma com um valor diferente na coluna RECORD:

{
  "name": "FunctionEmptyEvent"
}
Copy
{
  "name": "FunctionEventWithAttributes"
}
Copy

A linha de evento FunctionEventWithAttributes inclui os seguintes atributos na coluna RECORD_ATTRIBUTES da linha:

{
  "key1": "value1",
  "key2": "value2"
}
Copy

Adição de atributos de span

Você pode definir atributos - pares chave-valor - associados aos spans chamando o método telemetry.set_span_attribute.

Para obter mais detalhes sobre spans, consulte Como o Snowflake representa eventos de rastreamento.

O método set_span_attribute está disponível na seguinte forma:

telemetry.set_span_attribute(<key>, <value>)
Copy

onde:

O código no exemplo a seguir cria quatro atributos e define seus valores:

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

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"
}
Copy

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 Python OpenTelemetry para criar o span my.span como o span atual com start_as_current_span. Em seguida, ele adiciona um evento com atributos ao novo span usando a `API Python OpenTelemetry`_.

Os dados do evento não serão capturados pela tabela de evento, a menos que o span termine antes que o manipulador conclua a execução. Neste exemplo, o fechamento do span ocorre automaticamente quando a instrução with é concluída.

CREATE OR REPLACE FUNCTION customSpansPythonExample() RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.9
PACKAGES = ('snowflake-telemetry-python', 'opentelemetry-api')
HANDLER = 'custom_spans_function'
AS $$
from snowflake import telemetry
from opentelemetry import trace

def custom_spans_function():
  tracer = trace.get_tracer("my.tracer")
  with tracer.start_as_current_span("my.span") as span:
    span.add_event("Event2 in custom span", {"key1": "value1", "key2": "value2"})

  return "success"
$$;
Copy

Exemplos Python

As seções a seguir fornecem exemplos de como adicionar suporte para eventos de rastreamento do código Python.

Exemplo de procedimento armazenado

CREATE OR REPLACE PROCEDURE do_tracing()
RETURNS VARIANT
LANGUAGE PYTHON
PACKAGES=('snowflake-snowpark-python', 'snowflake-telemetry-python')
RUNTIME_VERSION = 3.9
HANDLER='run'
AS $$
from snowflake import telemetry
def run(session):
  telemetry.set_span_attribute("example.proc.do_tracing", "begin")
  telemetry.add_event("event_with_attributes", {"example.key1": "value1", "example.key2": "value2"})
  return "SUCCESS"
$$;
Copy

Exemplos do Streamlit

import streamlit as st
from snowflake import telemetry

st.title("Streamlit trace event example")

hifives_val = st.slider("Number of high-fives", min_value=0, max_value=90, value=60)

if st.button("Submit"):
    telemetry.add_event("new_submission", {"high_fives": hifives_val})
Copy

Exemplo de UDF

CREATE OR REPLACE FUNCTION times_two(x number)
RETURNS NUMBER
LANGUAGE PYTHON
PACKAGES=('snowflake-telemetry-python')
RUNTIME_VERSION = 3.9
HANDLER = 'times_two'
AS $$
from snowflake import telemetry
def times_two(x):
  telemetry.set_span_attribute("example.func.times_two", "begin")
  telemetry.add_event("event_without_attributes")
  telemetry.add_event("event_with_attributes", {"example.key1": "value1", "example.key2": "value2"})

  response = 2 * x

  telemetry.set_span_attribute("example.func.times_two.response", response)

  return response
$$;
Copy

Quando você chama a API do evento de rastreamento e uma função Python que processa uma linha de entrada, a API será chamada para cada linha processada pela UDF.

Por exemplo, a instrução a seguir chama a função Python definida no exemplo anterior para 50 linhas, resultando em 100 eventos de rastreamento (dois para cada linha):

select count(times_two(seq8())) from table(generator(rowcount => 50));
Copy

Exemplo de UDTF

CREATE OR REPLACE FUNCTION digits_of_number(input number)
RETURNS TABLE(result number)
LANGUAGE PYTHON
PACKAGES=('snowflake-telemetry-python')
RUNTIME_VERSION = 3.9
HANDLER = 'TableFunctionHandler'
AS $$
from snowflake import telemetry

class TableFunctionHandler:

  def __init__(self):
    telemetry.add_event("test_udtf_init")

  def process(self, input):
    telemetry.add_event("test_udtf_process", {"input": str(input)})
    response = input

    while input > 0:
      response = input % 10
      input /= 10
      yield (response,)

  def end_partition(self):
    telemetry.add_event("test_udtf_end_partition")
$$;
Copy

Quando você chama a API do evento de rastreamento no método process() de uma classe do manipulador da UDTF, a API será chamada para cada linha processada.

Por exemplo, a instrução a seguir chama o método process() definido no exemplo anterior para 50 linhas, resultando em 100 eventos de rastreamento (dois para cada linha) adicionados pelo método process():

select * from table(generator(rowcount => 50)), table(digits_of_number(seq8())) order by 1;
Copy