Snowflake a récemment enrichi ses capacités d'alerting : les alertes peuvent désormais être envoyées par e-mail ou via Webhook. Les Webhooks sont particulièrement puissants, puisqu'ils permettent d'acheminer les alertes vers Slack, Microsoft Teams, PagerDuty, etc. C'est précieux pour de nombreux cas d'usage, notamment les alertes d'échec de pipeline ou les alertes pilotées par la donnée.
Cet article propose un guide pas à pas pour configurer les alertes Snowflake dans Slack. Nous détaillerons un exemple concret qui déclenche une alerte lorsque l'utilisation d'un warehouse augmente.
Étape 1 : créer un Webhook dans Slack
Connectez-vous à votre compte Slack, puis rendez-vous sur cette page.
Cliquez sur Create an App.
Sélectionnez From Scratch.
Sur l'écran suivant, nommez l'application, choisissez un workspace, puis cliquez sur Create App.
L'écran suivant affiche vos Application Credentials.
Cliquez sur Incoming Webhooks dans la barre latérale gauche :
Basculez Active Incoming Webhooks sur On.
Une fois l'option activée, descendez en bas de la page et cliquez sur Add New Webhook to Workspace.
Choisissez le canal qui recevra les alertes Snowflake. J'ai créé un nouveau canal appelé snowflake-alerts, puis j'ai actualisé la page pour le voir apparaître dans la liste déroulante.
Cliquez sur Allow.
Tester le Webhook
Une fois Allow validé, la page suivante affiche l'URL de votre Webhook ainsi qu'une commande CURL de test.
Copiez-collez la commande de test dans votre terminal. Sous Windows, passez par Git Bash.
Un message doit s'afficher instantanément dans votre nouveau canal Slack.
Bravo, votre Webhook est opérationnel !
En option : un avatar Snowflake ❄️ plus élégant pour l'application
- Revenez dans l'onglet Basic Information.
- Descendez en bas de page.
- Téléchargez un logo Snowflake et importez-le ici.
- Relancez un test.
Le rendu est nettement plus soigné !
Étape 2 : créer un Secret Snowflake
L'URL du Webhook contient un secret. Remplacez la chaîne ci-dessous par la vôtre, puis exécutez cette commande dans Snowflake.
Rappel : les secrets sont des objets de niveau schéma. Vérifiez le contexte de base et de schéma de votre worksheet, ou utilisez des noms pleinement qualifiés.
Pour ma part, j'ai créé un secret nommé gmds_slack_secret dans le schéma public de la base analytics.
use schmea analytics.public;
CREATE OR REPLACE SECRET gmds_slack_secret
TYPE = GENERIC_STRING
SECRET_STRING = 'T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX';
Étape 3 : créer une intégration de notification par webhook
Le secret étant créé, passons à 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');
Étape 4 : envoyer la notification
Pour envoyer une notification, on s'appuie sur la procédure stockée native SYSTEM$SEND_SNOWFLAKE_NOTIFICATION. Il faut transmettre la fonction SANITIZE_WEBHOOK_CONTENT à la procédure afin de retirer le placeholder (à savoir SNOWFLAKE_WEBHOOK_SECRET) du message.
Voici le code exécuté dans mon compte :
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 notification est arrivée dans Slack instantanément !
Les bases sont posées, place à un exemple concret.
Exemple d'alerte : notifier en cas de pic d'utilisation d'un warehouse
Écrire une requête SQL pour détecter les pics et l'encapsuler dans une tâche serverless
La requête suivante compare l'utilisation récente (la dernière heure complète) à l'utilisation horaire moyenne de chaque warehouse sur le mois écoulé. Ici, nous signalons les warehouses dont l'utilisation a augmenté de 50 %.
On opte pour une tâche serverless, plus économique ! Il suffit d'omettre le nom du warehouse pour que la tâche bascule en mode serverless.
Pour les besoins de l'exemple, j'ajoute via un UNION une ligne factice afin que chaque exécution de la tâche produise un enregistrement et déclenche une alerte.
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
Déplier le code
Créer une table pour stocker les résultats de la requête
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
);
Cette table comporte quelques colonnes utilitaires, dotées de valeurs par défaut, qui ne figurent pas dans les résultats de la requête :
- alert_id : clé primaire
- inserted_at : indique à quel moment la tâche a inséré l'enregistrement.
- alert_sent : à false par défaut, bascule à true une fois l'alerte envoyée.
Tester la tâche et examiner les résultats
execute task monitor_warehouse_spikes;
select * from usage_spike_alerts where not alert_sent;
Créer une procédure pour envoyer l'alerte en cas de pic
Voici ce que l'on cherche à faire :
- Vérifier dans la table
usage_spike_alertsla présence d'enregistrements non envoyés :alert_sent==false - S'il y en a, les pousser vers Slack.
- Marquer l'enregistrement comme envoyé.
- Afficher dans la console SQL le nombre d'alertes envoyées.
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
"""
Déplier le code
J'ai rencontré des difficultés pour envoyer des sauts de ligne \n vers Slack via la fonction SANITIZE_WEBHOOK_CONTENT. Slack attend une chaîne littérale avec une double barre oblique inverse \n ; une chaîne Python \\n devrait donc convenir. Pourtant, lorsque Python transmet ce littéral à la fonction SQL, un problème survient et l'alerte n'est pas envoyée. Je ne suis pas parvenu à obtenir des alertes Python avec sauts de ligne, alors que cela fonctionne en exécution manuelle : SANITIZE_WEBHOOK_CONTENT('line1\line2')
Tester la procédure manuellement
Une ligne de test a déjà été insérée dans la table spikes. Exécutons la procédure et vérifions que :
- Les enregistrements passent à
alert_sent==true - Le message arrive bien dans Slack
execute task monitor_warehouse_spikes; -- si ce n'est pas déjà fait...
select * from usage_spike_alerts where not alert_sent; -- vérifier : sent == false
CALL send_usage_spike_alerts(); -- envoyer l'alerte
-- attendre que l'alerte arrive
select * from usage_spike_alerts where not alert_sent; -- 0 ligne
Vous devriez avoir reçu une alerte dans Slack !
Enchaîner la tâche et la procédure
Nous voulons que la planification horaire de la tâche monitor_warehouse_spikes orchestre l'ensemble du processus de bout en bout ; assurons-nous qu'après l'exécution de monitor_warehouse_spikes, la procédure d'envoi de l'alerte s'exécute également.
D'abord, encapsulez la procédure dans une tâche serverless et activez-la :
CREATE TASK send_usage_spike_alerts_task
AS
CALL send_usage_spike_alerts();
alter task send_usage_spike_alerts_task resume;
Puis, enchaînez les tâches :
ALTER TASK send_usage_spike_alerts_task
ADD AFTER monitor_warehouse_spikes;
Testez :
1execute task monitor_warehouse_spikes;
La tâche doit désormais ajouter les nouveaux enregistrements à la table et envoyer la ou les alertes vers Slack !
Lorsqu'on appelle directement la procédure send_usage_spike_alerts(), le message s'affiche aussitôt dans Slack. En revanche, lorsque send_usage_spike_alerts_task est enchaînée à monitor_warehouse_spikes, l'alerte peut mettre jusqu'à 3 minutes à arriver.
Consulter le DAG et l'historique des tâches
Dans le menu latéral Data de l'interface Snowsight (icône de base de données dans la barre latérale), accédez à la base et au schéma qui contiennent vos tâches. Dépliez le conteneur Tasks et sélectionnez l'une des tâches que nous avons créées. Cliquez ensuite sur l'onglet Graph dans le cadre principal. Vous pouvez y déclencher la tâche manuellement.
Vous pouvez également consulter l'historique des exécutions dans l'onglet Run History :
Notes de conception
La détection des pics et l'envoi de l'alerte auraient pu tenir dans une seule tâche. On pourrait estimer qu'enchaîner deux tâches ajoute une complexité inutile. Je préfère néanmoins cette approche, pour les raisons suivantes.
- Les pics sont historisés dans une table de manière pérenne. Techniquement, ce n'est pas indispensable pour l'alerting, mais c'est vraiment appréciable.
- Journaliser les pics dans une table constitue une unité de travail à part entière, qui mérite sa propre tâche.
- En dissociant la logique de surveillance des pics de l'alerte elle-même, on peut faire évoluer la logique sans avoir à retester la fonction d'envoi d'alertes.
Pour conclure
Envoyer des alertes Snowflake vers Slack est redoutablement utile. Les cas d'usage de ce type d'alerting sont infinis !
Cet article vous a permis de maîtriser les éléments suivants :
- Créer un Webhook dans Slack.
- Créer un secret dans Snowflake.
- Créer une Webhook Integration dans Snowflake.
- Créer une tâche pour journaliser les pics d'utilisation des warehouses.
- Créer une procédure pour envoyer des alertes selon une condition. Ici, la présence de lignes dans une requête.
- Encapsuler une procédure dans une tâche.
- Enchaîner plusieurs tâches.
Hâte de découvrir les cas d'usage que vous imaginerez ! 🥂
Jeff est consultant Data & Analytics, fort de plus de 15 ans d'expérience dans l'automatisation de l'analyse et l'exploitation de la donnée pour piloter les processus métier. Côté technique, il est spécialisé sur Snowflake + dbt + Tableau. Côté secteurs, il a travaillé pour les services publics, les essais cliniques, l'édition, les biens de grande consommation et l'industrie manufacturière. N'hésitez pas à le contacter : [email protected].