Acompanhar seu pipeline de dados ou aplicação é essencial no desenvolvimento. Sem logging e tracing adequados, manter tudo funcionando de forma estável vira um desafio. Alertas são fundamentais para dar contexto quando algo dá errado. Se aparecem discrepâncias, você precisa rastrear o problema pela lógica de transformação. Para depurar o código, é essencial ter visibilidade sobre o comportamento dele — coisas como valores de variáveis, mensagens de saída e resultados de fórmulas, que normalmente são registrados de diferentes maneiras. O Snowflake oferece recursos nativos de logging e tracing usando bibliotecas padrão do mercado, deixando tudo bem acessível para quem desenvolve. Vamos ver como configurar logging de eventos e tracing no Snowflake usando esses recursos.
O que são Event Tables?
As event tables foram lançadas em public preview em maio de 2023. São um tipo especial de tabela do Snowflake, com algumas diferenças em relação às tabelas padrão:
- Conjunto predefinido de colunas, que não pode ser modificado
- Usadas exclusivamente para armazenar dados de logging e tracing
- Só é possível ter uma event table ativa por conta
Os casos de uso mais comuns são capturar informações de logging do código dos seus handlers (stored procedures, UDFs) ou coletar dados de tracing em native apps.
Trabalhando com Event Tables
Habilitar uma event table na sua conta envolve alguns passos, conforme a imagem a seguir:
1. Criar a EVENT TABLE
Primeiro, precisamos criar uma event table. Isso é feito com uma instrução CREATE TABLE específica:
CREATE EVENT TABLE my_db.logging.my_event_table;
Não é preciso especificar as colunas, pois a tabela já vem com uma lista predefinida. Por enquanto, só dá para ter uma event table ativa em toda a conta.
2. Associar a event table à conta
Para colocar a event table em uso, precisamos associá-la à nossa conta. Isso é feito com a instrução ALTER ACCOUNT, ou seja, apenas a role ACCOUNTADMIN consegue executar essa operação. Também é necessário ter privilégios de OWNERSHIP ou INSERT na event table.
ALTER ACCOUNT SET EVENT_TABLE = my_db.logging.my_event_table;
3. Começar a capturar os eventos de log
Agora podemos enriquecer a UDF/UDTF ou a stored procedure com código de logging. Dependendo da linguagem do seu handler, dá para usar APIs e bibliotecas de logging nativas.
| Linguagem | Biblioteca de Logging |
|---|---|
| Java | SLF4J API |
| JavaScript | Snowflake JavaScript API |
| Python | módulo logging |
| Scala | SLF4J API |
| Snowflake scripting | Função Snowflake SYSTEM$LOG |
Vamos usar Python como exemplo.
CREATE OR REPLACE FUNCTION my_UDF()
RETURNS VARCHAR
RUNTIME_VERSION = 3.8
HANDLER = 'run'
AS $$
import logging
logger = logging.getLogger("my_logger")
def run():
logger.info("Processing start")
...
...
logger.error("Some error in your code")
return value
Para começar a fazer logging, basta importar o módulo logging e instanciar o objeto logger. Depois é só usar como em qualquer aplicação Python e registrar diferentes níveis, como INFO, WARNING ou ERROR.
Vamos a mais um exemplo, agora com SQL scripting, mostrando como adicionar logging quando o código do handler está em SQL. No caso do Snowflake Scripting, é preciso usar a função SYSTEM$LOG. Ela também suporta diferentes níveis de mensagem, como info, warning e error.
Temos uma stored procedure simples que retorna uma tabela. Para enriquecê-la com mensagens informativas de log, podemos fazer assim:
create or replace procedure returning_table()
returns table(id number, name varchar)
language sql
as
declare
result RESULTSET DEFAULT (SELECT 1 id, 'test value' name);
begin
SYSTEM$LOG('info', 'Returning a table');
return table(result);
end;
4. Consultando a event table
Já adicionamos o logging ao código do nosso handler. Agora é hora de verificar os eventos registrados consultando a event table. Cada mensagem registrada contém:
- Timestamp — quando o evento foi registrado
- Scope — por exemplo, o nome da classe onde o evento de log foi criado
- Nível de severidade do log — por exemplo, info, warning, error
- A mensagem de log em si
Para ver a lista completa de colunas da event table, consulte a documentação. Algumas colunas são pares chave-valor que armazenam vários atributos. Dá para extraí-los com consultas como esta:
create or replace procedure returning_table()
returns table(id number, name varchar)
language sql
as
declare
result RESULTSET DEFAULT (SELECT 1 id, 'test value' name);
begin
SYSTEM$LOG('info', 'Returning a table');
return table(result);
end;
E é assim que a saída da event table aparece:
Usando traces para registrar dados estruturados
Outro caso de uso das event tables é coletar dados de trace do seu código. Os dados de trace são informações de logging estruturadas em pares chave-valor, que oferecem uma visão mais detalhada do comportamento do código do que os dados de log costumam dar. Vamos a um exemplo coletando dados de trace de uma UDF em Python:
select
resource_attributes:"snow.database.id"::number,
resource_attributes:"snow.database.name"::varchar,
resource_attributes:"snow.executable.name"::varchar,
resource_attributes:"snow.executable.type"::varchar,
resource_attributes:"snow.owner.name"::varchar,
resource_attributes:"snow.query.id"::varchar,
resource_attributes:"snow.warehouse.name"::varchar,
resource_attributes:"telemetry.sdk.language"::varchar,
record,
value
from my_event_table;
Precisamos importar o snowflake-telemetry-package, que traz os métodos necessários.
Podemos usar o método set_span_attribute para definir pares chave-valor no objeto span. Os objetos span guardam os dados de telemetria gerados quando a função ou procedure é executada com sucesso, representando a unidade de execução da UDF ou stored procedure. Dá para adicionar vários eventos a essa unidade de execução com o método add_event.
Para saber mais sobre como o Snowflake representa os eventos de trace, consulte a documentação.
Event Table para Native Applications
Você pode usar a event table para coletar eventos de logging e dados de telemetria das suas native apps. Isso exige configuração adicional, já que o código da native app roda na conta do consumidor, que é onde os eventos são coletados. A configuração precisa ser feita dos dois lados — tanto na conta do provider quanto na do consumer.
Configuração do provider, resumida:
- Configure o nível de log e de evento no arquivo de manifesto
- Configure uma conta para armazenar os eventos
Configuração do consumer, resumida:
- Crie uma event table
- Revise os eventos na event table
- Habilite o logging e o compartilhamento dos eventos com o provider
Tanto o consumer quanto o provider têm acesso à event table e aos registros. Por isso, é importante que o consumer revise que tipo de informação está sendo registrada e compartilhada com o provider antes de habilitar o compartilhamento.
O Snowflake disponibiliza uma visão geral detalhada, com instruções passo a passo tanto para providers quanto para consumers. Para saber mais sobre toda a configuração, confira a documentação.
Alertas baseados em eventos
As event tables se combinam facilmente com Snowflake Alerts para automatizar notificações com base nos eventos registrados. Vamos criar um alerta que roda uma vez por hora e envia um e-mail sempre que houver um erro registrado.
CREATE OR REPLACE ALERT alert_logged_errors
WAREHOUSE = my_warehouse
SCHEDULE = '60 MINUTE'
IF (EXISTS (
SELECT *
FROM my_event_table
WHERE record:"severity_text"::VARCHAR == 'ERROR' and timestamp BETWEEN SNOWFLAKE.ALERT.LAST_SUCCESSFUL_SCHEDULED_TIME()
AND SNOWFLAKE.ALERT.SCHEDULED_TIME()
))
THEN CALL SYSTEM$SEND_EMAIL(...);
Limitações e pegadinhas das Event Tables
Existe um limite de tamanho para o payload de log e trace: ele não pode passar de 1 MB.
A event table aparece na view ACCOUNT_USAGE, junto com a lista de todas as tabelas da sua conta. Ela traz EVENT TABLE como valor na coluna TABLE_TYPE.
select *
from snowflake.account_usage.tables
where table_name = 'MY_EVENT_TABLE'
;
A event table não pode ser atualizada. Se você tentar rodar um update, vai receber o erro UPDATE statement's target must be a table. As operações suportadas em EVENT TABLES são:
- SHOW EVENT TABLE
- DESCRIBE EVENT TABLE
- DROP TABLE
- UNDROP TABLE
- TRUNCATE TABLE
- DELETE
- ALTER TABLE
Preços e cobrança das Event Tables
A coleta dos eventos de log é cobrada como recurso Serverless. O Snowflake usa recursos gerenciados pela própria plataforma para coletar os eventos, ou seja, eles não consomem seus virtual warehouses. Para conferir quanto foi cobrado por esse recurso, basta consultar a view EVENT_USAGE_HISTORY:
select
start_time,
end_time,
credits_used,
bytes_ingested
from snowflake.account_usage.EVENT_USAGE_HISTORY
order by start_time desc;
Tomáš Sobotík·Senior Data Engineer & Snowflake SME na Norlys
Tomas é um Snowflake Data SuperHero de longa data e referência geral em Snowflake. Tem mais de uma década de experiência no mundo dos dados, atuando como Snowflake data engineer, arquiteto e admin em diversos projetos de diferentes setores e tecnologias. É um membro ativo da comunidade, compartilhando seu conhecimento e inspirando outras pessoas. Também é instrutor da O'Reilly, conduzindo treinamentos ao vivo online.