Snowpark Container Services:监控服务

Publishing and accessing container logs

Snowflake automatically collects and stores container logs --- whatever your application container emits to standard output and standard error --- to an event table for later analysis, unless you choose to opt out. Ensure that your code outputs useful information that can help with debugging your service or conducting retrospective analysis of your services and jobs.

Use a combination of the following settings to control which container logs are sent to the event table:

  • In the service specification, use the logExporter field to indicate which stream (stdout/stderr) should be sent to the event table.

  • In CREATE SERVICE or ALTER SERVICE command, specify the LOG_LEVEL parameter to indicate the severity at which logs are collected.

When a service container is running, you can also retrieve the container log, without saving the logs to the event table by using the SYSTEM$GET_SERVICE_LOGS system function. This process is most useful during development and testing of your service code.

Publishing container logs

You application containers can publish structured or unstructured logs:

  • Unstructured logs: Text that can't be parsed as JSON that your application containers emit to standard output and standard error. Snowflake persists these strings to the value column in the event table.

  • Structured logs: These are JSON text that application containers emit to standard output and standard error. Snowflake extracts JSON fields and saves them to specific columns in the event table. Then, you can to query the event table and apply filters when exploring events.

    The following JSON structure shows supported fields that Snowflake stores in event table columns. If your application emits JSON that includes unsupported fields, as shown in the following example, Snowflake ignores those fields.

    {
      "severity_text": "DEBUG",    # "<DEBUG, INFO, WARN, ERROR, FATAL>",
      "body": "hello from SPCS",   # <body text>",
      "attributes": {
        "attr_key1": "attr_value1",
        "attr_key2": { "nested_key2": "nested_value2" } },
      },
      "scope": { "name1": "val1" },
      "timestamp": "2025-01-01T12:34:56.789Z", # Format: RFC 3339
      # Unsupported fields are dropped.
      "another_field_key1": "another_field_val1",
      "another_field_key2": "another_field_val2",
    }
    
    Copy

    The following table shows the JSON-log field names and the corresponding event-table column names where Snowflake stores their values. For description of the log fields, see the 事件表列 descriptions.

    JSON field

    Event table column

    Comment

    severity_text

    RECORD

    Snowflake saves both severity_text and the Snowflake-assigned severity_number as Object fields in this column.

    attributes

    RECORD_ATTRIBUTES.

    The fields from structured log are copied as Object fields in this column.

    scope

    SCOPE

    The fields from the structured log are copied as Object fields in this column.

    timestamp

    TIMESTAMP

    The following example shows a container log stored in an event table:

    +----------------------+--------------------------+-------------+----------------------------+-------------------+---------------------------------------------------------------------------------------------------+
    |        VALUE         |       TIMESTAMP          | RECORD_TYPE |           RECORD           |       SCOPE       |            RECORD_ATTRIBUTES           |                   RESOURCE_ATTRIBUTES                    |
    +----------------------+--------------------------+-------------+----------------------------+-------------------+---------------------------------------------------------------------------------------------------+
    | "hello from SPCS"    | 2025-01-01T12:34:56.789Z | LOG         | {                          | {                 | {                                      | {                                                        |
    |                      |                          |             |   "severity_number": 5,    |   "name1": "val1" |   "attr_key1": "attr_value1",          |   "snow.account.name": "****",                           |
    |                      |                          |             |   "severity_text": "DEBUG" | }                 |   "attr_key2": {                       |   "snow.compute_pool.id": "****",                        |
    |                      |                          |             | }                          |                   |     "nested_key2": "nested_value2"     |   "snow.compute_pool.name": "MYPO****",                  |
    |                      |                          |             |                            |                   |   }                                    |   "snow.compute_pool.node.id": "****",                   |
    |                      |                          |             |                            |                   | }                                      |   "snow.compute_pool.node.instance_family": "CPU_****",  |
    |                      |                          |             |                            |                   |                                        |   "snow.database.id": "****",                            |
    |                      |                          |             |                            |                   |                                        |   "snow.database.name": "MYDB****",                      |
    |                      |                          |             |                            |                   |                                        |   "snow.query.id": "****",                               |
    |                      |                          |             |                            |                   |                                        |   "snow.schema.id": "****",                              |
    |                      |                          |             |                            |                   |                                        |   "snow.schema.name": "MYSC****",                        |
    |                      |                          |             |                            |                   |                                        |   "snow.service.container.instance": "0",                |
    |                      |                          |             |                            |                   |                                        |   "snow.service.container.name": "main****",             |
    |                      |                          |             |                            |                   |                                        |   "snow.service.container.run.id": "****",               |
    |                      |                          |             |                            |                   |                                        |   "snow.service.id": "****",                             |
    |                      |                          |             |                            |                   |                                        |   "snow.service.instance": "0",                          |
    |                      |                          |             |                            |                   |                                        |   "snow.service.name": "TEST****",                       |
    |                      |                          |             |                            |                   |                                        |   "snow.service.type": "Service"                         |
    |                      |                          |             |                            |                   |                                        | }                                                        |
    +----------------------+--------------------------+-------------+----------------------------+-------------------+----------------------------------------+----------------------------------------------------------+
    

    If you use Python for your application code, you can use the Snowflake-provided log formatter (https://pypi.org/project/snowflake-telemetry-python/) (SnowflakeLogFormatter) to emit structured logs, as shown in the following example:

    from snowflake.telemetry.logs import SnowflakeLogFormatter
    
    handler = logging.StreamHandler(stream=get_stream(arguments.stream))
    handler.setFormatter(SnowflakeLogFormatter())
    logger.addHandler(handler)
    logger.setLevel(logging.DEBUG) # info by default
    
    # Emit logs with record attributes (`extra` argument)
    logger.warning("warning log record with attributes", extra={"custom": True})
    logger.debug("debug log with nested attributes", extra={"nested": {"key1": [1, 2, 3]}})
    
    Copy

Accessing container logs

You can currently access container logs by using the following options:

  • Use the service helper method: We recommend calling the 使用 <service-name>!SPCS_GET_LOGS 函数 to retrieve container logs of the specified service or job, collected by Snowflake in the event table.

  • 直接使用事件表: 如果您拥有事件表的完全访问权限,则可以直接查询事件表以获取历史日志。

  • 使用 SYSTEM$GET_SERVICE_LOGS 系统函数: 调用 SYSTEM$GET_SERVICE_LOGS 以检索当前正在运行的服务或作业容器的日志。

使用 <service-name>!SPCS_GET_LOGS 函数

<service_name>!SPCS_GET_LOGS 表函数返回指定作业容器的日志。这些日志由 Snowflake 收集并存储在事件表中。

以下列表说明了使用此表函数的优点:

  • 您可以检索特定服务的日志。

  • 您可以检索指定时间范围内的日志。

  • 调用方不需要访问整个事件表,这对于具有严格信息安全要求的客户有利。如果当前会话包含服务所有者角色,则他们有权访问这些日志。

对于 service_name,您可以指定服务的名称。函数返回 Snowflake 从该服务的容器收集的日志(参阅 Publishing and accessing container logs)。

您可以选择性指定日期范围。默认情况下,该函数将返回一天的日志。例如,该查询检索了 Snowflake 从 my_test_job 任务容器收集的过去一天的日志,这是默认设置。

SELECT * FROM TABLE(my_test_job!SPCS_GET_LOGS());
Copy

输出示例:

+-------------------------+-------------+----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+
| TIMESTAMP               | INSTANCE_ID | CONTAINER_NAME | LOG                                                                                                                                                                 | RECORD_ATTRIBUTES          |
|-------------------------+-------------+----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------|
| 2025-06-26 00:23:40.281 |           0 | main           | job-tutorial - INFO - Job finished                                                                                                                                  | {                          |
|                         |             |                |                                                                                                                                                                     |   "log.iostream": "stdout" |
|                         |             |                |                                                                                                                                                                     | }                          |
| 2025-06-26 00:23:38.787 |           0 | main           | job-tutorial - INFO - Executing query [select current_time() as time,'hello'] and writing result to table [results]                                                 | {                          |
|                         |             |                |                                                                                                                                                                     |   "log.iostream": "stdout" |
|                         |             |                |                                                                                                                                                                     | }                          |
| 2025-06-26 00:23:38.787 |           0 | main           | job-tutorial - INFO - Connection succeeded. Current session context: database="TUTORIAL_DB", schema="DATA_SCHEMA", warehouse="TUTORIAL_WAREHOUSE", role="TEST_ROLE" | {                          |
|                         |             |                |                                                                                                                                                                     |   "log.iostream": "stdout" |
|                         |             |                |                                                                                                                                                                     | }                          |
| 2025-06-26 00:23:36.852 |           0 | main           | job-tutorial - INFO - Job started                                                                                                                                   | {                          |
|                         |             |                |                                                                                                                                                                     |   "log.iostream": "stdout" |
|                         |             |                |                                                                                                                                                                     | }                          |
+-------------------------+-------------+----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+

有关调用此方法的更多信息,请参阅 <service_name>!SPCS_GET_LOGS

使用事件表

Snowflake 可以获取从容器发送到标准输出的日志,并将标准错误流发送到为您的账户配置的事件表中。有关配置事件表的更多信息,请参阅 日志记录、跟踪和指标

您可以通过使用服务规范文件中的 spec.logExporters 字段 来控制要收集哪些流(全部、仅标准错误或无)并将其存储在事件表中。

然后您可以查询事件表中的事件。要查找账户的活动事件表,请使用 SHOW PARAMETERS 命令检查 EVENT_TABLE 参数的值:

SHOW PARAMETERS LIKE 'event_table' IN ACCOUNT;
Copy

该参数指定账户的活动事件表。

接下来,查询该事件表。以下 SELECT 语句可检索过去一小时内记录的 Snowflake 服务和作业事件:

SELECT TIMESTAMP, RESOURCE_ATTRIBUTES, RECORD_ATTRIBUTES, VALUE
FROM <current_event_table_for_your_account>
WHERE timestamp > dateadd(hour, -1, current_timestamp())
AND RESOURCE_ATTRIBUTES:"snow.service.name" = '<service_name>'
AND RECORD_TYPE = 'LOG'
ORDER BY timestamp DESC
LIMIT 10;
Copy

Snowflake 建议您在事件表查询的 WHERE 子句中包含时间戳,如本例所示。这一点尤为重要,因为各种 Snowflake 组件可能会生成大量数据。通过应用筛选器,可以检索到较小的数据子集,从而提高查询性能。

事件表包括以下列,这些列提供了有关 Snowflake 从您的容器收集的日志的有用信息:

  • TIMESTAMP: 显示 Snowflake 收集日志的时间。

  • RESOURCE_ATTRIBUTES: 提供 JSON 对象,用于标识 Snowflake 服务和生成日志消息的服务中的容器。例如,它提供了服务运行时指定的服务名称、容器名称和计算池名称等详细信息。

    {
      "snow.account.name": "SPCSDOCS1",
      "snow.compute_pool.id": 20,
      "snow.compute_pool.name": "TUTORIAL_COMPUTE_POOL",
      "snow.compute_pool.node.id": "a17e8157",
      "snow.compute_pool.node.instance_family": "CPU_X64_XS",
      "snow.database.id": 26,
      "snow.database.name": "TUTORIAL_DB",
      "snow.schema.id": 212,
      "snow.schema.name": "DATA_SCHEMA",
      "snow.service.container.instance": "0",
      "snow.service.container.name": "echo",
      "snow.service.container.run.id": "b30566",
       "snow.service.id": 114,
      "snow.service.name": "ECHO_SERVICE2",
      "snow.service.type": "Service"
    }
    
    Copy
  • RECORD_ATTRIBUTES: 对于 Snowflake 服务,它标识错误源(标准输出或标准错误)。

    { "log.iostream": "stdout" }
    
    Copy
  • VALUE: 标准输出和标准错误被分成若干行,每一行都会在事件表中生成一条记录。

    "echo-service [2023-10-23 17:52:27,429] [DEBUG] Sending response: {'data': [[0, 'Joe said hello!']]}"
    

使用 SYSTEM$GET_SERVICE_LOGS

SYSTEM$GET_SERVICE_LOGS 函数返回当前运行服务容器的日志。容器退出后,您可以使用系统函数短时间继续访问日志。系统函数在开发和测试过程中,即在最初授权服务或作业时最有用。

您需要提供服务名称、实例 ID、容器名称,还可选择提供要检索的最新日志行数。如果只有一个服务实例正在运行,则服务实例 ID 为 0。例如,以下语句命令会从名为 echo 的容器的日志中检索末尾的 10 行,该容器属于名为 echo_service 的服务的实例 0:

SELECT SYSTEM$GET_SERVICE_LOGS('echo_service', '0', 'echo', 10);
Copy

输出示例:

+--------------------------------------------------------------------------+
| SYSTEM$GET_SERVICE_LOGS                                                  |
|--------------------------------------------------------------------------|
| 10.16.6.163 - - [11/Apr/2023 21:44:03] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:08] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:13] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:18] "GET /healthcheck HTTP/1.1" 200 - |
+--------------------------------------------------------------------------+
1 Row(s) produced. Time Elapsed: 0.878s

