Monitorare la propria data pipeline o applicazione è fondamentale in fase di sviluppo. Senza un sistema adeguato di logging e tracing è difficile garantire un funzionamento regolare. Servono alert in grado di fornire contesto in caso di anomalie e, quando emergono discrepanze, occorre risalire al problema attraverso la logica di trasformazione. Per il debugging è essenziale capire nel dettaglio il comportamento del codice: valori delle variabili, messaggi di output e risultati delle formule, registrati di norma in varie forme. Snowflake offre funzionalità native di logging e tracing basate su librerie standard di settore, facilmente accessibili agli sviluppatori. Vediamo come impostare logging e tracing degli eventi in Snowflake sfruttando queste funzionalità.
Cosa sono le Event Tables?
Le event tables sono state rilasciate in public preview a maggio 2023. Si tratta di un tipo speciale di tabella Snowflake che presenta diverse differenze rispetto alle tabelle standard:
- Set predefinito di colonne, non modificabile
- Utilizzate esclusivamente per tracciare dati di logging e tracing
- È possibile avere una sola event table attiva per account
I casi d'uso tipici sono la cattura di informazioni di logging dagli handler del codice utilizzati come stored procedure o UDF, oppure la raccolta di dati di tracing dalle native app.
Lavorare con le Event Tables
L'attivazione di una event table per il proprio account avviene in più passaggi, come mostrato nell'immagine seguente:
1. Creare la EVENT TABLE
Per prima cosa occorre creare una event table, tramite uno statement CREATE TABLE dedicato:
CREATE EVENT TABLE my_db.logging.my_event_table;
Non è necessario specificare le colonne della tabella, poiché contiene un elenco predefinito di colonne. Per ora è possibile avere una sola event table attiva per l'intero account.
2. Associare la Event Table all'account
Per rendere operativa la event table dobbiamo associarla al nostro account. L'operazione si effettua con lo statement ALTER ACCOUNT e, di conseguenza, può essere eseguita solo con il ruolo ACCOUNTADMIN. È inoltre necessario disporre dei privilegi OWNERSHIP o INSERT sulla event table.
ALTER ACCOUNT SET EVENT_TABLE = my_db.logging.my_event_table;
3. Iniziare a catturare gli eventi di log
A questo punto possiamo arricchire UDF, UDTF o stored procedure con il codice di logging. In base al linguaggio dell'handler, si possono utilizzare API e librerie di logging native.
| Linguaggio | Libreria di logging |
|---|---|
| Java | SLF4J API |
| JavaScript | Snowflake JavaScript API |
| Python | modulo logging |
| Scala | SLF4J API |
| Snowflake scripting | Funzione SYSTEM$LOG di Snowflake |
Prendiamo come esempio Python.
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
Per iniziare a fare logging bisogna importare il modulo logging e istanziare l'oggetto logger. Da quel momento si utilizza come in una qualsiasi applicazione Python standard, registrando log su livelli diversi quali INFO, WARNING o ERROR.
Vediamo un ulteriore esempio relativo allo scripting SQL e a come aggiungere il logging quando il codice dell'handler è scritto in SQL. Con Snowflake Scripting bisogna ricorrere alla funzione SYSTEM$LOG, che supporta anch'essa diversi livelli di log: info, warning o error.
Abbiamo una semplice stored procedure che restituisce una tabella. Se vogliamo arricchirla con messaggi di logging informativi, possiamo procedere così:
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. Interrogare la event table
Abbiamo aggiunto il logging nel codice dell'handler; ora vogliamo verificare gli eventi registrati. È il momento di interrogare la event table. Ogni messaggio registrato contiene:
- Timestamp – quando l'evento è stato registrato
- Scope – ad esempio il nome della classe in cui è stato generato l'evento di log
- Livello di severità del log – ad esempio info, warning, error
- Il messaggio di log vero e proprio
Per l'elenco completo delle colonne delle event tables, consulti la documentazione. Alcune colonne sono coppie chiave-valore che memorizzano più attributi e si possono estrarre con query simili a queste:
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;
Ed ecco come si presenta l'output della event table:
Usare i trace per registrare dati strutturati
Un altro caso d'uso delle event tables è la raccolta di dati di tracing dal codice. I trace data sono informazioni di logging strutturate sotto forma di coppie chiave-valore, capaci di offrire una panoramica più dettagliata del comportamento del codice rispetto ai normali log. Vediamo un esempio in cui iniziamo a raccogliere dati di tracing da una UDF scritta in 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;
Occorre importare lo snowflake-telemetry-package, che contiene i metodi necessari.
Con il metodo set_span_attribute possiamo impostare coppie chiave-valore sullo span object. Gli span object contengono i dati di telemetria generati al termine dell'esecuzione della funzione o della procedura e rappresentano l'unità di esecuzione della UDF o della stored procedure. A quell'unità di esecuzione si possono aggiungere più eventi tramite il metodo add_event.
Per approfondire come Snowflake rappresenta gli eventi di trace, faccia riferimento alla relativa documentazione.
Event Table per le Native Applications
È possibile utilizzare la event table per raccogliere eventi di logging e dati di telemetria nelle proprie native app. Serve una configurazione aggiuntiva, perché il codice della native app viene eseguito nel consumer account, dove vengono raccolti gli eventi. La configurazione va effettuata su entrambi i lati: provider e consumer.
Setup del provider in sintesi:
- Configurare i livelli di log ed event nel file manifest
- Configurare un account in cui memorizzare gli eventi
Setup del consumer in sintesi:
- Creare una event table
- Esaminare gli eventi presenti nella event table
- Abilitare il logging e la condivisione degli eventi con il provider
Sia il consumer sia il provider hanno accesso alla event table e alle voci registrate. È quindi importante che il consumer valuti con attenzione quali informazioni vengono registrate e condivise con il provider prima di abilitare la funzionalità.
Snowflake mette a disposizione una panoramica dettagliata con istruzioni passo passo sia per i provider sia per i consumer. Per approfondire la configurazione complessiva, consulti la documentazione.
Alert basati sugli eventi
Le event tables si combinano facilmente con gli Snowflake Alerts per automatizzare le notifiche sulla base degli eventi registrati. Proviamo a creare un alert che venga eseguito una volta all'ora e che, in presenza di un errore registrato, invii un'email.
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(...);
Limiti e accortezze delle Event Tables
Esiste un limite alla dimensione del payload di log e trace: non può superare 1 MB.
La event table compare nella vista ACCOUNT_USAGE insieme all'elenco di tutte le tabelle dell'account, con valore EVENT TABLE nella colonna TABLE_TYPE.
select *
from snowflake.account_usage.tables
where table_name = 'MY_EVENT_TABLE'
;
La event table non può essere aggiornata. Se si prova a eseguire uno statement di update, si ottiene un errore che indica che UPDATE statement's target must be a table. Le operazioni supportate sulle EVENT TABLES sono:
- SHOW EVENT TABLE
- DESCRIBE EVENT TABLE
- DROP TABLE
- UNDROP TABLE
- TRUNCATE TABLE
- DELETE
- ALTER TABLE
Pricing e fatturazione delle Event Tables
La raccolta degli eventi di log è fatturata come funzionalità Serverless. Snowflake utilizza risorse gestite direttamente da Snowflake per raccogliere gli eventi, quindi non è necessario impiegare uno dei propri virtual warehouse. Per verificare quanto le è stato addebitato per questa funzionalità, può interrogare la vista 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 presso Norlys
Tomas è da tempo Snowflake Data SuperHero e riconosciuto esperto della piattaforma Snowflake. Vanta oltre un decennio di esperienza nel mondo dei dati, durante il quale ha ricoperto i ruoli di data engineer, architect e admin Snowflake in numerosi progetti, in settori e tecnologie eterogenei. Tomas è un membro attivo della community, dove condivide costantemente le proprie competenze ispirando gli altri. È inoltre instructor O'Reilly e tiene sessioni di formazione live online.