Hacerle seguimiento a tu pipeline de datos o a tu aplicación es clave durante el desarrollo. Sin un logging y un tracing adecuados, mantener una operación estable se complica. Hacen falta alertas que aporten contexto cuando algo falla. Si aparecen discrepancias, tienes que rastrear el problema a través de la lógica de transformación. Y para depurar, es fundamental tener visibilidad sobre cómo se comporta el código. Por ejemplo, necesitas información de contexto como valores de variables, mensajes de salida y resultados de fórmulas, que normalmente se registran de distintas maneras. Snowflake ofrece funcionalidades nativas de logging y tracing apoyadas en librerías estándar de la industria, lo que las vuelve muy accesibles para los desarrolladores. Veamos cómo configurar el logging y el tracing de eventos en Snowflake usando estas funcionalidades.
¿Qué son las Event Tables?
Las event tables se lanzaron en public preview en mayo de 2023. Son un tipo especial de tabla de Snowflake con varias diferencias respecto a las tablas estándar:
- Tienen un conjunto predefinido de columnas que no se puede modificar
- Se usan únicamente para almacenar datos de logging y tracing
- Solo puedes tener una event table activa asociada a la cuenta
Los casos de uso típicos son capturar información de logging desde tus handlers de código en stored procedures o UDFs, o recopilar datos de tracing desde apps nativas.
Cómo trabajar con Event Tables
Habilitar una event table en tu cuenta se hace en varios pasos, como muestra la siguiente imagen:
1. Crear la EVENT TABLE
Lo primero es crear la event table. Esto se hace con una sentencia CREATE TABLE especial:
CREATE EVENT TABLE my_db.logging.my_event_table;
No hace falta especificar las columnas, porque la tabla ya trae una lista predefinida. Por ahora solo puedes tener una event table activa por cuenta.
2. Asignar la Event Table a la cuenta
Para empezar a usar la event table hay que asociarla a la cuenta. Se hace con la sentencia ALTER ACCOUNT, así que solo se puede ejecutar con el rol ACCOUNTADMIN. Además, se requieren privilegios de OWNERSHIP o INSERT sobre la event table.
ALTER ACCOUNT SET EVENT_TABLE = my_db.logging.my_event_table;
3. Empezar a capturar los eventos de log
Ahora podemos enriquecer la UDF/UDTF o el stored procedure con código de logging. Según el lenguaje del handler, puedes usar APIs y librerías de logging nativas.
| Lenguaje | Librería de logging |
|---|---|
| Java | SLF4J API |
| JavaScript | Snowflake JavaScript API |
| Python | módulo logging |
| Scala | SLF4J API |
| Snowflake scripting | función SYSTEM$LOG de Snowflake |
Tomemos Python como ejemplo.
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 empezar a hacer logging hay que importar el módulo logging e instanciar el objeto logger. Después se usa igual que en cualquier app estándar de Python, registrando distintos niveles como INFO, WARNING o ERROR.
Veamos otro ejemplo con SQL scripting y cómo añadir logging cuando el código del handler está en SQL. En el caso de Snowflake Scripting hay que usar la función SYSTEM$LOG. También admite distintos niveles de mensajes como info, warning o error.
Tenemos un stored procedure sencillo que devuelve una tabla. Si queremos enriquecerlo con mensajes de log informativos, podemos hacer lo siguiente:
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. Consultar la event table
Ya agregamos el logging en el código del handler; ahora toca revisar los eventos registrados. Es el momento de consultar la event table. Cada mensaje registrado contiene:
- Timestamp: cuándo se registró el evento
- Scope: por ejemplo, el nombre de la clase donde se creó el evento de log
- Nivel de severidad del log: por ejemplo, info, warning, error
- El mensaje de log en sí
Para ver la lista completa de columnas de la event table, consulta la documentación. Algunas columnas son pares clave-valor para almacenar múltiples atributos. Puedes extraerlos con consultas similares:
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;
Y así se ve la salida de la event table:
Usar traces para registrar datos estructurados
Otro caso de uso de las event tables es recopilar datos de trace desde tu código. Los datos de trace son información de logging estructurada en forma de pares clave-valor, que suele ofrecer una visión mucho más detallada del comportamiento del código que los datos de log. Veamos un ejemplo en el que empezaremos a recopilar datos de trace desde una UDF escrita en 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;
Hay que importar el paquete snowflake-telemetry-package, que contiene los métodos necesarios.
Podemos usar el método set_span_attribute para definir pares clave-valor en el objeto span. Los objetos span almacenan los datos de telemetría que se generan cuando la función o el procedimiento se ejecuta correctamente. Representan la unidad de ejecución de la UDF o del stored procedure. Puedes añadir varios eventos a esa unidad de ejecución con el método add_event.
Si quieres profundizar en cómo Snowflake representa los eventos de trace, consulta su documentación.
Event Table para aplicaciones nativas
Puedes usar la event table para recopilar eventos de logging y datos de telemetría en tus apps nativas. Esto requiere configuración adicional, ya que el código de la app nativa se ejecuta en la cuenta del consumidor, que es donde se recopilan los eventos. Hay que configurar ambos lados: la cuenta del proveedor y la del consumidor.
Configuración del proveedor, en resumen:
- Configurar el nivel de log y de evento en el archivo manifest
- Configurar una cuenta para almacenar los eventos
Configuración del consumidor, en resumen:
- Crear una event table
- Revisar los eventos en la event table
- Habilitar el logging y compartir los eventos con el proveedor
Tanto el consumidor como el proveedor tienen acceso a la event table y a los registros. Por eso es importante que el consumidor revise qué información se registra y se comparte con el proveedor antes de habilitarlo.
Snowflake ofrece una guía detallada con instrucciones paso a paso para proveedores y consumidores. Si quieres conocer la configuración completa, revisa la documentación.
Alertas basadas en eventos
Las event tables se pueden combinar fácilmente con Snowflake Alerts para automatizar notificaciones a partir de los eventos registrados. Vamos a crear una alerta que se ejecute una vez por hora y que, si detecta un error registrado, envíe 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(...);
Limitaciones y detalles a tener en cuenta
Existe un límite para el tamaño del payload de log y trace: no puede superar 1 MB.
La event table aparece en la vista ACCOUNT_USAGE junto con todas las tablas de tu cuenta. Lleva EVENT TABLE como valor en la columna TABLE_TYPE.
select *
from snowflake.account_usage.tables
where table_name = 'MY_EVENT_TABLE'
;
La event table no se puede actualizar. Si intentas ejecutar una sentencia UPDATE, obtendrás un error que indica que UPDATE statement's target must be a table. Las operaciones admitidas en EVENT TABLES son:
- SHOW EVENT TABLE
- DESCRIBE EVENT TABLE
- DROP TABLE
- UNDROP TABLE
- TRUNCATE TABLE
- DELETE
- ALTER TABLE
Precios y facturación de Event Table
La recolección de eventos de log se factura como una funcionalidad Serverless. Snowflake usa recursos gestionados por Snowflake para recopilar los eventos, así que no consumen tus virtual warehouses. Si quieres revisar cuánto te han cobrado por esta funcionalidad, puedes consultar 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 en Norlys
Tomas es Snowflake Data SuperHero desde hace años y un referente en todo lo relacionado con Snowflake. Su trayectoria en el mundo de los datos supera la década, durante la cual ha ejercido como data engineer, arquitecto y admin de Snowflake en proyectos de distintas industrias y tecnologías. Es un miembro activo de la comunidad, comparte su experiencia constantemente e inspira a otros. También es instructor en O'Reilly, donde imparte sesiones de formación online en vivo.