如果没有调用该函数所需的服务相关信息(如实例 ID 或容器名称),您可以先运行 SHOW SERVICE CONTAINERS IN SERVICE 命令获取每个实例中运行的服务实例和容器的相关信息。

SYSTEM$GET_SERVICE_LOGS 函数有以下限制:

  • 它将标准输出和标准错误流合并。该函数没有说明输出来自哪个流。

  • 它在单个服务实例中报告特定容器的捕获数据。

  • 它只报告运行中容器的日志。该函数无法从先前重新启动的容器或者已停止或已删除的服务容器中获取日志。

  • 该函数最多可返回 100 KB 数据。

访问平台指标

Snowflake 为账户中的 计算池 和在这些计算池上运行的 服务 提供指标。这些由 Snowflake 提供的指标也称为平台指标。

  • 事件表服务指标: 各个服务发布指标。这些是提供特定于服务的信息的计算池指标的子集。其目标用例是观察特定服务的资源利用率。在服务规范中,您可以定义希望 Snowflake 在服务运行时在事件表中记录哪些指标。

  • 计算池指标: 每个计算池还发布指标,提供有关该计算池内部发生情况的信息。其目标用例是观察计算池利用率。要访问计算池指标,您需要编写一个服务,该服务使用与 Prometheus 兼容的 API 来轮询计算池发布的指标。

