Snowflake amplió hace poco sus funciones de alertas y ahora permite enviarlas por correo electrónico o Webhook. Las alertas por Webhook son muy potentes, porque abren la puerta a integrarlas con Slack, Microsoft Teams, Pager Duty y más. Resultan útiles en muchos escenarios, como avisos de fallas en pipelines o alertas basadas en datos.
En este post vas a encontrar una guía paso a paso para configurar alertas de Snowflake en Slack. Repasaremos un ejemplo detallado que dispara una alerta cuando aumenta el uso de un warehouse.
Paso 1: crea un Webhook en Slack
Inicia sesión en tu cuenta de Slack y entra a esta página.
Haz clic en Create an App.
Selecciona "From Scratch".
En la siguiente pantalla, ponle nombre a la app, elige un workspace y haz clic en Create App.
La pantalla que sigue te mostrará las credenciales de la aplicación.
Haz clic en Incoming Webhooks, en la barra lateral izquierda:
Pon "Active Incoming Webhooks" en "On".
Una vez activado, desplázate hasta el final de la página y haz clic en "Add New Webhook to Workspace".
Elige a qué canal quieres que lleguen las alertas de Snowflake. Yo creé un canal nuevo llamado "snowflake-alerts" y recargué la página para que apareciera en el desplegable.
Haz clic en Allow.
Prueba el Webhook
Después de hacer clic en Allow, la siguiente pantalla te entregará tu Webhook URL y un comando CURL de prueba.
Copia el comando de prueba y pégalo en tu terminal. Si estás en Windows, usa Git Bash.
Al instante debería llegar un mensaje a tu nuevo canal de Slack.
¡Listo, tu nuevo Webhook ya funciona!
Opcional: dale a la app un avatar más vistoso de Snowflake ❄️
- Vuelve a la pestaña "Basic Information".
- Desplázate hasta el final.
- Descarga un logo de Snowflake y súbelo ahí.
- Vuelve a probar.
¡Ahora se ve mucho mejor!
Paso 2: crea un Secret en Snowflake
La Webhook URL incluye un secret. Reemplaza la cadena del secret de abajo por la tuya y ejecuta este comando en Snowflake.
Recuerda: los secrets son objetos a nivel de schema. Cuida el contexto de base de datos y schema de tu worksheet, o usa nombres totalmente calificados.
En mi caso, creé un secret llamado gmds_slack_secret en el schema public de la base de datos analytics.
use schmea analytics.public;
CREATE OR REPLACE SECRET gmds_slack_secret
TYPE = GENERIC_STRING
SECRET_STRING = 'T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX';
Paso 3: crea una integración de notificación por Webhook
Con el secret ya creado, pasemos a la Notification Integration:
CREATE OR REPLACE NOTIFICATION INTEGRATION gmds_slack_webhook_integration
TYPE=WEBHOOK
ENABLED=TRUE
WEBHOOK_URL='https://hooks.slack.com/services/SNOWFLAKE_WEBHOOK_SECRET'
WEBHOOK_SECRET=analytics.public.gmds_slack_secret
WEBHOOK_BODY_TEMPLATE='{"text": "SNOWFLAKE_WEBHOOK_MESSAGE"}'
WEBHOOK_HEADERS=('Content-Type'='application/json');
Paso 4: envía la notificación
Para enviar una notificación se usa el stored procedure integrado SYSTEM$SEND_SNOWFLAKE_NOTIFICATION. Hay que pasarle la función SANITIZE_WEBHOOK_CONTENT al procedimiento para quitar el placeholder (por ejemplo, SNOWFLAKE_WEBHOOK_SECRET) del mensaje.
Este es el código que corrí en mi cuenta:
CREATE OR REPLACE NOTIFICATION INTEGRATION gmds_slack_webhook_integration
TYPE=WEBHOOK
ENABLED=TRUE
WEBHOOK_URL='https://hooks.slack.com/services/SNOWFLAKE_WEBHOOK_SECRET'
WEBHOOK_SECRET=analytics.public.gmds_slack_secret
WEBHOOK_BODY_TEMPLATE='{"text": "SNOWFLAKE_WEBHOOK_MESSAGE"}'
WEBHOOK_HEADERS=('Content-Type'='application/json');
¡La notificación llegó a Slack al instante!
Ya tenemos los engranajes básicos en su lugar; vamos a un ejemplo del mundo real.
Ejemplo de alertas: avisar cuando se dispara el uso de un warehouse
Arma una consulta SQL para detectar picos de uso del warehouse y envuélvela en una task serverless
La siguiente consulta compara el uso reciente (la última hora completa) con el promedio horario de uso de cada warehouse durante el último mes. En este caso, marcamos los warehouses cuyo uso aumentó un 50%.
Usamos una task serverless porque nos sale más barato. Basta con omitir el nombre del warehouse para que la task se vuelva serverless.
A modo de ejemplo, voy a hacer un UNION con un registro ficticio para garantizar que cada ejecución de la task genere una fila y una alerta.
CREATE OR REPLACE TASK monitor_warehouse_spikes
SCHEDULE = 'USING CRON 2 * * * * America/New_York'
SERVERLESS_TASK_MIN_STATEMENT_SIZE = 'XSMALL'
SERVERLESS_TASK_MAX_STATEMENT_SIZE = 'XSMALL'
as
insert into usage_spike_alerts (warehouse_name,last_hour_credits,avg_monthly_credits,credit_diff,percent_increase)
WITH last_hour_usage AS (
SELECT
warehouse_name,
sum(credits_used) AS last_hour_credits
FROM
snowflake.account_usage.warehouse_metering_history
WHERE
start_time >= DATEADD(hour, -2, CURRENT_TIMESTAMP)
AND end_time <= CURRENT_TIMESTAMP
Expandir código
Crea una tabla para guardar los resultados de la consulta
CREATE or replace TABLE usage_spike_alerts (
alert_id INT AUTOINCREMENT PRIMARY KEY,
warehouse_name STRING NOT NULL,
last_hour_credits FLOAT NOT NULL,
avg_monthly_credits FLOAT NOT NULL,
credit_diff FLOAT NOT NULL,
percent_increase FLOAT NOT NULL,
inserted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
alert_sent boolean default false
);
Ten en cuenta que esta tabla incluye un par de columnas auxiliares con valores por defecto que no salen de la consulta:
- alert_id: clave primaria.
- inserted_at: nos indica cuándo insertó el registro la task.
- alert_sent: arranca en false y pasa a true cuando se envía la alerta.
Prueba la task y revisa los resultados
execute task monitor_warehouse_spikes;
select * from usage_spike_alerts where not alert_sent;
Crea un procedimiento para enviar la alerta cuando aparezca un pico
Queremos hacer lo siguiente:
- Revisar la tabla
usage_spike_alertsen busca de registros sin enviar:alert_sent==false. - Si hay registros pendientes, mandarlos a Slack.
- Marcar el registro como enviado.
- Mostrar la cantidad de alertas enviadas en la consola SQL.
CREATE OR REPLACE PROCEDURE send_usage_spike_alerts()
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'send_alerts'
AS $$
import snowflake.snowpark as snowpark
def send_alerts(session):
query = """
SELECT warehouse_name, last_hour_credits, avg_monthly_credits, credit_diff, percent_increase
FROM usage_spike_alerts
WHERE alert_sent = FALSE
"""
Expandir código
Me topé con problemas al enviar saltos de línea \n a Slack mediante la función SANITIZE_WEBHOOK_CONTENT. Slack pide un string literal con doble backslash \n, así que un string de Python como \\n debería bastar. Pero cuando Python le pasa ese literal a la función SQL, algo se rompe y la alerta no llega. No conseguí que las alertas con saltos de línea funcionaran desde Python, aunque manualmente sí funciona: SANITIZE_WEBHOOK_CONTENT('line1\line2').
Prueba el procedimiento manualmente
Ya insertamos una fila de prueba en la tabla de "spikes". Corramos el sproc y comprobemos:
- Que los registros pasen a
alert_sent==true. - Que llegue el mensaje a Slack.
execute task monitor_warehouse_spikes; -- si aún no lo hiciste...
select * from usage_spike_alerts where not alert_sent; -- revísalo: sent == false
CALL send_usage_spike_alerts(); -- envía la alerta
-- espera a que llegue
select * from usage_spike_alerts where not alert_sent; -- 0 filas
¡Tendrías que haber recibido una alerta en Slack!
Encadena la task y el procedimiento
Queremos que el calendario horario de la task monitor_warehouse_spikes se encargue del flujo de punta a punta; vamos a asegurar que, después de ejecutarse monitor_warehouse_spikes, también corra el procedimiento que envía la alerta.
Primero, envuelve el procedimiento en una task serverless y actívala:
CREATE TASK send_usage_spike_alerts_task
AS
CALL send_usage_spike_alerts();
alter task send_usage_spike_alerts_task resume;
Luego, encadena las tasks:
ALTER TASK send_usage_spike_alerts_task
ADD AFTER monitor_warehouse_spikes;
Pruébalo:
1execute task monitor_warehouse_spikes;
¡Esta task debería sumar los nuevos registros a la tabla y disparar la o las alertas a Slack!
Cuando llamas directamente al procedimiento send_usage_spike_alerts(), el mensaje aparece en Slack al toque. Cuando encadenamos send_usage_spike_alerts_task a la task monitor_warehouse_spikes, la alerta puede tardar hasta 3 minutos en llegar.
Revisa el DAG y el historial de la task
Desde el menú lateral Data de la interfaz de Snowsight (el icono de base de datos en la barra lateral), navega hasta la base de datos y el schema donde están tus tasks. Expande el contenedor de tasks y selecciona cualquiera de las dos que creamos. Luego haz clic en la pestaña "Graph" del panel principal. Desde ahí puedes ejecutar la task manualmente.
También puedes consultar el historial de ejecuciones en la pestaña "Run History":
Notas de diseño
La consulta para detectar picos y el envío de la alerta podrían haberse resuelto en una sola task. Alguien podría decir que encadenar dos tasks agrega complejidad innecesaria. Aun así, prefiero este diseño por estos motivos:
- Los picos quedan registrados en una tabla para siempre. En estricto rigor no hace falta para alertar, pero es muy útil tenerlo.
- Registrar los picos en una tabla es una unidad de trabajo independiente y merece su propia task.
- Al separar la lógica de monitoreo de picos del envío de la alerta, podemos cambiar esa lógica sin tener que volver a probar el envío.
Cierre
Enviar alertas de Snowflake a Slack es tremendamente útil. ¡Los casos de uso para este tipo de alertas no tienen fin!
Con este artículo ya sabes:
- Crear un Webhook en Slack.
- Crear un Secret en Snowflake.
- Crear una integración de Webhook en Snowflake.
- Crear una task que registre los picos de uso de los warehouses.
- Crear un procedimiento que envíe alertas según una condición. En este caso, la presencia de filas en una consulta.
- Envolver un procedimiento en una task.
- Encadenar tasks entre sí.
¡Tengo muchas ganas de conocer los casos de uso que se te ocurran! 🥂
Jeff es Consultor de Data y Analytics con más de 15 años de experiencia automatizando insights y aprovechando los datos para gobernar procesos de negocio. En lo tecnológico se especializa en Snowflake + dbt + Tableau. En cuanto a industrias, tiene experiencia en Servicios Públicos, Ensayos Clínicos, Publishing, CPG y Manufactura. Escríbele cuando quieras a [email protected].