Journalisation des messages en Python¶
Vous pouvez enregistrer les messages dâune fonction ou dâun gestionnaire de procĂ©dure Ă©crit en Python en utilisant la journalisation, le module de journalisation de la bibliothĂšque standard de Python. Lorsque vous avez configurĂ© 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.
Pour plus dâinformations sur les niveaux de journalisation pris en charge par Python, voir la documentation sur les niveaux de journalisation. Notez que Snowflake traite deux des niveaux de journalisation de Python dâune maniĂšre particuliĂšre :
Le niveau
CRITICAL
de Python sera traité comme FATAL.Le niveau
NOTSET
de Python sera traité comme TRACE.
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 :
Mettre en place une table dâĂ©vĂ©nements pour collecter les messages enregistrĂ©s par le code du gestionnaire.
Pour plus dâinformations, voir Aperçu de la table dâĂ©vĂ©nements.
Assurez-vous que le niveau de journalisation est dĂ©fini de maniĂšre Ă ce que les messages souhaitĂ©s soient stockĂ©s dans la table dâĂ©vĂ©nements.
Pour plus dâinformations, voir DĂ©finition des niveaux de journalisation, des mĂ©triques et du traçage.
Remplacement des niveaux de seuil de journalisation avec Python¶
Vous pouvez utiliser le code du gestionnaire Python pour remplacer les niveaux de seuil de journalisation qui ont été définis avec SQL. Lorsque vous définissez le niveau de journalisation avec Python, les entrées de journalisation utiliseront les niveaux de journalisation définis par Python.
En définissant des niveaux de journalisation en Python, vous pouvez effectuer les opérations suivantes :
Remplacer le seuil dĂ©fini pour la session Snowflake ou pour des objets tels que la procĂ©dure ou lâUDF.
Définir des seuils pour des paquets Python spécifiés.
Par exemple, vous pouvez utiliser le nom du journaliseur que vous avez dĂ©fini (et qui est stockĂ© dans la table dâĂ©vĂ©nements) pour dĂ©finir un seuil pour ce journaliseur avec Python.
Le code Python de lâexemple suivant dĂ©finit le niveau de journalisation pour le paquet session
Snowpark pour DEBUG.
session_logger = logging.getLogger('snowflake.snowpark.session')
session_logger.setLevel(logging.DEBUG)
Utilisation du nom du journaliseur pour définir le niveau de journalisation¶
Vous pouvez utiliser le nom du journaliseur enregistrĂ© dans la table dâĂ©vĂ©nements pour dĂ©finir un seuil pour les entrĂ©es de journalisation de ce journaliseur. Cela peut sâavĂ©rer utile lorsque vous souhaitez dĂ©finir le seuil dâun journaliseur de maniĂšre Ă ce quâil filtre les entrĂ©es dâenregistrement indĂ©sirables dĂ©passant un certain niveau.
Pour ce faire, vous devez dâabord interroger la table dâĂ©vĂ©nements pour dĂ©couvrir le nom du journaliseur associĂ© aux entrĂ©es pour lesquelles vous souhaitez capturer un niveau de journalisation diffĂ©rent. Ensuite, en utilisant le nom du journaliseur, vous dĂ©finissez le niveau de journalisation au seuil que vous souhaitez.
Le code de lâexemple suivant demande des entrĂ©es de journal, en incluant le nom du journaliseur dans les donnĂ©es renvoyĂ©es. Vous pouvez obtenir le nom comme valeur de la colonne de portĂ©e.
SET event_table_name='my_db.public.my_event_table';
SELECT
TIMESTAMP as time,
RECORD['severity_text'] as log_level,
SCOPE['name'] as logger_name,
VALUE as message
FROM
IDENTIFIER($event_table_name)
WHERE
RECORD_TYPE = 'LOG';
Cette requĂȘte peut renvoyer de nombreuses entrĂ©es provenant de plusieurs journaliseurs. Si, aprĂšs avoir examinĂ© les rĂ©sultats, vous dĂ©cidez que vous obtenez de nombreux messages INFO
que vous ne souhaitez pas recevoir du journaliseur numpy, vous pouvez utiliser Python pour définir le seuil de ce journaliseur afin de capturer les entrées de journal au niveau ERROR
et au-dessus.
numpy_logger = logging.getLogger('numpy_logs')
numpy_logger.setLevel(logging.ERROR)
Pour en savoir plus sur lâinterrogation de la table dâĂ©vĂ©nements, voir Affichage des messages de journalisation.
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 lors de lâappel de lâune des fonctions de niveau de journalisation â y compris logger.info
, logger.error
, et ainsi de suite â ajoutez un argument de mot-clĂ© extra
, dĂ©finissant la valeur de lâargument sur les paires clĂ©-valeur Ă enregistrer en tant quâattributs personnalisĂ©s.
Le code de lâexemple suivant enregistre un message « Logging with attributes » dans la colonne VALUE de la table des Ă©vĂ©nements. Cela ajoute Ă©galement deux attributs personnalisĂ©s Ă la colonne RECORD_ATTRIBUTES.
CREATE OR REPLACE PROCEDURE do_logging_python()
RETURNS VARCHAR
LANGUAGE PYTHON
PACKAGES = ('snowflake-snowpark-python')
RUNTIME_VERSION = 3.9
HANDLER = 'do_things'
AS $$
import logging
logger = logging.getLogger("python_logger")
def do_things(session):
logger.info("Logging with attributes in SP", extra = {'custom1': 'value1', 'custom2': 'value2'})
return "SUCCESS"
$$;
La sortie de lâappel logger.info
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 in" | { |
| | "code.filepath": "_udf_code.py", |
| | "code.function": "do_things", |
| | "code.lineno": 10, |
| | "custom1": "value1", |
| | "custom2": "value2" |
| | } |
---------------------------------------------------------------------
Exemples Python¶
Les sections suivantes fournissent des exemples dâajout de la prise en charge de la journalisation Ă partir du code Python.
Exemple de procédure stockée¶
Le code de lâexemple suivant importe le module logging
, obtient un enregistreur et enregistre un message au niveau INFO
.
Pour plus dâinformations sur les niveaux de journalisation pris en charge par Python, voir la documentation sur les niveaux de journalisation.
CREATE OR REPLACE PROCEDURE do_logging()
RETURNS VARCHAR
LANGUAGE PYTHON
PACKAGES=('snowflake-snowpark-python')
RUNTIME_VERSION = 3.9
HANDLER='do_things'
AS $$
import logging
logger = logging.getLogger("python_logger")
logger.info("Logging from Python module.")
def do_things(session):
logger.info("Logging from Python function start.")
try:
throw_exception()
except Exception:
logger.error("Logging an error from Python handler: ")
return "ERROR"
return "SUCCESS"
def throw_exception():
raise Exception("Something went wrong.")
$$;
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'] = 'python_logger'
AND RECORD_TYPE = 'LOG';
Lâexemple prĂ©cĂ©dent gĂ©nĂšre la sortie suivante.
---------------------------------------------------------------------------
| SEVERITY | MESSAGE |
---------------------------------------------------------------------------
| "INFO" | "Logging from Python module." |
---------------------------------------------------------------------------
| "INFO" | "Logging from Python function start." |
---------------------------------------------------------------------------
| "ERROR" | "Logging an error from Python handler." |
---------------------------------------------------------------------------
Exemples Streamlit¶
Le code de lâexemple suivant importe le module logging
, obtient un enregistreur et enregistre un message au niveau INFO
.
Pour plus dâinformations sur les niveaux de journalisation pris en charge par Python, voir la documentation sur les niveaux de journalisation.
import streamlit as st
import logging
logger = logging.getLogger('app_logger')
st.title("Streamlit logging example")
hifives_val = st.slider("Number of high-fives", min_value=0, max_value=90, value=60)
if st.button("Submit"):
logger.info(f"Submitted with high-fives: {hifives_val}")