访问事件表服务指标

要将服务指标记录到为账户配置的事件表中,请在服务规范中包含以下部分:

platformMonitor:
  metricConfig:
    groups:
    - <group 1>
    - <group 2>
    - ...
Copy

其中,每个 group N 指的是您感兴趣的 预定义指标组;例如,systemnetworkstorage。有关更多信息,请参阅服务规范文档中的 spec.platformMonitor 字段 部分。

在服务运行时,Snowflake 会将这些指标记录到账户中的事件表中。您可以使用以下方式读取这些指标:

  • 使用服务辅助方法: <service_name>!SPCS_GET_METRICS 表函数返回 Snowflake 为指定服务收集的指标。以下列表说明了使用此表函数的优点:

    • 您可以检索特定服务的指标:

    • 您可以检索指定时间范围内的指标。

    • 调用方不需要访问整个事件表,这对于具有严格信息安全要求的客户有利。

    以下 SELECT 语句使用表函数检索在过去一小时内记录的指定服务的平台事件:

    SELECT *
      FROM TABLE(echo_service!SPCS_GET_METRICS(start_time => dateadd('hour', -1, current_timestamp())));
    
    Copy
  • 直接查询事件表: 您可以查询事件表来读取指标。以下查询检索了过去一小时内为服务 my_service 记录的服务指标:

    SELECT timestamp, value
      FROM my_event_table_db.my_event_table_schema.my_event_table
      WHERE timestamp > DATEADD(hour, -1, CURRENT_TIMESTAMP())
        AND RESOURCE_ATTRIBUTES:"snow.service.name" = 'MY_SERVICE'
        AND RECORD_TYPE = 'METRIC'
        ORDER BY timestamp DESC
        LIMIT 10;
    
    Copy

    如果您不知道该账户的活动事件表的名称,请运行 SHOW PARAMETERS 命令来显示账户级别 EVENT_TABLE 参数的值:

    SHOW PARAMETERS LIKE 'event_table' IN ACCOUNT;
    
    Copy

    有关事件表的更多信息,请参阅 使用事件表

