Protokollierung von Meldungen in Python

Sie können Meldungen von einem in Python geschriebenen Funktions- oder Prozedur-Handler protokollieren, indem Sie logging, das Protokollierungsmodul der Standardbibliothek von Python, verwenden. Wenn Sie eine Ereignistabelle zum Speichern von Protokolleinträgen eingerichtet haben, speichert Snowflake die von Ihrem Handler-Code generierten Protokolleinträge in dieser Tabelle.

Weitere Informationen zu den von Python unterstützten Protokolliergraden finden Sie in der Dokumentation zu Protokolliergrade. Beachten Sie, dass Snowflake zwei der Python-Protokolliergrade auf besondere Weise verarbeitet:

  • Die Python-Schweregrad CRITICAL wird als FATAL behandelt.

  • Die Python-Schweregrad NOTSET wird als TRACE behandelt.

Allgemeine Informationen zur Einstellung der Protokollierung und zum Abrufen von Meldungen in Snowflake finden Sie unter Protokollierung von Meldungen aus Funktionen und Prozeduren.

Bevor Sie die Protokollierung für Code nutzen können, müssen Sie Folgendes tun:

Überschreiben von Protokollschwellenwerten mit Python

Sie können Python-Handler-Code verwenden, um die Schwellenwerte für die Protokollierung zu überschreiben, die für den mit SQL festgelegten Protokolliergrad gelten. Wenn Sie den Protokolliergrad mit Python festlegen, werden für die Protokolleinträge die von Python definierten Protokolliergrade verwendet.

Durch das Festlegen von Protokolliergraden in Python können Sie Folgendes tun:

  • Überschreiben des Schwellenwerts, der für die Snowflake-Sitzung oder für Objekte wie die Prozedur oder UDF festgelegt wurde.

  • Festlegen von Schwellenwerten, die nur für bestimmte Python-Pakete gelten.

    So können Sie beispielsweise den von Ihnen festgelegten (und in der Ereignistabelle gespeicherten) Loggernamen verwenden, um mit Python einen Schwellenwert für diesen Logger festzulegen.

Der Python-Code im folgenden Beispiel setzt den Protokolliergrad für das Snowpark-Paket session auf DEBUG.

session_logger = logging.getLogger('snowflake.snowpark.session')
session_logger.setLevel(logging.DEBUG)
Copy

Verwenden des Loggernamens zum Einstellen des Protokolliergrads

Sie können den in der Ereignistabelle erfassten Loggernamen verwenden, um einen Schwellenwert für Protokolleinträge von diesem Logger festzulegen. Dies kann nützlich sein, wenn Sie den Schwellenwert eines Loggers so einstellen möchten, dass unerwünschte Protokolleinträge oberhalb eines bestimmten Wertes herausgefiltert werden.

Dazu müssen Sie zunächst die Ereignistabelle abfragen, um den Namen des Loggers zu ermitteln, der mit den Einträgen verbunden ist, für die Sie einen anderen Protokolliergrad erfassen möchten. Unter Verwendung dieses Loggernamens setzen Sie dann den Protokolliergrad auf den gewünschten Schwellenwert.

Der Code im folgenden Beispiel führt eine Abfrage nach Protokolleinträgen aus und fügt den Loggernamen in die zurückgegebenen Daten ein. Sie können den Namen als Wert der Spalte Scope erhalten.

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';
Copy

Diese Abfrage kann viele Einträge von mehreren Loggern zurückgeben. Wenn Sie nach Durchsicht der Ergebnisse zu dem Schluss kommen, dass Sie vom Numpy-Logger viele INFO-Meldungen erhalten, die Sie nicht benötigen, können Sie mit Python den Schwellenwert dieses Loggers so einstellen, dass nur Protokolleinträge des Protokolliergrads ERROR und darüber erfasst werden.

numpy_logger = logging.getLogger('numpy_logs')
numpy_logger.setLevel(logging.ERROR)
Copy

Weitere Informationen zum Abfragen der Ereignistabelle finden Sie unter Anzeigen von Protokollmeldungen.

Hinzufügen von benutzerdefinierten Attributen

Wenn Sie einen Protokolleintrag erstellen, können Sie Ihre eigenen Attribute in Schlüssel-Wert-Paaren hinzufügen. Snowflake speichert diese benutzerdefinierten Attribute in der Spalte RECORD_ATTRIBUTES der Ereignistabelle.

Um benutzerdefinierte Attribute hinzuzufügen, wenn Sie eine der Funktionen des Protokolliergrads aufrufen, einschließlich logger.info, logger.error usw. fügen Sie ein extra Schlüsselwort als Argument hinzu und stellen Sie den Wert des Arguments auf die Schlüssel-Wert-Paare ein, die als benutzerdefinierte Attribute aufgezeichnet werden sollen.

Der Code im folgenden Beispiel protokolliert eine Meldung „Protokollierung mit Attributen“ in der VALUE-Spalte der Ereignistabelle. Es fügt außerdem zwei benutzerdefinierte Attribute zur RECORD_ATTRIBUTES-Spalte hinzu.

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"
$$;
Copy

Die Ausgabe des logger.info-Aufrufs wird in der Ereignistabelle wie folgt angezeigt. Beachten Sie, dass die RECORD_ATTRIBUTES-Spalte Attribute enthält, die Snowflake automatisch hinzufügt.

---------------------------------------------------------------------
| VALUE                        | RECORD_ATTRIBUTES                  |
---------------------------------------------------------------------
| "Logging with attributes in" | {                                  |
|                              |   "code.filepath": "_udf_code.py", |
|                              |   "code.function": "do_things",    |
|                              |   "code.lineno": 10,               |
|                              |   "custom1": "value1",             |
|                              |   "custom2": "value2"              |
|                              | }                                  |
---------------------------------------------------------------------

Python-Beispiele

In den folgenden Abschnitten finden Sie Beispiele für das Hinzufügen von Unterstützung für die Protokollierung aus Python-Code.

Beispiel einer gespeicherten Prozedur

Der Code im folgenden Beispiel importiert das Modul logging, ruft einen Logger ab und protokolliert eine Meldung des Protokolliergrads INFO.

Weitere Informationen zu den von Python unterstützten Protokolliergraden finden Sie in der Dokumentation zu Protokolliergrade.

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.")

$$;
Copy

Sie können auf die Protokollmeldungen zugreifen, indem Sie einen SELECT-Befehl auf der Ereignistabelle ausführen. Weitere Informationen dazu finden Sie unter Anzeigen von Protokollmeldungen.

Der Code im folgenden Beispiel fragt die Ereignistabelle ab, in der die Protokollmeldungen gespeichert sind. Die Abfrage gibt den Schweregrad und die Meldung jedes Protokolleintrags der Handler-Klasse zurück.

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';
Copy

Das vorherige Beispiel generiert die folgende Ausgabe.

---------------------------------------------------------------------------
| SEVERITY | MESSAGE                                                      |
---------------------------------------------------------------------------
| "INFO"   | "Logging from Python module."                                |
---------------------------------------------------------------------------
| "INFO"   | "Logging from Python function start."                        |
---------------------------------------------------------------------------
| "ERROR"  | "Logging an error from Python handler."                      |
---------------------------------------------------------------------------

Streamlit-Beispiel

Der Code im folgenden Beispiel importiert das Modul logging, ruft einen Logger ab und protokolliert eine Meldung des Protokolliergrads INFO.

Weitere Informationen zu den von Python unterstützten Protokolliergraden finden Sie in der Dokumentation zu Protokolliergrade.

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}")
Copy