教程:日志记录和跟踪入门

简介

本教程介绍了从函数和过程处理程序代码中发出、收集和查询日志及跟踪数据的基础知识。

The tutorial uses the Snowsight web interface, but you can use any Snowflake client that supports executing SQL. For more information about Snowsight, see Getting started with worksheets and Work with worksheets in Snowsight.

您将学习以下内容

在本教程中,您将学习如何进行以下操作:

  • 创建事件表以存储日志和跟踪数据。

Snowflake 会在表的预定义结构中收集日志和跟踪数据。

  • 从用户定义的函数 (UDF) 发出日志消息和跟踪数据。

可使用专为处理程序语言设计的 API,从处理程序代码中发出日志消息和跟踪数据。

  • 通过查询事件表来查看收集到的日志和跟踪数据。

可使用 SELECT 语句查询此表,以分析收集到的数据。

先决条件

  • 必须在同一个 SQL 命令会话中执行所有 SQL 命令,因为会话上下文是必需的。

    To do this in Snowsight, for example, paste all of your code into the same worksheet as you go along. As you progress from section to section, each section builds on the previous.

  • 必须能够使用 ACCOUNTADMIN 角色。

在本教程中,您将使用 ACCOUNTADMIN 角色执行所有步骤。但在一般情况下,您使用的角色具有专为正在执行的操作而定义的权限。例如,您可能有专为创建 UDFs 的开发者提供的角色,另外还有专为查询收集到的日志和跟踪数据的分析师提供的单独角色,以此类推。

For more about roles, see Switch your primary role and Access control best practices.

设置数据库、仓库和访问

在本部分中,您将创建本教程需要用到的仓库和数据库。您还会开始使用 ACCOUNTADMIN 角色,执行本教程中的部分语句时必须使用此角色。

您要创建一个数据库,稍后将在其中创建事件表和用户定义的函数。对于在本教程中创建的所有对象,均可在不再需要时予以删除,包括数据库和仓库在内。

要创建供本教程使用的数据库和仓库,请执行以下操作:

  1. Sign in to Snowsight.

  2. In the lower-left corner, select your name » Switch role » ACCOUNTADMIN.

  3. At the top of the navigation menu, select Add a dashboard tile (Create) » SQL Worksheet.

  4. Rename the new worksheet to Logging-tracing tutorial.

  5. 在新工作表中,粘贴并运行以下语句以创建数据库。这个新数据库仅用于本教程。

    CREATE OR REPLACE DATABASE tutorial_log_trace_db;
  6. 粘贴并运行以下语句以创建仓库。这个新仓库仅用于本教程。

    CREATE OR REPLACE WAREHOUSE tutorial_log_trace_wh
      WAREHOUSE_TYPE = STANDARD
      WAREHOUSE_SIZE = XSMALL;

在本部分中,您将准备本教程所需的部分。在下一部分中,您将创建事件表来存储日志和跟踪数据。

创建事件表

在本部分中,您将创建事件表。当处理程序代码发出日志消息和跟踪数据时,Snowflake 会将发出的数据保存在事件表行之中。您可以查询事件表以分析数据。

You must create an event table to collect log and trace data. An event table always uses the predefined structure defined by Snowflake.

Important

要完成本部分,您需要能使用 ACCOUNTADMIN 角色,这是更改账户时所必需的,这样新事件表才能是该账户的活动事件表。

若要创建事件表,必须使用已分配 CREATE EVENT TABLE 权限的角色。

要创建事件表,并使其成为账户的活动事件表,请执行以下操作:

  1. 粘贴并运行以下语句,以创建事件表。
    CREATE OR REPLACE EVENT TABLE tutorial_event_table;

Snowflake 在此表中存储日志和跟踪数据。

  1. 粘贴并运行以下语句以更改账户,使您创建的事件表成为该账户的活动事件表。

    USE ROLE ACCOUNTADMIN;
    
    ALTER ACCOUNT SET EVENT_TABLE = tutorial_log_trace_db.public.tutorial_event_table;

此语句将新事件表设置为 Snowflake 应该用于以下用途的表:存储源自当前账户中处理程序的日志消息和跟踪数据。在一个账户中,您只能有一个活动事件表。

在本部分中,您创建了一个事件表。在下一部分中,您将开始发出 Snowflake 存储在表中的日志消息。

发出日志消息

在本部分中,您将使用发出日志消息的 Python 处理程序代码,创建一个用户定义的函数 (UDF)。在代码发出日志消息时,Snowflake 会收集消息数据并将其存储在您创建的事件表中。

Snowflake supports APIs to log messages from each supported handler language. For handlers you write in Python, you can use the logging module in Python’s standard library.