示例

要创建一个示例服务,将指标记录到为您的账户配置的事件表中,请完成以下步骤。

  1. 按照 教程 1 中的步骤创建一个名为 echo_service 的服务,但有一处变化。在第 3 步中,创建服务时,使用以下 CREATE SERVICE 命令,在修改后的服务规范中添加 platformMonitor 字段:

    CREATE SERVICE echo_service
      IN COMPUTE POOL tutorial_compute_pool
      FROM SPECIFICATION $$
        spec:
          containers:
          - name: echo
            image: /tutorial_db/data_schema/tutorial_repository/my_echo_service_image:latest
            env:
              SERVER_PORT: 8000
              CHARACTER_NAME: Bob
            readinessProbe:
              port: 8000
              path: /healthcheck
          endpoints:
          - name: echoendpoint
            port: 8000
            public: true
          platformMonitor:
            metricConfig:
              groups:
              - system
              - system_limits
          $$
        MIN_INSTANCES=1
        MAX_INSTANCES=1;
    
    Copy

服务运行后,Snowflake 开始将指定的指标组中的指标记录到事件表中。

  1. 通过调用 <service_name>!SPCS_GET_METRICS 函数或通过查询事件表来访问指标。例如,检索 echo_service 服务在过去一小时内报告的指标:

    • 使用 <service_name>!SPCS_GET_METRICS 辅助函数:

      
      
      Copy

      SELECT * FROM TABLE(echo_service!SPCS_GET_METRICS(START_TIME => DATEADD('hour', -1, CURRENT_TIMESTAMP())));

    • 直接查询事件表:

      SELECT timestamp, value
       FROM my_events
       WHERE timestamp > DATEADD(hour, -1, CURRENT_TIMESTAMP())
         AND RESOURCE_ATTRIBUTES:"snow.service.name" = 'ECHO_SERVICE'
         AND RECORD_TYPE = 'METRIC'
         AND RECORD:metric.name = 'container.cpu.usage'
         ORDER BY timestamp DESC
         LIMIT 100;
      
      Copy

访问计算池指标

计算池 指标可提供对计算池中的节点及其上运行的服务的洞察。每个节点可报告特定于节点的指标(例如容器的可用内存量),以及服务指标(例如各个容器的内存使用情况)。计算池指标从节点的角度提供信息。

每个节点都有一个指标发布器,用于监听 TCP 端口 9001。其他服务可以使用指向节点上端口 9001 的路径 /metrics 发出 HTTP GET 请求。要发现节点的 IP 地址,请从 DNS 中检索 discover.monitor.compute_pool_name.cp.spcs.internal 主机名的 SRV 记录(或 A 记录)。然后,在您的账户中创建另一项服务,用于主动轮询每个节点以检索指标。

响应中的正文使用 ` Prometheus 格式 <https://prometheus.io/docs/instrumenting/exposition_formats/#text-based-format (https://prometheus.io/docs/instrumenting/exposition_formats/#text-based-format)>`_ 提供指标,如以下示例指标所示:

# HELP node_memory_capacity Defines SPCS compute pool resource capacity on the node
# TYPE node_memory_capacity gauge
node_memory_capacity{snow_compute_pool_name="MY_POOL",snow_compute_pool_node_instance_family="CPU_X64_S",snow_compute_pool_node_id="10.244.3.8"} 1
node_cpu_capacity{snow_compute_pool_name="MY_POOL",snow_compute_pool_node_instance_family="CPU_X64_S",snow_compute_pool_node_id="10.244.3.8"} 7.21397383168e+09

请注意以下事项:

  • 响应主体以 # HELP# TYPE 开头,提供简短描述和指标类型。在本示例中,node_memory_capacity 指标类型为 gauge

  • 然后是指标的名称、描述特定资源(数据点)的标签列表及其值。在本示例中,指标(名为 node_memory_capacity)提供了内存信息,表明节点有 7.2 GB 可用内存。该指标还包括标签形式的元数据,如下所示:

    snow_compute_pool_name="MY_POOL",
    snow_compute_pool_node_instance_family="CPU_X64_S",snow_compute_pool_node_id="10.244.3.8"
    

