SELECTSELECT

SELECT

Event Tables : logging et tracing structurés dans Snowflake

By Tomáš SobotíkMay 19, 20246 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

Suivre un pipeline de données ou une application est essentiel pendant la phase de développement. Sans logging ni tracing adaptés, difficile d'en garantir le bon fonctionnement. Les alertes doivent apporter du contexte lorsqu'un incident survient, et lorsque des écarts apparaissent, il faut pouvoir remonter le problème à travers la logique de transformation. Pour le débogage, comprendre le comportement de son code est crucial : valeurs des variables, messages de sortie, résultats de formules — autant d'informations à journaliser sous différentes formes. Snowflake propose des fonctionnalités natives de logging et de tracing qui s'appuient sur des bibliothèques standards du marché, accessibles à tous les développeurs. Voyons comment mettre en place le logging et le tracing d'événements dans Snowflake grâce à ces fonctionnalités.

Que sont les event tables ?

Les event tables sont passées en public preview en mai 2023. Il s'agit d'un type particulier de table Snowflake qui se distingue des tables standards sur plusieurs points :

  • Un ensemble prédéfini de colonnes, non modifiable
  • Un usage strictement réservé au suivi des données de logging et de tracing
  • Une seule event table active possible par compte

Les cas d'usage typiques consistent à capturer les informations de logging issues des handlers de votre code (procédures stockées, UDFs) ou à collecter des données de tracing depuis des applications natives.

Travailler avec les event tables

L'activation d'une event table sur votre compte se fait en plusieurs étapes, comme illustré ci-dessous :

1. Créer l'EVENT TABLE

Première étape : créer une event table. Cela passe par une instruction CREATE TABLE spécifique :

CREATE EVENT TABLE my_db.logging.my_event_table;

Inutile de préciser les colonnes : elles sont prédéfinies. Pour l'instant, une seule event table active est possible pour l'ensemble du compte.

2. Associer l'event table au compte

Pour qu'elle soit effective, il faut l'associer au compte via une instruction ALTER ACCOUNT. Cela nécessite donc le rôle ACCOUNTADMIN, ainsi que les privilèges OWNERSHIP ou INSERT sur l'event table.

ALTER ACCOUNT SET EVENT_TABLE = my_db.logging.my_event_table;

3. Capturer les événements de log

Vous pouvez maintenant enrichir vos UDF, UDTF ou procédures stockées avec du code de logging. Selon le langage de votre handler, plusieurs APIs et bibliothèques natives sont disponibles.

Langage Bibliothèque de logging
Java SLF4J API
JavaScript Snowflake JavaScript API
Python module logging
Scala SLF4J API
Snowflake scripting fonction Snowflake SYSTEM$LOG

Prenons Python comme exemple.

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

Pour démarrer le logging, on importe le module logging et on instancie un objet logger. On l'utilise ensuite comme dans n'importe quelle application Python standard, avec différents niveaux de log : INFO, WARNING ou ERROR.

Autre exemple avec du SQL scripting : si votre handler est écrit en SQL, il faut passer par la fonction SYSTEM$LOG. Elle prend également en charge plusieurs niveaux de message : info, warning ou error.

Voici une procédure stockée simple qui retourne une table. Pour l'enrichir avec des messages de log d'information :

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. Interroger l'event table

Le logging est en place dans le handler ; reste à consulter les événements enregistrés. C'est le moment d'interroger l'event table. Chaque message journalisé contient :

  • Timestamp — moment où l'événement a été journalisé
  • Scope — par exemple le nom de la classe où l'événement a été créé
  • Niveau de sévérité — info, warning, error, etc.
  • Le message de log lui-même

Pour la liste complète des colonnes d'une event table, consultez la documentation. Certaines colonnes sont des paires clé-valeur permettant de stocker plusieurs attributs. Vous pouvez les extraire avec des requêtes similaires :

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;

Et voici à quoi ressemble la sortie de l'event table :