要创建发出日志消息的 UDF,请执行以下操作:

  1. Paste and run the following statement to set the log level to INFO.

    ALTER SESSION SET LOG_LEVEL = INFO;

    This specifies the severity of log messages that Snowflake should capture as the UDF runs. In this case, the level permits all messages ranging from informational (INFO) to the most severe (FATAL).

  2. 粘贴并运行以下语句以创建用户定义的函数。

    CREATE OR REPLACE FUNCTION log_trace_data()
    RETURNS VARCHAR
    LANGUAGE PYTHON
    RUNTIME_VERSION = 3.12
    HANDLER = 'run'
    AS $$
    import logging
    logger = logging.getLogger("tutorial_logger")
    
    def run():
      logger.info("Logging from Python function.")
      return "SUCCESS"
    $$;

代码中突出显示的行执行以下操作:

  • Import the Python logging module so that the handler code can use it.
  • 创建一个日志记录程序,它会公开您的代码将用于在日志中记录消息的接口。
  • Log a message at the INFO level.
  1. 粘贴并运行以下语句来执行刚刚创建的函数。
    SELECT log_trace_data();

这会产生以下输出。此外,在函数执行时,它发出了一条日志消息,而 Snowflake 在事件表中收集了该消息。

--------------------
| LOG_TRACE_DATA() |
--------------------
| SUCCESS          |
--------------------

在本部分中,您从 UDF 发出了一条日志消息。在下一部分中,您将查询事件表以检索与该消息相关的数据。

查询日志消息

在本部分中,您将在事件表中查询上一部分中运行的 UDF 发出的日志消息数据。

Note

处理程序代码发出的日志或跟踪数据可能需要几秒钟时间才能记录到事件表中。如未立即看到结果,请在几秒钟后重试。

Snowflake uses predefined event table columns to collect and store log and trace data of the following kinds:

  • 您从处理程序代码发出的数据,例如日志消息和跟踪事件数据。

您可以在 RECORD_TYPE、RECORD、RECORD_ATTRIBUTES 等列中找到这些数据。

  • Data about the context in which the log or trace data was emitted, such as the timestamp, name of the handler method from which the data was emitted, and so on.

您可以在 RESOURCE_ATTRIBUTES、TIMESTAMP 和 SCOPE 等列中找到这些数据。

要查询事件表以获得日志消息数据,请执行以下操作:

  1. 粘贴并运行以下语句,以查询事件表。

    SELECT
      TIMESTAMP AS time,
      RESOURCE_ATTRIBUTES['snow.executable.name'] as executable,
      RECORD['severity_text'] AS severity,
      VALUE AS message
    FROM
      tutorial_log_trace_db.public.tutorial_event_table
    WHERE
      RECORD_TYPE = 'LOG'
      AND SCOPE['name'] = 'tutorial_logger';

    Some columns contain structured data expressed as key-value pairs. In this query, you specify attribute keys within a column by using bracket notation such as RECORD['severity_text'].

    You also use bracket notation (SCOPE['name']) to specify that you want to select column values only where the log entries are emitted with the Python logger, tutorial_logger, you created in handler code.

  2. 查看输出。

    -----------------------------------------------------------------------------------------------------------
    | TIME                | EXECUTABLE                           | SEVERITY | MESSAGE                         |
    -----------------------------------------------------------------------------------------------------------
    | 2023-04-19 22:00:49 | "LOG_TRACE_DATA():VARCHAR(16777216)" | "INFO"   | "Logging from Python function." |
    -----------------------------------------------------------------------------------------------------------

    The output illustrates how the event table’s predefined columns each contain parts of the collected data. For the EXECUTABLE and SEVERITY values, you’ve used bracket notation to specify the attributes whose values you want.

    | | 输出列 | 描述 | | ------------- | ------------------------------------------------------------------------------------------------- | | | TIME | 条目的创建时间(来自 TIMESTAMP 列)。 | | | EXECUTABLE | UDF name and parameters (from the RESOURCE_ATTRIBUTES column’s snow.executable.name attribute). | | | SEVERITY | Log entry severity (from the RECORD column’s severity_text attribute). | | | MESSAGE | 日志消息(来自 VALUE 列)。 |

在本部分中,您使用了一条 SELECT 语句来查询日志数据。在下一部分中,您将更新 UDF,以使其发出跟踪数据。

发射跟踪数据

在本部分中,您将更新 UDF 处理程序代码,使其也能发出跟踪数据。在代码发出跟踪数据时,Snowflake 会收集数据,并将其存储在您创建的事件表中。

跟踪数据具有结构化特性,包括按 Span 分组的事件数据,以及以键值对形式获取的数据,与日志数据通常支持的详细程度相比,这使您可以更详细地了解代码活动。

Snowflake supports APIs to emit trace data from each supported handler language. For handlers you write in Python, you can use the Snowflake telemetry package.