您可以选择任何方式来处理这些指标;例如,您可以将指标存储在数据库中,然后使用 UI(例如 Grafana 仪表板)来显示信息。

备注

  • Snowflake 不提供任何指标的聚合。例如,要获取给定服务的指标,您必须查询正在运行该服务实例的所有节点。

  • 计算池必须具有与 DNS 兼容的名称,以便您访问指标。

  • 服务可以使用对计算池具有 OWNERSHIP 或 MONITOR 权限的角色,访问计算池公开的端点。

有关可用计算池指标的列表,请参阅 可用平台指标

示例

有关配置 Prometheus 以轮询计算池来获取指标的示例,请参阅 计算池指标教程 (https://github.com/Snowflake-Labs/spcs-templates/tree/main/user-metrics)。

可用平台指标

以下是可用平台指标组以及每个组内的指标的列表。请注意,当前仅从块存储卷收集 storage 指标。

指标组 . 指标名称

单位

类型

描述

system . container.cpu.usage

CPU 核心数

gauge

自上次测量以来使用的 CPU 内核的平均数。1.0 表示 1 个 CPU 内核的充分利用率。最大值是容器可用的 CPU 内核数。

system . container.memory.usage

bytes

gauge

已使用的内存(以字节为单位)。

system . container.gpu.memory.usage

bytes

gauge

已使用的每 GPU 内存(以字节为单位)。源 GPU 在“gpu”属性中表示。

system . container.gpu.utilization

比率

gauge

每个 GPU 使用率与容量的比率。源 GPU 在“gpu”属性中表示。

system_limits . container.cpu.limit

CPU 核心数

gauge

服务规范中的 CPU 资源限制。如果没有定义限制,则默认为节点容量。

system_limits . container.gpu.limit

GPU 数

gauge

服务规范中的 GPU 计数限制。如果没有定义限制,则不会发出该指标。

system_limits . container.memory.limit

bytes

gauge

服务规范的内存限制。如果没有定义限制,则默认为节点容量。

system_limits . container.cpu.requested

CPU 核心数

gauge

服务规范中的 CPU 资源请求。如果没有定义限制,则默认为 Snowflake 选择的值。

system_limits . container.gpu.requested

GPU 数

gauge

服务规范中的 GPU 计数。如果没有定义限制,则不会发出该指标。

system_limits . container.memory.requested

bytes

gauge

服务规范中的内存请求。如果没有定义限制,则默认为 Snowflake 选择的值。

system_limits . container.gpu.memory.capacity

bytes

gauge

每 GPU 内存容量。源 GPU 在“gpu”属性中表示。

status . container.restarts

重启次数

gauge

Snowflake 重新启动容器的次数。

status . container.state.finished

布尔

gauge

当容器处于“完成”状态时,该指标将以值 1 发出。

status . container.state.last.finished.reason

布尔

gauge

如果容器之前已经重启过,该指标将以值 1 发出。“原因”标签描述了容器上次完成的原因。

status . container.state.last.finished.exitcode

整数

gauge

如果容器之前已经重启过,则该指标将包含上次运行的退出代码。

status . container.state.pending

布尔

gauge

当容器处于“待处理”状态时,该指标将以值 1 发出。

status . container.state.pending.reason

布尔

gauge

当容器处于“待处理”状态时,该指标将以值 1 发出。“原因”标签描述了容器最近处于待处理状态的原因。

status . container.state.running

布尔

gauge

当容器处于“正在运行”状态时,该指标的值为 1。

status . container.state.started

布尔

gauge

当容器处于“已启动”状态时,该指标的值为 1。

network . network.egress.denied.packets

数据包数

gauge

Network egress total denied packets from service instance due to policy validation failures.

network . network.egress.received.bytes

bytes

gauge

Network egress total bytes received by service instance from remote destinations.

network . network.egress.received.packets

数据包数

gauge

Network egress total packets received by service instance from remote destinations.

network . network.egress.transmitted.bytes

字节

gauge

Network egress total bytes transmitted by service instance out to remote destinations.

network . network.egress.transmitted.packets

数据包数

gauge

Network egress total packets transmitted by service instance out to remote destinations.

network . network.ingress.connections.active

connections

gauge

Number of active ingress connections for this endpoint. This metric includes the resource attribute snow.endpoint.name to determine the value per endpoint.

network . network.ingress.cps

connections/sec

gauge

Number of ingress connections to this endpoint per second. This metric includes the resource attribute snow.endpoint.name to help you to determine the value per endpoint.

storage . volume.capacity

bytes

gauge

Size of the filesystem. The target volume is denoted in the volume_name attribute.

storage . volume.io.inflight

操作数

gauge

Number of active filesystem I/O operations at current instant. The target volume is denoted in the volume_name attribute.

storage . volume.read.throughput

字节/秒

gauge

Filesystem reads throughput in bytes per second since last measurement. The target volume is denoted in the volume_name attribute.

storage . volume.read.iops

操作数/秒

gauge

Filesystem read operations per second since last measurement. The target volume is denoted in the volume_name attribute

storage . volume.usage

bytes

gauge

Total number of bytes used in the filesystem since last measurement. The target volume is denoted in the volume_name attribute.

storage . volume.write.throughput

字节/秒

gauge

Filesystem write throughput in bytes per second since last measurement. The target volume is denoted in the volume_name attribute.

storage . volume.write.iops

操作数/秒

gauge

Filesystem write operations per second since last measurement. The target volume is denoted in the volume_name attribute.

发布和访问应用程序指标

与 Snowflake 生成的平台指标不同,应用程序指标和跟踪由您的服务生成。您的服务容器可以生成 OLTP 或 Prometheus 指标,Snowflake 会将这些指标发布到为您的账户配置的事件表中。

请注意,您应确保您的服务容器代码输出具有正确单位、聚合和仪表化类型的指标,以生成对您的分析有意义且有效的指标。

发布 OTLP 应用程序指标和跟踪

Snowflake 会运行一个 OTel 收集器,您的服务容器可使用该收集器发布 OTLP 应用程序指标和跟踪。也就是说,服务容器可以将指标推送到 OTel 收集器端点,然后 Snowflake 会将这些指标连同源服务详细信息写入为您的 Snowflake 账户配置的事件表中。

它的工作原理如下:

  • Snowflake 会在您的服务容器中自动填充以下环境变量,这些变量提供了 OTel 收集器端点,容器可以在这些端点上发布应用程序指标和跟踪。

    • OTEL_EXPORTER_OTLP_METRICS_ENDPOINT

    • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT

  • 标准 OTLP 客户端 (https://opentelemetry.io/docs/languages/) 会查找这些环境变量,以自动发现 OTel 收集器。这样,您的服务容器就可以使用此客户端发布指标和跟踪。

配置 OTLP 应用程序跟踪 IDs

跟踪必须使用 Snowflake Trace ID 格式,以便在 Snowflake Trail 中查看,并允许执行查找。

Snowflake 提供 Python 和 Java 库,以简化跟踪 ID 生成器的设置。以下示例展示了如何使用这些库覆盖默认的 OpenTelemetry 跟踪 ID 生成器。

from opentelemetry.sdk.trace import TracerProvider
from snowflake.telemetry.trace import SnowflakeTraceIdGenerator


trace_id_generator = SnowflakeTraceIdGenerator()
tracer_provider = TracerProvider(
    resource=Resource.create({"service.name": SERVICE_NAME}),
    id_generator=trace_id_generator
)
Copy

有关更多信息,请参阅 PyPI 上的 snowflake-telemetry-python (https://pypi.org/project/snowflake-telemetry-python/)。

import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import com.snowflake.telemetry.trace.SnowflakeTraceIdGenerator;

static OpenTelemetry initOpenTelemetry() {
  return AutoConfiguredOpenTelemetrySdk.builder()
      .addPropertiesSupplier(
          () ->
              Map.of(...config options...)
      .addTracerProviderCustomizer(
          (tracerProviderBuilder, configProperties) -> {
            tracerProviderBuilder.setIdGenerator(SnowflakeTraceIdGenerator.INSTANCE);
            return tracerProviderBuilder;
          })
      .build()
      .getOpenTelemetrySdk();
Copy

有关安装 com.snowflake.telemetry 的更多信息,请参阅 设置 Java 和 Scala 环境以使用遥测类

跟踪 ID 生成器也可用于任何其他编程语言。16 字节 ID(大端序)的最高四个字节必须包含一个时间戳。其他字节应包含随机位。有关更多信息,请参阅 Python 参考实施 (https://github.com/snowflakedb/snowflake-telemetry-python/blob/0c5b4faf024997d993f7cd1d00e6ae0cb0bb7d08/src/snowflake/telemetry/trace/__init__.py#L14)。

发布 Prometheus 应用程序指标

Snowflake 支持 Prometheus 指标,其中,您的应用程序可能会暴露 Prometheus 指标,由 Snowflake 提供的收集器进行轮询,而不是推送 OTLP 指标。为了让 Snowflake 从您的服务收集应用程序指标并将其发布到事件表,请执行以下步骤:

  • 让您的服务监听一个端口,以暴露 Prometheus 指标。

  • 在您的服务中包含一个 Snowflake 提供的容器(也称为“sidecar”容器),并进行必要的配置,以从您的服务容器中拉取指标。

Prometheus sidecar 容器按计划频率从服务容器中拉取应用程序指标,将 Prometheus 格式转换为 OTLP 格式,并将指标推送到 OTel 收集器。然后,OTel 收集器会将这些指标发布到为您的 Snowflake 账户配置的事件表中。

备注

Snowflake 不支持 Prometheus 摘要 指标类型 (https://prometheus.io/docs/concepts/metric_types/),因为`已被 OpenTelemetry <https://opentelemetry.io/docs/specs/otel/metrics/data-model/#summary-legacy (https://opentelemetry.io/docs/specs/otel/metrics/data-model/#summary-legacy)>`_ 弃用。改用直方图类型。

您将 Prometheus sidecar 容器作为另一个容器添加到服务规范中,并包括一个参数来指定您的容器暴露的 HTTP 端点,格式如下:

localhost:{PORT}/{METRICS_PATH}, {SCRAPE_FREQUENCY}

它指定了端口号、路径以及 sidecar 容器应当拉取指标的频率。

下面是一个示例服务规范片段,展示了 sidecar 容器每分钟从端口 8000 拉取服务容器的指标,并从路径“/metrics”拉取指标:

spec:
  containers:
  - name: <name>
    image: <image-name>
    .....
  - name: prometheus
    image: /snowflake/images/snowflake_images/monitoring-prometheus-sidecar:0.0.1
    args:
      - "-e"
      - "localhost:8000/metrics,1m"
Copy

在规范中:

  • image 是 Snowflake 提供的 sidecar 容器映像。

  • args 提供必要配置以使 Prometheus 容器抓取指标:

    • 从容器提供的端口 8000。在此 Prometheus 容器配置中,端口是必填项。

    • 使用路径“/metrics”。这是可选项。如果未指定,默认路径为“/metrics”。

    • 每一分钟。这是可选项。如果未指定,则默认值为“1m”。

    如果使用默认值,抓取指标的配置等效于以下内容:

    spec:
        ...
        args:
          - "-e"
          - "localhost:8000"
    
    Copy

备注

Prometheus sidecar 容器只支持服务(不支持作业)。如果要收集作业的应用程序指标,必须将指标推送到 OTel 收集器。

访问事件表中的应用程序指标和跟踪

您可以查询事件表来检索应用程序指标。以下查询可用于检索过去一小时内收集的应用程序指标。

SELECT timestamp, record:metric.name, value
  FROM <current_event_table_for_your_account>
  WHERE timestamp > dateadd(hour, -1, CURRENT_TIMESTAMP())
    AND resource_attributes:"snow.service.name" = <service_name>
    AND scope:"name" != 'snow.spcs.platform'
    AND record_type = 'METRIC'
  ORDER BY timestamp DESC
  LIMIT 10;
Copy

有关事件表的更多信息,请参阅 事件表概述。这些指标可以在 Snowflake 仪表板 中直观显示。

您还可以查询事件表,以查看应用程序跟踪。例如,要检索过去一小时内的应用程序跟踪,可替换前述查询中的 record_type 条件,如下所示:

AND record_type = 'SPAN' OR record_type = 'SPAN_EVENT'
Copy

这些跟踪可以在 `Snowflake trail<https://www.snowflake.com/en/data-cloud/snowflake-trail/>`__ 查看器中直观显示。

指标和跟踪包含用户定义和 Snowflake 定义的属性,这些属性被划分为资源和记录属性。请注意,snow. 前缀是为 Snowflake 生成的属性保留的,Snowflake 会忽略使用此前缀的自定义属性。要查看 Snowflake 定义属性的列表,请参阅 可用平台指标

提供了 示例代码 (https://github.com/Snowflake-Labs/spcs-templates/tree/main/application-observability),分别使用 Python 和 Java 展示了如何使用 OTLP SDK 为应用程序添加自定义指标和跟踪。示例展示了如何配置 Snowflake Trace ID 生成,以便与用于跟踪的 Snowflake 跟踪查看器兼容。

访问平台事件

Snowflake 记录事件,让您可以查看服务的状态和历史记录。这些 Snowflake 提供的事件被称为 平台事件

例如,如果您的服务容器当前正在运行,但前一天由于致命错误(例如内存不足情况)而重新启动,则可以使用平台事件来查看此历史事件。

Snowflake 将这些平台事件记录到您账户的 事件表 中。默认情况下,不记录平台事件。要启用平台事件的日志记录,请在创建资源时(例如,运行 CREATE SERVICE 时)设置 LOG_LEVEL 参数,或使用 ALTER 语句更新现有资源的日志级别。

备注

如果未在资源级别设置 LOG_LEVEL 参数,Snowflake 可以继承在更高级别设置的参数值。对于服务,Snowflake 可以继承在架构、数据库或服务账户上设置的 LOG_LEVEL 参数值。有关更多信息,请参阅 Snowflake 如何确定有效级别

您可以通过运行 SHOW PARAMETERS ... IN SERVICE 来检查为服务设置的当前日志级别:

SHOW PARAMETERS LIKE 'LOG_LEVEL' IN SERVICE mydb.myschema.myservice;
Copy

LOG_LEVEL 参数的值决定了要记录在事件表中的事件的严重性。在当前实施中,支持的 LOG_LEVEL 值为:INFOERROR

  • 如果只想在事件表中记录 ERROR 事件,请将 LOG_LEVEL 设置为 ERROR

  • 如果要将 INFOERROR 事件记录在事件表中,请将 LOG_LEVEL 设置为 INFO

  • 如果要停止在事件表中记录平台事件,请将 LOG_LEVEL 设置为 OFF

有关更多信息,请参阅 设置遥测级别

查询平台事件

配置资源的日志级别后,Snowflake 会将平台事件记录到您 Snowflake 账户的活动事件表中。您可以通过以下方式访问这些事件:

  • 使用服务辅助方法: <service_name>!SPCS_GET_EVENTS 表函数返回 Snowflake 从指定服务的容器中收集的事件。

    以下列表说明了使用此表函数的优点:

    • 您可以检索特定服务的事件。

    • 您可以检索指定时间范围内的事件。

    • 调用方不需要访问整个事件表,这对于具有严格信息安全要求的客户有利。

    以下 SELECT 语句使用表函数检索在过去一小时内记录的指定服务的平台事件:

    SELECT *
    FROM TABLE(echo_service!SPCS_GET_EVENTS(START_TIME => DATEADD('hour', -1, CURRENT_TIMESTAMP())));
    
    Copy
  • 直接使用事件表: 您可以直接查询事件表。要查找账户的活动事件表,请使用 SHOW PARAMETERS 命令检查 EVENT_TABLE 参数的值:

    SHOW PARAMETERS LIKE 'event_table' IN ACCOUNT;
    
    Copy

    该参数指定账户的活动事件表。

    接下来,查询该事件表。以下 SELECT 语句检索在过去一小时内记录的指定服务的平台事件:

    SELECT TIMESTAMP, RESOURCE_ATTRIBUTES, RECORD, VALUE
      FROM <your_event_table>
      WHERE TIMESTAMP > DATEADD(hour, -1, CURRENT_TIMESTAMP())
        AND RESOURCE_ATTRIBUTES:"snow.service.name" = '<your_service_name>'
        AND RECORD_TYPE = 'EVENT'
        AND SCOPE:"name" = 'snow.spcs.platform'
      ORDER BY TIMESTAMP DESC
      LIMIT 10;
    
    Copy

    有关事件表的更多信息,请参阅 使用事件表

    事件表中的以下列提供了有关平台事件的有用信息:

    • TIMESTAMP: 显示 Snowflake 记录日志的时间。

    • RESOURCE_ATTRIBUTES: 为 JSON 对象提供有关事件源的元数据,例如服务、容器或计算池。resource_attribute 列中的以下值示例标识了记录事件的特定服务

      {
        "snow.compute_pool.name": "TUTORIAL_COMPUTE_POOL",
        "snow.compute_pool.id": 123,
        "snow.database.name": "TUTORIAL_DB",
        "snow.database.id": 456,
        "snow.schema.name": "DATA_SCHEMA",
        "snow.schema.id": 789,
        "snow.service.container.name": "echo",
        "snow.service.name": "ECHO_SERVICE2",
        "snow.service.id": 212,
        "snow.service.type": "Service"
      }
      
      Copy
    • SCOPE: 表示事件的起源。对于平台事件,范围的名称为 snow.spcs.platform,如以下示例所示:

      { "name": "snow.spcs.platform" }
      
      Copy
    • RECORD_TYPE: 对于平台事件,EVENT 是 RECORD_TYPE。

    • RECORD: 提供有关特定事件的元数据。以下元数据显示平台事件的名称和严重性级别:

      { "name": "CONTAINER.STATUS_CHANGE", "severity_text": "INFO" }
      
      Copy
    • VALUE: 提供事件详细信息。以下示例显示了容器状态和有关容器状态的消息:

      { "message": "Running", "status": "READY" }
      
      Copy

支持的事件

目前,Snowflake 仅支持容器状态变更事件。

下表列出了 Snowflake 记录的平台事件。列名称中的 RECORDVALUE 指的是事件表中的列(在上一节中进行了说明)。

RECORD:name

RECORD:severity_text

VALUE:message

VALUE:status

CONTAINER.STATUS_CHANGE

INFO

正在运行

READY

CONTAINER.STATUS_CHANGE

INFO

路径 <path>、端口 <port> 处的就绪情况探测失败

PENDING

CONTAINER.STATUS_CHANGE

INFO

等待开始

PENDING

CONTAINER.STATUS_CHANGE

INFO

正在配置计算池节点

PENDING

CONTAINER.STATUS_CHANGE

ERROR

无法提取图像

PENDING

CONTAINER.STATUS_CHANGE

ERROR

提供的图像名称使用了无效的格式

FAILED

CONTAINER.STATUS_CHANGE

ERROR

遇到致命错误,正在重试

FAILED

CONTAINER.STATUS_CHANGE

ERROR

遇到致命错误

FAILED

CONTAINER.STATUS_CHANGE

ERROR

运行时遇到致命错误,请查看容器日志

FAILED

CONTAINER.STATUS_CHANGE

ERROR

由于资源使用情况,容器 OOMKilled

FAILED

CONTAINER.STATUS_CHANGE

ERROR

用户应用程序错误,请查看容器日志

FAILED

CONTAINER.STATUS_CHANGE

ERROR

启动容器时遇到致命错误

FAILED

CONTAINER.STATUS_CHANGE

INFO

成功完成

DONE

准则和限制

  • 对于 AWS 和 Azure 上的 Snowflake 账户,向事件表引入的日志的最大吞吐量为每节点 1 MB/秒。

  • 对于 Azure 和 AWS,向事件表引入的指标和跟踪的最大合并吞吐量为每节点 1 MB/秒。

  • 引入事件表的日志的最大记录大小为 16 KiB。

语言: 中文