Utiliser les traces pour journaliser des données structurées

Autre cas d'usage des event tables : la collecte de données de tracing depuis votre code. Ces données prennent la forme d'informations de logging structurées en paires clé-valeur, ce qui offre une vue bien plus détaillée du comportement du code que les logs classiques. Voici un exemple de collecte de données de tracing depuis une UDF 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;

Il faut importer le package snowflake-telemetry-package, qui contient les méthodes nécessaires.

La méthode set_span_attribute permet de définir des paires clé-valeur sur un objet span. Les spans contiennent les données de télémétrie générées après l'exécution réussie d'une fonction ou d'une procédure. Un span représente l'unité d'exécution d'une UDF ou d'une procédure stockée. Vous pouvez y ajouter plusieurs événements via la méthode add_event.

Pour en savoir plus sur la manière dont Snowflake représente les événements de tracing, consultez la documentation.

Event Tables pour les applications natives

Vous pouvez utiliser les event tables pour collecter les événements de logging et les données de télémétrie de vos applications natives. Cela demande une configuration supplémentaire, car le code d'une application native s'exécute dans le compte consumer, où les événements sont collectés. La configuration s'effectue des deux côtés : compte provider et compte consumer.

Configuration côté provider, en bref :

  1. Configurer les niveaux de log et d'événement dans le fichier manifest
  2. Configurer un compte de stockage des événements

Configuration côté consumer, en bref :

  1. Créer une event table
  2. Consulter les événements dans l'event table
  3. Activer le logging et le partage des événements avec le provider

Provider et consumer ont tous deux accès à l'event table et aux entrées journalisées. Il est donc essentiel que le consumer vérifie au préalable quelles informations sont journalisées et partagées avec le provider avant d'activer cette option.

Snowflake fournit une vue d'ensemble détaillée avec des instructions pas à pas, à la fois pour les providers et pour les consumers. Pour en savoir plus sur la configuration globale, consultez la documentation.

Alertes basées sur les événements

Les event tables se combinent facilement avec les Snowflake Alerts pour automatiser des notifications à partir des événements journalisés. Créons par exemple une alerte qui s'exécute toutes les heures et qui envoie un e-mail dès qu'une erreur apparaît dans les logs.

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(...);

Limites et points de vigilance des event tables

La taille du payload de log et de trace est limitée : elle ne peut pas dépasser 1 Mo.

L'event table apparaît dans la vue ACCOUNT_USAGE, qui liste toutes les tables de votre compte. La colonne TABLE_TYPE prend alors la valeur EVENT TABLE.

select *
from snowflake.account_usage.tables
where table_name = 'MY_EVENT_TABLE'
;

Une event table ne peut pas être mise à jour. Si vous tentez un UPDATE, vous obtiendrez l'erreur UPDATE statement's target must be a table. Les opérations prises en charge sur les EVENT TABLES sont :

  • SHOW EVENT TABLE
  • DESCRIBE EVENT TABLE
  • DROP TABLE
  • UNDROP TABLE
  • TRUNCATE TABLE
  • DELETE
  • ALTER TABLE

Tarification et facturation des event tables

La collecte des événements de log est facturée comme une fonctionnalité Serverless. Snowflake mobilise ses propres ressources managées pour collecter les événements : aucun de vos virtual warehouses n'est sollicité. Pour vérifier le montant facturé au titre de cette fonctionnalité, interrogez la vue 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 chez Norlys

Tomas est Snowflake Data SuperHero de longue date et un expert reconnu de Snowflake. Fort de plus d'une décennie d'expérience dans le monde de la data, il est intervenu comme data engineer, architecte et administrateur Snowflake sur de nombreux projets, dans des secteurs et avec des technologies très variés. Membre actif de la communauté, il partage son expertise au quotidien et inspire ses pairs. Il est également formateur O'Reilly et anime des sessions de formation en ligne en direct.