在 Snowflake Scripting 中发出跟踪事件¶
可使用 Snowflake SYSTEM
函数,从使用 Snowflake Scripting 编写的函数或过程处理程序发出跟踪事件。
在发出跟踪事件之前,请确保已设置跟踪级别,以便将所需数据存储在事件表中。有关更多信息,请参阅 为日志、指标和跟踪设置级别。
备注
在开始发出跟踪事件之前,必须设置事件表。有关更多信息,请参阅 事件表概述。
您可以通过对事件表执行 SELECT 命令,来访问存储的跟踪事件数据。有关更多信息,请参阅 查看跟踪数据。
有关在 Snowflake 中设置日志记录和检索消息的一般信息,请参阅 针对函数和过程的跟踪事件。
备注
有关添加跟踪事件时要牢记的准则,请参阅 添加跟踪事件的一般准则。
添加跟踪事件¶
可通过调用 SYSTEM$ADD_EVENT 函数并传递跟踪事件的名称来添加跟踪事件。您还可以选择将属性(键值对)与事件相关联。
以下示例中的代码添加了两个事件:SProcEmptyEvent
和 SProcEventWithAttributes
。通过 SProcEventWithAttributes
,该代码还添加了两个属性:key1
和 key2
。
SYSTEM$ADD_EVENT('SProcEmptyEvent');
SYSTEM$ADD_EVENT('SProcEventWithAttributes', {'key1': 'value1', 'key2': 'value2'});
添加这些事件会在事件表中添加两行,每行在列中 RECORD 具有不同的值:
{
"name": "SProcEmptyEvent"
}
{
"name": "SProcEventWithAttributes"
}
SProcEventWithAttributes
事件行包含行的 RECORD_ATTRIBUTES 列中的以下属性:
{
"key1": "value1",
"key2": "value2"
}
添加 span 属性¶
您可以通过调用 SYSTEM$SET_SPAN_ATTRIBUTES 函数来设置与 Span 关联的属性(键值对)。
有关 Span 的详细信息,请参阅 Snowflake 如何表示跟踪事件。
SYSTEM$SET_SPAN_ATTRIBUTES 函数提供以下形式:
SYSTEM$SET_SPAN_ATTRIBUTES(<object>);
其中
object
是一个 Snowflake Scripting 对象,它具有键值对,用于指定此跟踪事件的属性。
以下示例中的代码创建两个属性并设置其值:
SYSTEM$SET_SPAN_ATTRIBUTES('{'attr1':'value1', 'attr2':true}');
设置这些属性会导致事件表的 RECORD_ATTRIBUTES 列中出现以下内容:
{
"attr1": "value1",
"attr2": "value2"
}
示例¶
以下示例中的代码使用 SYSTEM$ADD_EVENT 函数添加一个名为 name_a
的事件和一个名为 name_b
的事件。name_b
关联两个属性,即 score
和 pass
。该代码还使用 SYSTEM$SET_SPAN_ATTRIBUTES 设置两个 Span 属性,即 key1
和 key2
。
CREATE OR REPLACE PROCEDURE pi_proc()
RETURNS DOUBLE
LANGUAGE SQL
AS $$
BEGIN
-- Add an event without attributes
SYSTEM$ADD_EVENT('name_a');
-- Add an event with attributes
LET attr := {'score': 89, 'pass': TRUE};
SYSTEM$ADD_EVENT('name_b', attr);
-- Set attributes for the span
SYSTEM$SET_SPAN_ATTRIBUTES({'key1': 'value1', 'key2': TRUE});
RETURN 3.14;
END;
$$;
CALL pi_proc();
自动发出子作业和异常的跟踪事件¶
您可以自动为事件表中的 Snowflake Scripting 存储过程发出以下其他类型的跟踪事件:
异常捕获。
有关子作业执行的信息。
子作业统计信息。
存储过程统计信息,包括执行时间和输入值。
自动跟踪发射适用于以下用例:
您想要发出预定义的跟踪事件而不修改存储过程的主体。
您想要收集有关存储过程执行的信息,以便稍后进行分析,其中包括:
有关子作业执行的信息(例如
childJobUUID
、rowCount
、exceptionCode
等)。子作业执行时间。
输入实参值。
您希望提高存储过程执行的可见性,以便更轻松地进行开发和调试,而无需在存储过程中手动添加跟踪代码。
要自动为存储过程发出这些附加的跟踪事件,请使用 ALTER PROCEDURE 命令,将 AUTO_EVENT_LOGGING 参数设置为 TRACING
或者 ALL
。当您将此参数设置为 ALL
时,也会为存储过程自动生成附加的 日志消息。
重要
仅当有效 TRACE_LEVEL 设置为 ALWAYS
或 ON_EVENT
时,才会将附加信息添加到事件表中。有关更多信息,请参阅 为日志、指标和跟踪设置级别。
例如,创建一个简单的表并插入数据:
CREATE OR REPLACE TABLE test_auto_event_logging (id INTEGER, num NUMBER(12, 2));
INSERT INTO test_auto_event_logging (id, num) VALUES
(1, 11.11),
(2, 22.22);
接下来,创建一个名为 auto_event_logging_sp
的存储过程。此示例存储过程用于更新表行,然后对该表执行查询:
CREATE OR REPLACE PROCEDURE auto_event_logging_sp(
table_name VARCHAR,
id_val INTEGER,
num_val NUMBER(12, 2))
RETURNS TABLE()
LANGUAGE SQL
AS
$$
BEGIN
UPDATE IDENTIFIER(:table_name)
SET num = :num_val
WHERE id = :id_val;
LET res RESULTSET := (SELECT * FROM IDENTIFIER(:table_name) ORDER BY id);
RETURN TABLE(res);
EXCEPTION
WHEN statement_error THEN
res := (SELECT :sqlcode sql_code, :sqlerrm error_message, :sqlstate sql_state);
RETURN TABLE(res);
END;
$$
;
以下示例会为存储过程设置 AUTO_EVENT_LOGGING 参数:
ALTER PROCEDURE auto_event_logging_sp(VARCHAR, INTEGER, NUMBER)
SET AUTO_EVENT_LOGGING = 'TRACING';
ALTER PROCEDURE auto_event_logging_sp(VARCHAR, INTEGER, NUMBER)
SET AUTO_EVENT_LOGGING = 'ALL';
调用存储过程:
CALL auto_event_logging_sp('test_auto_event_logging', 2, 44.44);
+----+-------+
| ID | NUM |
|----+-------|
| 1 | 11.11 |
| 2 | 44.44 |
+----+-------+
在事件表中查询由名为 auto_event_logging_sp
的存储过程记录的跟踪数据。对于每个跟踪事件,打印出事件的时间戳、名称和属性。
SELECT
TIMESTAMP as time,
RECORD['name'] as event_name,
RECORD_ATTRIBUTES as attributes,
FROM
my_db.public.my_events
WHERE
RESOURCE_ATTRIBUTES['snow.executable.name'] LIKE '%AUTO_EVENT_LOGGING_SP%'
AND RECORD_TYPE LIKE 'SPAN%';
+-------------------------+--------------------------+-----------------------------------------------------------------------------------------------+
| TIME | EVENT_NAME | ATTRIBUTES |
|-------------------------+--------------------------+-----------------------------------------------------------------------------------------------|
| 2024-10-25 20:48:49.844 | "snow.auto_instrumented" | { |
| | | "childJobTime": 474, |
| | | "executionTime": 2, |
| | | "inputArgumentValues": "{ ID_VAL: 2, TABLE_NAME: test_auto_event_logging, NUM_VAL: 44.44 }" |
| | | } |
| 2024-10-25 20:48:49.740 | "child_job" | { |
| | | "childJobUUID": "01b7ef00-0003-01d1-0000-a99501233092", |
| | | "rowCount": 1, |
| | | "rowsAffected": 1 |
| | | } |
| 2024-10-25 20:48:49.843 | "child_job" | { |
| | | "childJobUUID": "01b7ef00-0003-01d1-0000-a99501233096", |
| | | "rowCount": 2, |
| | | "rowsAffected": 0 |
| | | } |
+-------------------------+--------------------------+-----------------------------------------------------------------------------------------------+
现在,调用存储过程,但指定不存在的表以引发异常:
CALL auto_event_logging_sp('no_table', 2, 82.44);
+----------+-----------------------------------------------------+-----------+
| SQL_CODE | ERROR_MESSAGE | SQL_STATE |
|----------+-----------------------------------------------------+-----------|
| 2003 | SQL compilation error: | 42S02 |
| | Object 'NO_TABLE' does not exist or not authorized. | |
+----------+-----------------------------------------------------+-----------+
再次对事件表运行查询以查看有关异常的信息:
SELECT
TIMESTAMP as time,
RECORD['name'] as event_name,
RECORD_ATTRIBUTES as attributes,
FROM
my_db.public.my_events
WHERE
RESOURCE_ATTRIBUTES['snow.executable.name'] LIKE '%AUTO_EVENT_LOGGING_SP%'
AND RECORD_TYPE LIKE 'SPAN%';
+-------------------------+--------------------------+-----------------------------------------------------------------------------------------------------+
| TIME | EVENT_NAME | ATTRIBUTES |
|-------------------------+--------------------------+-----------------------------------------------------------------------------------------------------|
| 2024-10-25 20:52:43.633 | "snow.auto_instrumented" | { |
| | | "childJobTime": 66, |
| | | "executionTime": 4, |
| | | "inputArgumentValues": "{ ID_VAL: 2, TABLE_NAME: no_table, NUM_VAL: 82.44 }" |
| | | } |
| 2024-10-25 20:52:43.601 | "caught_exception" | { |
| | | "exceptionCode": 2003, |
| | | "exceptionMessage": "SQL compilation error:\nObject 'NO_TABLE' does not exist or not authorized." |
| | | } |
+-------------------------+--------------------------+-----------------------------------------------------------------------------------------------------+