要更新 UDF 以发送跟踪数据,请执行以下操作:

  1. 粘贴并运行以下语句,以指定应获取哪些跟踪数据。

    ALTER SESSION SET TRACE_LEVEL = ON_EVENT;

    This sets the trace level to ON_EVENT. This specifies that only trace data emitted explicitly by your own code should be captured.

  2. 粘贴并运行以下语句,以创建一个 UDF 来发出跟踪数据。

    CREATE OR REPLACE FUNCTION log_trace_data()
    RETURNS VARCHAR
    LANGUAGE PYTHON
    RUNTIME_VERSION = 3.12
    HANDLER = 'run'
    AS $$
    import logging
    logger = logging.getLogger("tutorial_logger")
    from snowflake import telemetry
    
    def run():
      telemetry.set_span_attribute("example.proc.run", "begin")
      telemetry.add_event("event_with_attributes", {"example.key1": "value1", "example.key2": "value2"})
      logger.info("Logging from Python function.")
      return "SUCCESS"
    $$;

通过运行此代码,即可将之前创建的函数替换为添加代码,以发出跟踪数据的函数。突出显示的行执行以下操作:

  • Import the telemetry package so you can call its functions.
  • 将一个属性及属性值设置为 Snowflake 在代码运行时创建的 Span。

Span 代表一个过程的执行单元或 UDF 的执行单元,您可以在其中添加多个事件。

  • 添加一个事件(具有其自己的属性),将其作为 Span 的一部分进行记录。
  1. 粘贴并运行以下语句来执行刚刚创建的函数。
    SELECT log_trace_data();

这会产生以下输出。此外,在函数执行时,它发出了跟踪数据,而 Snowflake 在事件表中收集了该跟踪数据。

--------------------
| LOG_TRACE_DATA() |
--------------------
| SUCCESS          |
--------------------

在本部分中,您从 UDF 发出了跟踪数据。在下一部分中,您将查询事件表以检索与该跟踪相关的数据。

查询跟踪消息

在本部分中,您将在事件表中查询上一部分中运行的 UDF 发出的跟踪数据。

Note

处理程序代码发出的日志或跟踪数据可能需要几秒钟时间才能记录到事件表中。如未立即看到结果,请在几秒钟后重试。

您编写的查询将检索与该函数发出的事件相关的上下文信息。该上下文包括发出它的函数的名称。

要查询事件表以获得跟踪数据,请执行以下操作:

  1. 粘贴并运行以下语句,以在事件表中查询跟踪数据。

    SELECT
      TIMESTAMP AS time,
      RESOURCE_ATTRIBUTES['snow.executable.name'] AS handler_name,
      RECORD['name'] AS event_name,
      RECORD_ATTRIBUTES AS attributes
    FROM
      tutorial_log_trace_db.public.tutorial_event_table
    WHERE
      RECORD_TYPE = 'SPAN_EVENT'
      AND HANDLER_NAME LIKE 'LOG_TRACE_DATA%';

    Some columns contain structured data expressed as key-value pairs. For these, you can select attribute values within a column by using bracket notation, as shown in the code.

  2. 查看输出。

    -----------------------------------------------------------------------------------------------------------------------------------------------------
    | TIME                    | HANDLER_NAME                         | EVENT_NAME              | ATTRIBUTES                                             |
    -----------------------------------------------------------------------------------------------------------------------------------------------------
    | 2023-05-10 20:49:35.080 | "LOG_TRACE_DATA():VARCHAR(16777216)" | "event_with_attributes" | { "example.key1": "value1", "example.key2": "value2" } |
    -----------------------------------------------------------------------------------------------------------------------------------------------------

    The output illustrates how the event table’s predefined columns each contain parts of the collected data. For the EXECUTABLE and SEVERITY values, you’ve used bracket notation to specify the attribute whose value you want.

    | | 输出列 | 描述 | | ------------- | -------------------------------------------------------------------------------------------------- | | | TIME | 条目的创建时间(来自 TIMESTAMP 列)。 | | | HANDLER_NAME | UDF name and parameters (from the RESOURCE_ATTRIBUTES column’s snow.executable.name attribute). | | | EVENT_NAME | Name of the event added with the add_event function (from the RECORD column’s name attribute). | | | ATTRIBUTES | 为事件添加的附带属性(来自 RECORD_ATTRIBUTES 列)。 |

在本部分中,您在事件表中查询了您编写的 UDF 发出的跟踪数据。在最后一部分中,您将获得一些链接,其指向与本教程中执行的操作相关的信息。

了解详情

您已成功完成!做得很好。

在本教程中,您获得了端到端视图,以了解如何从处理程序代码中发出日志和跟踪数据、存储这些数据,然后查询所存储的数据。在此过程中,您执行了以下操作: