在 Python 中记录消息日志

您可以使用 ` 日志记录 <https://docs.python.org/library/logging.html (https://docs.python.org/library/logging.html)>`_ (Python 标准库中的日志记录模块)记录来自用 Python 编写的函数或过程处理程序的消息。当您设置事件表来存储日志条目时,Snowflake 会将处理程序代码生成的日志条目存储在表中。

有关 Python 支持的日志记录级别的更多信息,请参阅 ` 日志记录级别文档 <https://docs.python.org/3/library/logging.html#levels (https://docs.python.org/3/library/logging.html#levels)>`_ 。请注意,Snowflake 以特定方式处理两个 Python 日志记录级别:

  • Python CRITICAL 级别将被视为 FATAL。

  • Python NOTSET 级别将被视为 TRACE。

有关在 Snowflake 中设置日志记录和检索消息的一般信息,请参阅 来自函数和过程的日志记录消息

通过代码记录之前,您必须:

  • 设置事件表来收集通过处理程序代码记录的消息。

    有关更多信息,请参阅 设置事件表

  • 确保您设置了日志记录级别,以便将所需的消息存储在事件表中。

    有关更多信息,请参阅 设置日志级别

使用 Python 替换日志阈值级别

您可使用 Python 处理程序代码来替换 已使用 SQL 设置了日志级别 的日志阈值级别。使用 Python 设置日志级别时,日志条目将使用 ` Python 定义的日志记录级别 <https://docs.python.org/3/library/logging.html#levels (https://docs.python.org/3/library/logging.html#levels)>`_ 。

通过使用 Python 设置日志级别,您可执行以下操作:

  • 替换为 Snowflake 会话或对象(如过程或 UDF)设置的阈值。

  • 将阈值范围限定为指定的 Python 包。

    例如,您可以使用您设置的记录器名称(并存储在 事件表 中),利用 Python 设置该记录器的阈值。

以下示例中的 Python 代码将 Snowpark session 包的日志级别设置为 DEBUG。

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

使用记录器名称设置日志记录级别

您可以使用事件表中记录的记录器名称为该记录器中的日志条目设置阈值。当您想要设置记录器的阈值,使它过滤掉高于特定级别的不需要的日志条目时,此操作可能会很有用。

为此,您首先需要查询事件表,找出与要获取不同日志记录级别的条目相关的记录器名称。然后,使用该记录器名称将日志级别设置为所需的阈值。

以下示例中的代码查询日志条目,包括返回数据中的记录器名称。您可以 :ref:` 范围列 <label-event_table_scope_column>` 值的形式获取该名称。

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

此查询可能会返回来自多个记录器的许多条目。如果在查看结果后,您认为您从 numpy 记录器中得到了许多不想要的 INFO 消息,则可使用 Python 设置该记录器的阈值,以获取 ERROR 及以上级别的日志条目。

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

有关查询事件表的更多信息,请参阅 访问已记录消息的数据

Python 示例

以下各节提供了从 Python 代码中为日志记录添加支持的示例。

存储过程示例

以下示例中的代码导入 logging 模块、获取记录器,并在 INFO 级别记录消息。

有关 Python 支持的日志记录级别的更多信息,请参阅 ` 日志记录级别文档 <https://docs.python.org/3/library/logging.html#levels (https://docs.python.org/3/library/logging.html#levels)>`_ 。

CREATE OR REPLACE PROCEDURE do_logging()
RETURNS VARCHAR
LANGUAGE PYTHON
PACKAGES=('snowflake-snowpark-python')
RUNTIME_VERSION=3.8
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

您可以通过对事件表执行 SELECT 命令,来访问日志消息。有关更多信息,请参阅 访问已记录消息的数据

以下示例中的代码查询存储日志消息的事件表。该查询报告处理程序类中每个日志条目的严重性和消息。

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

前面的示例生成以下输出。

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

Streamlit 示例

以下示例中的代码导入 logging 模块、获取记录器,并在 INFO 级别记录消息。

有关 Python 支持的日志记录级别的更多信息,请参阅 ` 日志记录级别文档 <https://docs.python.org/3/library/logging.html#levels (https://docs.python.org/3/library/logging.html#levels)>`_ 。

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
语言: 中文