You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数据提供方如何统计Snowflake共享安全UDF调用时的输出表规模

Snowflake 共享UDTF细粒度用量统计方案

原生能力边界

Snowflake 自带的共享使用审计能力只能到查询维度,做不到单UDTF调用的细粒度统计:

  • 你可以在提供方账号的SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY视图里,查到所有消费者账号发起的、调用你共享安全函数的查询记录,能拿到整个查询的返回行数、执行时长、消费者账号ID、执行时间等信息,但如果单条查询里多次调用你的UDTF,原生视图无法拆分出每次UDTF调用单独的输出行数。
  • 原生审计日志不会记录UDTF的入参值,没法直接统计输入参数的规模。

自定义实现细粒度统计的可行方案

安全UDTF的执行逻辑完全运行在提供方的计算上下文里,消费者看不到函数实现细节,你可以通过改写UDTF为支持自定义处理逻辑的多语言UDTF(Python/Java/Scala均可),结合Snowflake原生的事件日志能力实现统计,全程不需要消费者做任何配置,统计数据只有提供方能访问。

实现步骤

  1. 首次配置需要先在你的提供方账号创建事件表,用来存储UDTF运行时输出的日志,消费者完全没有该表的访问权限:
-- 仅需执行一次
CREATE EVENT TABLE IF NOT EXISTS <DB>.<SCHEMA>.UDTF_USAGE_EVENTS;
ALTER ACCOUNT SET EVENT_TABLE = <DB>.<SCHEMA>.UDTF_USAGE_EVENTS;
  1. 将你原来的SQL UDTF改写为Python安全UDTF,在处理逻辑里累计返回行数、记录入参,在单轮调用结束时把统计信息写入日志:
CREATE OR REPLACE SECURE FUNCTION CLIENT_ACCESS
    (INPUT_RECORDID STRING, INPUT_LOOKUP INTEGER)
    RETURNS TABLE
    (RECORDID STRING, LOOKUP INTEGER, SENSITIVE_DATA STRING)
LANGUAGE PYTHON
RUNTIME_VERSION = '3.10'
HANDLER = 'AccessUDTF'
PACKAGES = ('snowflake-snowpark-python')
EXECUTE AS OWNER
AS
$$
import logging
logger = logging.getLogger("udtf_usage_tracker")

class AccessUDTF:
    def __init__(self):
        self.row_count = 0
        self.param_recordid = None
        self.param_lookup = None

    def process(self, INPUT_RECORDID, INPUT_LOOKUP):
        # 记录入参
        self.param_recordid = INPUT_RECORDID
        self.param_lookup = INPUT_LOOKUP
        # 替换为你实际的业务查询逻辑
        res = session.sql("""
            SELECT 
                %s AS RECORDID,
                LOOKUP,
                SENSITIVE_DATA
            FROM <DB>.<SCHEMA>.SHARED_DATA
            WHERE LOOKUP = %s
        """, (INPUT_RECORDID, INPUT_LOOKUP)).collect()
        # 逐行返回结果并计数
        for row in res:
            self.row_count += 1
            yield (row.RECORDID, row.LOOKUP, row.SENSITIVE_DATA)

    def end_partition(self):
        # 单轮调用结束,写入统计日志
        logger.info(f"CALL_STAT|input_recordid={self.param_recordid}|input_lookup={self.param_lookup}|return_rows={self.row_count}")
$$;
  1. 后续你只需要定时查询UDTF_USAGE_EVENTS表,解析日志字段就能拿到每一次UDTF调用对应的入参值、返回行数,还可以结合日志里自带的调用时间、会话信息关联出消费者账号、调用IP等信息,完全满足你要的统计粒度。

注意事项

  • Snowflake禁止UDF/UDTF执行DML修改数据,不要尝试在UDTF内直接执行INSERT语句写入统计表,会直接抛出运行时错误,事件表日志是官方支持的合法副作用输出方式。
  • 如果你更熟悉Java/Scala,也可以用对应语言实现UDTF,逻辑完全一致,都是在分区处理的终结阶段输出统计日志。
  • 如果需要区分不同消费者的调用,可以在process方法里查询CURRENT_ACCOUNT()、CURRENT_ROLE()等上下文函数,把对应信息一起打到日志里即可。
  • 如果需要实时统计,可以给事件表配置Snowpipe Stream和定时任务,自动解析日志写入结构化的用量统计表,直接对接可视化看板即可。
  • 因为是安全UDTF,所有统计逻辑对消费者完全不可见,不存在被绕过的风险。

内容的提问来源于stack exchange,提问作者ConnorOSully

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 12:12:21