Journalisation des messages en Scala

Vous pouvez enregistrer des messages provenant d’une fonction ou d’un gestionnaire de procédure écrit en Scala en utilisant l”API SLF4J. Lorsque vous avez mis en place une table d’événements pour stocker les entrées de journal, Snowflake stocke les entrées de journal générées par votre code de gestionnaire dans la table.

Vous pouvez utiliser l”API SLF4J incluse dans la bibliothèque de télémétrie Snowflake incluse dans Snowflake. Pour ce faire, incluez la valeur suivante dans la clause PACKAGES lorsque vous créez la fonction ou la procédure : com.snowflake:telemetry:latest.

Pour plus d’informations sur l’inclusion de la bibliothèque de télémétrie lors de l’empaquetage de votre code avec Maven, voir Configuration de votre environnement Java et Scala pour l’utilisation de la classe de télémétrie.

Note

L’utilisation de la bibliothèque de télémétrie Snowflake ajoute d’autres bibliothèques à l’environnement d’exécution de votre fonction ou procédure. Pour plus d’informations, voir Dépendances du paquet de télémétrie Snowflake.

Note

SLF4J ne prend pas en charge les messages de journalisation au niveau FATAL. Pour les gestionnaires écrits en Java ou Scala, le niveau FATAL est traité comme le niveau ERROR.

Par exemple, si vous définissez le paramètre LOG_LEVEL sur FATAL, les messages de niveau ERROR provenant d’un gestionnaire Java ou Scala sont pris en compte.

Pour des informations générales sur la configuration de la journalisation et la récupération des messages dans Snowflake, voir Enregistrement de messages à partir de fonctions et de procédures.

Avant de journaliser à partir d’un code, vous devez :

Ajout d’attributs personnalisés

Lorsque vous créez une entrée de journal, vous pouvez ajouter vos propres attributs dans des paires clé-valeur. Snowflake enregistre ces attributs personnalisés dans la colonne RECORD_ATTRIBUTES de la table des événements.

Pour ajouter des attributs personnalisés, appelez les méthodes de l’API slf4j fluent, telles que Logger.atInfo et Logger.atError. Utilisez ces méthodes pour définir des paires clé-valeur dans l’entrée de journal. Chacune renvoie un org.slf4j.spi.LoggingEventBuilder, que vous pouvez utiliser pour définir le message du journal.

Le code de l’exemple suivant enregistre un message « Logging with attributes » dans la colonne VALUE de la table des événements. Il ajoute également un attribut personnalisé à la colonne RECORD_ATTRIBUTES.

CREATE OR REPLACE PROCEDURE do_logging_scala()
RETURNS VARCHAR
LANGUAGE SCALA
RUNTIME_VERSION = '2.12'
PACKAGES=('com.snowflake:telemetry:latest', 'com.snowflake:snowpark:latest')
HANDLER = 'ScalaLoggingHandler.doThings'
AS
$$
  import org.slf4j.Logger
  import org.slf4j.LoggerFactory
  import com.snowflake.snowpark.Session

  class ScalaLoggingHandler {
    private val logger: Logger = LoggerFactory.getLogger(getClass)

    def doThings(session: Session): String = {
      logger.atInfo().addKeyValue("custom1", "value1").setMessage("Logging with attributes").log();
      return "SUCCESS"
    }
  }
$$;
Copy

La sortie de cet appel Logger.atInfo apparaît dans la table des événements comme suit. Notez que la colonne RECORD_ATTRIBUTES comprendra les attributs que Snowflake ajoute automatiquement.

------------------------------------------------------------------
| VALUE                     | RECORD_ATTRIBUTES                  |
------------------------------------------------------------------
| "Logging with attributes" | {                                  |
|                           |   "custom1": "value1",             |
|                           |   "thread.name": "Thread-5"        |
|                           | }                                  |
------------------------------------------------------------------

Exemple en Scala

Le code de l’exemple suivant fait référence à la bibliothèque de télémétrie Snowflake et obtient un enregistreur à partir de celle-ci. Il enregistre un message au niveau INFO. Il enregistre également une erreur en cas d’exception.

Pour plus d’informations sur les méthodes que vous pouvez utiliser pour enregistrer à des niveaux spécifiques, reportez-vous aux méthodes SLF4J.

CREATE OR REPLACE PROCEDURE do_logging()
RETURNS VARCHAR
LANGUAGE SCALA
RUNTIME_VERSION = '2.12'
PACKAGES=('com.snowflake:snowpark:latest', 'com.snowflake:telemetry:latest')
HANDLER = 'ScalaLoggingHandler.doThings'
AS
$$
  import org.slf4j.Logger
  import org.slf4j.LoggerFactory
  import com.snowflake.snowpark.Session

  class ScalaLoggingHandler {
    private val logger: Logger = LoggerFactory.getLogger(getClass)

    logger.info("Logging from within the Scala constructor.")

    def doThings(session: Session): String = {
      logger.info("Logging from Scala method start.")

      try {
        throwException
      } catch {
        case e: Exception => logger.error("Logging an error from Scala handler: " + e.getMessage())
        return "ERROR"
      }
      return "SUCCESS"
    }

    // Simulate a thrown exception to catch.
    @throws(classOf[Exception])
    private def throwException = {
      throw new Exception("Something went wrong.")
    }
  }
$$
;
Copy

Vous pouvez accéder aux messages du journal en exécutant une commande SELECT sur la table d’événements. Pour plus d’informations, voir Affichage des messages de journalisation.

Le code de l’exemple suivant interroge la table d’événements dans laquelle sont stockés les messages du journal. La requête indique la gravité et le message de chaque entrée de journal de la classe du gestionnaire.

SET event_table_name='my_db.public.my_event_table';

SELECT
  RECORD['severity_text'] AS SEVERITY,
  VALUE AS MESSAGE
FROM
  IDENTIFIER($event_table_name)
WHERE
  SCOPE['name'] = 'ScalaLoggingHandler'
  AND RECORD_TYPE = 'LOG';
Copy

L’exemple précédent génère la sortie suivante.

---------------------------------------------------------------------------
| SEVERITY | MESSAGE                                                      |
---------------------------------------------------------------------------
| "INFO"   | "Logging from within the Scala constructor."                 |
---------------------------------------------------------------------------
| "INFO"   | "Logging from Scala method start."                           |
---------------------------------------------------------------------------
| "ERROR"  | "Logging an error from Scala handler: Something went wrong." |
---------------------------------------------------------------------------