教程:日志记录和跟踪入门¶
简介¶
本教程介绍了从函数和过程处理程序代码中发出、收集和查询日志及跟踪数据的基础知识。
本教程使用 Snowsight Web 界面,不过您可以使用任何支持执行 SQL 的 Snowflake 客户端。有关 Snowsight 的更多信息,请参阅 工作表入门 和 在 Snowsight 中管理和使用工作表。
您将学习的内容¶
在本教程中,您将学习如何进行以下操作:
创建事件表以存储日志和跟踪数据。
Snowflake 会在表的预定义结构中收集日志和跟踪数据。
从用户定义的函数 (UDF) 发出日志消息和跟踪数据。
可使用专为处理程序语言设计的 API,从处理程序代码中发出日志消息和跟踪数据。
通过查询事件表来查看收集到的日志和跟踪数据。
可使用 SELECT 语句查询此表,以分析收集到的数据。
先决条件¶
设置数据库、仓库和访问¶
在本部分中,您将创建本教程需要用到的仓库和数据库。您还会开始使用 ACCOUNTADMIN 角色,执行本教程中的部分语句时必须使用此角色。
您要创建一个数据库,稍后将在其中创建事件表和用户定义的函数。对于在本教程中创建的所有对象,均可在不再需要时予以删除,包括数据库和仓库在内。
要创建供本教程使用的数据库和仓库,请执行以下操作:
登录 Snowsight。
打开 Projects » Worksheets。
选择 + » SQL Worksheet。
将新工作表重命名 为
Logging-tracing tutorial
。在新工作表中,粘贴并运行以下语句以创建数据库。这个新数据库仅用于本教程。
CREATE OR REPLACE DATABASE tutorial_log_trace_db;
粘贴并运行以下语句以创建仓库。这个新仓库仅用于本教程。
CREATE OR REPLACE WAREHOUSE tutorial_log_trace_wh WAREHOUSE_TYPE = STANDARD WAREHOUSE_SIZE = XSMALL;
在本部分中,您将准备本教程所需的部分。在下一部分中,您将创建事件表来存储日志和跟踪数据。
创建事件表¶
在本部分中,您将创建事件表。当处理程序代码发出日志消息和跟踪数据时,Snowflake 会将发出的数据保存在事件表行之中。您可以查询事件表以分析数据。
必须创建事件表以收集日志和跟踪数据。事件表始终使用 Snowflake 定义的 预定义结构。
重要
要完成本部分,您需要能使用 ACCOUNTADMIN 角色,这是更改账户时所必需的,这样新事件表才能是该账户的活动事件表。
要创建事件表,并使其成为账户的活动事件表,请执行以下操作:
粘贴并运行以下语句,以创建事件表。
CREATE OR REPLACE EVENT TABLE tutorial_event_table;
Snowflake 在此表中存储日志和跟踪数据。
粘贴并运行以下语句以更改账户,使您创建的事件表成为该账户的活动事件表。
ALTER ACCOUNT SET EVENT_TABLE = tutorial_log_trace_db.public.tutorial_event_table;
此语句将新事件表设置为 Snowflake 应该用于以下用途的表:存储源自当前账户中处理程序的日志消息和跟踪数据。在一个账户中,您只能有一个活动事件表。
在本部分中,您创建了一个事件表。在下一部分中,您将开始发出 Snowflake 存储在表中的日志消息。
发出日志消息¶
在本部分中,您将使用发出日志消息的 Python 处理程序代码,创建一个用户定义的函数 (UDF)。在代码发出日志消息时,Snowflake 会收集消息数据并将其存储在您创建的事件表中。
Snowflake 支持通过 APIs 记录来自每种受支持的处理程序语言的消息。对于使用 Python 编写的处理程序,您可以使用 Python 标准库中的 logging
模块。
要创建发出日志消息的 UDF,请执行以下操作:
粘贴并运行以下语句,以将日志级别设置为
INFO
。ALTER SESSION SET LOG_LEVEL = INFO;
这指定了 Snowflake 在 UDF 运行时应该获取的日志消息的严重性。在这种情况下,该级别允许捕获从信息 (
INFO
) 到最高严重性 (FATAL
) 的所有消息。粘贴并运行以下语句以创建用户定义的函数。
CREATE OR REPLACE FUNCTION log_trace_data() RETURNS VARCHAR LANGUAGE PYTHON RUNTIME_VERSION = 3.8 HANDLER = 'run' AS $$ import logging logger = logging.getLogger("tutorial_logger") def run(): logger.info("Logging from Python function.") return "SUCCESS" $$;
代码中突出显示的行执行以下操作:
导入 Python
logging
模块,以供处理程序代码使用。创建一个日志记录程序,它会公开您的代码将用于在日志中记录消息的接口。
它会在
INFO
级别记录一条消息。
粘贴并运行以下语句来执行刚刚创建的函数。
SELECT log_trace_data();
这会产生以下输出。此外,在函数执行时,它发出了一条日志消息,而 Snowflake 在事件表中收集了该消息。
-------------------- | LOG_TRACE_DATA() | -------------------- | SUCCESS | --------------------
在本部分中,您从 UDF 发出了一条日志消息。在下一部分中,您将查询事件表以检索与该消息相关的数据。
查询日志消息¶
在本部分中,您将在事件表中查询上一部分中运行的 UDF 发出的日志消息数据。
备注
处理程序代码发出的日志或跟踪数据可能需要几秒钟时间才能记录到事件表中。如未立即看到结果,请在几秒钟后重试。
Snowflake 使用 预定义的事件表列,来收集和存储以下类型的日志和跟踪数据:
您从处理程序代码发出的数据,例如日志消息和跟踪事件数据。
您可以在 RECORD_TYPE、RECORD、RECORD_ATTRIBUTES 等列中找到这些数据。
与发出日志或跟踪数据的 上下文相关的数据,例如时间戳、发出数据的处理程序方法的名称等。
您可以在 RESOURCE_ATTRIBUTES、TIMESTAMP 和 SCOPE 等列中找到这些数据。
要查询事件表以获得日志消息数据,请执行以下操作:
粘贴并运行以下语句,以查询事件表。
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';
有些列包含以键值对表示的结构化数据。在此查询中,您可以使用 方括号表示法 在列中指定属性键,例如
RECORD['severity_text']
。您还可以使用方括号表示法 (
SCOPE['name']
),指定仅选择符合以下条件的列值:使用您在处理程序代码中创建的 Python 日志记录器tutorial_logger
发出日志条目的列。查看输出。
----------------------------------------------------------------------------------------------------------- | TIME | EXECUTABLE | SEVERITY | MESSAGE | ----------------------------------------------------------------------------------------------------------- | 2023-04-19 22:00:49 | "LOG_TRACE_DATA():VARCHAR(16777216)" | "INFO" | "Logging from Python function." | -----------------------------------------------------------------------------------------------------------
输出展示了 事件表的预定义列 如何分别包含所收集数据的各个部分。对于
EXECUTABLE
和SEVERITY
值,您已使用方括号表示法来指定所需值对应的属性。输出列
描述
TIME
条目的创建时间(来自 TIMESTAMP 列)。
EXECUTABLE
UDF 名称和参数(来自 RESOURCE_ATTRIBUTES 列的
snow.executable.name
属性)。SEVERITY
日志条目严重性(来自 RECORD 列的
severity_text
属性)。MESSAGE
日志消息(来自 VALUE 列)。
在本部分中,您使用了一条 SELECT 语句来查询日志数据。在下一部分中,您将更新 UDF,以使其发出跟踪数据。
发出追踪数据¶
在本部分中,您将更新 UDF 处理程序代码,使其也能发出跟踪数据。在代码发出跟踪数据时,Snowflake 会收集数据,并将其存储在您创建的事件表中。
跟踪数据具有结构化特性,包括按 Span 分组的事件数据,以及以键值对形式获取的数据,与日志数据通常支持的详细程度相比,这使您可以更详细地了解代码活动。
Snowflake 支持通过 APIs 从每种支持的处理程序语言发出跟踪数据。对于使用 Python 编写的处理程序,可以使用 Snowflake telemetry
包。
要更新 UDF 以发送跟踪数据,请执行以下操作:
粘贴并运行以下语句,以指定应获取哪些跟踪数据。
ALTER SESSION SET TRACE_LEVEL = ON_EVENT;
这会将跟踪级别设置为
ON_EVENT
。这指定了仅应获取您自己的代码显式发出的跟踪数据。粘贴并运行以下语句,以创建一个 UDF 来发出跟踪数据。
CREATE OR REPLACE FUNCTION log_trace_data() RETURNS VARCHAR LANGUAGE PYTHON PACKAGES = ('snowflake-telemetry-python') RUNTIME_VERSION = 3.8 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" $$;
通过运行此代码,即可将之前创建的函数替换为添加代码,以发出跟踪数据的函数。突出显示的行执行以下操作:
将
snowflake-telemetry-python`(其中包含 :code:`telemetry
包)添加到 UDF 的执行环境中。导入
telemetry
包,以便您可以调用其函数。将一个属性及属性值设置为 Snowflake 在代码运行时创建的 Span。
Span 代表一个过程的执行单元或 UDF 的执行单元,您可以在其中添加多个事件。
添加一个事件(具有其自己的属性),将其作为 Span 的一部分进行记录。
粘贴并运行以下语句来执行刚刚创建的函数。
SELECT log_trace_data();
这会产生以下输出。此外,在函数执行时,它发出了跟踪数据,而 Snowflake 在事件表中收集了该跟踪数据。
-------------------- | LOG_TRACE_DATA() | -------------------- | SUCCESS | --------------------
在本部分中,您从 UDF 发出了跟踪数据。在下一部分中,您将查询事件表以检索与该跟踪相关的数据。
查询追踪消息¶
在本部分中,您将在事件表中查询上一部分中运行的 UDF 发出的跟踪数据。
备注
处理程序代码发出的日志或跟踪数据可能需要几秒钟时间才能记录到事件表中。如未立即看到结果,请在几秒钟后重试。
您编写的查询将检索与该函数发出的事件相关的上下文信息。该上下文包括发出它的函数的名称。
要查询事件表以获得跟踪数据,请执行以下操作:
粘贴并运行以下语句,以在事件表中查询跟踪数据。
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%';
有些列包含以键值对表示的结构化数据。为此,您可以使用 :ref:`方括号表示法 <label-bracket_notation_when_querying_semistructured_data>`在列中选择属性值,如代码中所示。
查看输出。
----------------------------------------------------------------------------------------------------------------------------------------------------- | 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" } | -----------------------------------------------------------------------------------------------------------------------------------------------------
输出展示了 事件表的预定义列 如何分别包含所收集数据的各个部分。对于
EXECUTABLE
和SEVERITY
值,您已使用方括号表示法来指定所需值对应的属性。输出列
描述
TIME
条目的创建时间(来自 TIMESTAMP 列)。
HANDLER_NAME
UDF 名称和参数(来自 RESOURCE_ATTRIBUTES 列的
snow.executable.name
属性)。EVENT_NAME
通过
add_event
函数添加的事件的名称(来自 RECORD 列的name
属性)。ATTRIBUTES
为事件添加的附带属性(来自 RECORD_ATTRIBUTES 列)。
在本部分中,您在事件表中查询了您编写的 UDF 发出的跟踪数据。在最后一部分中,您将获得一些链接,其指向与本教程中执行的操作相关的信息。
了解详情¶
您已成功完成!做得很好。
在本教程中,您获得了端到端视图,以了解如何从处理程序代码中发出日志和跟踪数据、存储这些数据,然后查询所存储的数据。在此过程中,您执行了以下操作:
创建了用户定义的函数 (UDF),用于发送日志和跟踪数据。相关信息请参阅以下内容:
有关 Snowflake 中的日志记录支持的概述,请参阅 来自函数和过程的日志记录消息。有关使用 Python 进行日志记录的具体信息,请参阅 Python 标准库中的 来自函数和过程的日志记录消息 和 `日志记录 <https://docs.python.org/library/logging.html (https://docs.python.org/library/logging.html)>`__模块。
有关设置日志级别的详细信息,请参阅 设置日志级别。
有关跟踪支持的概述,请参阅 针对函数和过程的跟踪事件。有关使用 Python 执行跟踪的具体信息,请参阅 在 Python 中发出跟踪事件。
有关设置跟踪级别的详细信息,请参阅 设置跟踪级别。
有关创建 UDFs 的一般信息,请参阅 用户定义函数概述。
查询了事件表 以获取日志和跟踪数据。有关事件表的信息,请参阅以下内容:
有关如何查询日志数据的更完整介绍,请参阅 访问已记录消息的数据。
有关如何查询跟踪数据的介绍,请参阅 访问跟踪数据。
有关 Span 和事件的详细信息,以及 Snowflake 如何为其存储数据,请参阅 Snowflake 如何表示跟踪事件。