Python 业务参数提取

更新时间:
复制 MD 格式

排查 Python 应用调用链路问题时,业务参数是快速定位根因和追踪请求信息的关键。ARMS 支持通过控制台配置提取规则,无侵入地将 HTTP 请求和响应中的指定参数写入 Span Attributes,还可配置自定义错误规则将匹配的 Span 标记为错误。

前提条件

  • 已为 Python 应用接入 ARMS Python 探针。

  • Python 探针版本不低于 3.1.0

支持范围说明

业务参数提取规则对框架和实际用法有一定要求。Python 版支持的参数提取类型和来源如下:

参数提取类型

参数提取来源

支持的框架

备注

HTTP 服务端请求

Header、Query Parameter、Cookie、Body

Flask、Django、FastAPI

Body 需为 JSON 格式,详见常见问题

HTTP 服务端响应

Header、Body、Cookie

Flask、Django、FastAPI

Body 需为 JSON 格式;Cookie 来源读取的是请求侧 Cookie。

HTTP 客户端请求

Header、Query Parameter

requests、httpx、aiohttp、urllib3

客户端不支持 Body、Cookie 来源。

HTTP 客户端响应

Header

requests、httpx、aiohttp、urllib3

-

如果需要提取的参数来源超出上述支持范围,可通过引入 OpenTelemetry SDK 添加自定义埋点,将业务参数作为 Attributes 写入 Span。

功能入口

  1. 登录 ARMS 控制台

  2. 在左侧导航栏选择应用监控 > 应用列表,在顶部菜单栏选择目标地域,然后单击目标 Python 应用的名称。

  3. 在左侧导航栏单击应用设置,然后单击自定义参数页签。

    • 业务参数提取规则区域,可以创建、查看和修改当前应用的业务参数提取规则。ARMS 探针会动态识别规则变化,并依照所有已启用的规则将业务参数提取出来。

    • 自定义错误设置区域,可以配置自定义错误规则,对提取出来的业务参数值进行匹配,命中后将对应 Span 标记为错误。

新增提取规则

重要

首次创建提取规则需要重启应用使功能生效。后续新增或修改规则无需重启,规则通过探针的配置热更新动态下发,预计 1~2 分钟后开始生效。

业务参数提取规则区域,按以下步骤创建提取规则:

  1. 单击新增规则

  2. 填写规则名称Attribute名称

  3. 选择参数提取类型,并配置生效接口,指定规则作用的接口范围。

  4. 参数提取规则区域,添加参数来源并配置参数处理步骤。支持配置多个参数来源和处理步骤,若多个来源均可提取到参数,排序在前的优先级更高。

  5. 设置是否启用,然后单击保存

规则创建完成并启用后将实时下发至客户端探针侧。业务参数提取后将记录至对应调用链 Span 的 Attributes,可在调用链分析页面按需筛选查询。Attribute 名称默认具有 biz. 前缀,不允许重复。

规则配置说明

参数

说明

规则名称

该条规则的可读名称。

Attribute名称

提取值对应的 Span Attribute 名称,默认以 biz. 开头,后续由多个单词组成,每个单词仅允许由大小写字母、数字、短划线(-)、下划线(_)组成,单词与单词之间必须以一个半角句号(.)分隔。最多允许 10 个单词。

参数提取类型

需要提取的参数类型(HTTP服务端请求/HTTP服务端响应/HTTP客户端请求/HTTP客户端响应)。

生效接口

规则作用的接口范围,探针仅对匹配成功的接口提取相应参数,匹配语义详见生效接口如何匹配。支持的匹配方式:等于、开始于、结束于、正则匹配、所有接口。

参数提取规则

定义待提取参数所在的实际载体来源和提取后的处理方式,支持配置多个参数来源和提取步骤。若多个来源均可提取到参数,排序在前的参数提取规则优先级高于后者。

参数来源

待提取参数所在的实际载体来源(Header、Query Parameter、Cookie、Body)。参数来源根据所选参数提取类型联动过滤可选项。

参数处理步骤

流式的参数处理步骤,用于逐步解析参数载体并提取最终的参数值。可添加多条参数处理步骤,前者的解析结果会成为后者的输入。如果不添加处理步骤,则提取到的参数值为载体对象的 JSON 文本。

是否启用

该条规则是否启用。

参数处理方式

Python 版支持的参数处理方式如下:

参数处理方式

输入

输出

说明

JsonPath

JSON 字符串 / JSON 对象

String

支持点表示法的 JsonPath 语句,命中多个值时取第一个。示例:$.data.code

Regex

String

String

支持基于命名分组的正则表达式语句,待提取的子串对应名为 res 的分组,采用全匹配语义(正则需匹配完整输入,而非子串搜索)。示例:.*from:(?<res>[a-z]+).*

生效接口如何匹配

生效接口匹配的对象是 Span 名称,格式为 请求方法 路由,例如 POST /api/orderGET /api/user/{id}。因此:

  • 等于 /api/order不会命中,应配置为 等于 POST /api/order

  • 或使用 以 /api/order 结尾

  • 或使用正则 .*/api/order(正则同样为全匹配语义)。

值处理说明

  • 截断:提取值超过最大长度限制(默认 100 字符)会被截断并以 ... 结尾。若需要提取较长的 Body 字段,请调大提取值长度限制。

  • 多值合并:同名 Header/Query Parameter 存在多个值时,会合并为 [a,b,c] 形式的字符串。

  • 脱敏:开启脱敏后,提取值统一替换为 ***

  • Cookie:同名 Cookie 以最后一个值为准;响应阶段的 Cookie 来源读取的是请求侧的 Cookie。

生效验证

参数提取规则配置完成后即可生效(首次创建规则除外,需重启应用后生效)。在调用链分析页面查看相关调用链,如果对应接口的 Span Attributes 已有自定义 Attribute 被写入,说明提取规则生效。

  1. 找到新增规则对应的 Attribute 名称。

  2. 在调用链分析页面添加 attributes.$attributesName 作为查询条件,过滤相关 Span。

  3. 单击任意一条 Trace,在对应的 Span 下查看自定义的 Attributes。

管理规则

  • 启用/禁用规则:在目标规则右侧设置是否启用开关。

  • 编辑和删除:在目标规则右侧单击编辑删除,修改或删除对应规则。

  • 批量删除:选中需要删除的提取规则,单击批量删除

  • 批量复制:选中需要复制的提取规则,单击批量复制至其他应用,打开对话框后选择复制到其他所有应用或指定应用。

    • 批量复制至其他应用需要 1~2 分钟生效。

    • 该功能仅复制参数提取规则,配套的自定义错误不会被复制到目标应用。

    • 参数提取规则要求 Attribute 名称唯一,如果目标应用已存在同样的 Attribute 名称,则该条规则不会被复制到目标应用。

常见问题

什么情况下会导致参数提取失败?

  • 参数提取类型或来源超出支持范围(例如客户端的 Body/Cookie 来源),请参见支持范围说明确认当前框架和来源是否支持。

  • 生效接口的匹配规则配置有误。注意匹配对象为 请求方法 路由 格式的 Span 名称,等于 /api/order 形式的规则不会命中,请参见生效接口如何匹配

  • 参数处理步骤的语法配置有误,或输入类型与处理方式的要求不匹配:

    • Regex 必须包含名为 res 的命名分组,且为全匹配语义。如需匹配子串,应在两侧补充 .*

    • JsonPath 的输入必须是 JSON 对象或 JSON 文本;对普通字符串(如 Header 值 abc)执行 JsonPath 不会产出结果。

  • Python 探针版本低于 3.1.0,不支持业务参数提取功能。

  • 首次创建规则后未重启应用。

什么情况下会导致 Body 提取不到?

为了保证不影响应用自身对请求/响应体的读取,探针在读取 Body 前会先做准入检查,以下任一条件不满足时,Body 来源会被整体跳过(不会截断后解析):

  • Content-Type 不是 JSON。仅支持 application/json 或以 +json 结尾的媒体类型;text/plainapplication/x-www-form-urlencodedmultipart/form-data、二进制等类型不会提取。

  • Content-Length 缺失或超限。请求头中没有 Content-Length(例如 chunked 分块传输),或 Body 长度超过上限(默认 64 KB)时整体跳过。

  • Body 不是合法的 UTF-8 编码 JSON。解码或 JSON 解析失败时跳过。

  • 流式响应。Flask 的流式/direct_passthrough 响应、Django 的 StreamingHttpResponse、FastAPI/Starlette 的 StreamingResponse(含 SSE)均不提取响应 Body。

此外还有各框架特有的情况:

  • FastAPI:请求 Body 只有在应用侧实际读取时才可见——即接口声明了 Body 参数(如 Pydantic 模型、Body()),或代码中调用了 await request.body() / await request.json()。如果接口没有读取请求体,探针不会主动消费请求流,Body 也就无法提取。

  • Django:如果应用先通过 request.read() 等方式直接消费了请求流(触发 RawPostDataException),或 Body 超过 Django 的 DATA_UPLOAD_MAX_MEMORY_SIZE 限制(触发 RequestDataTooBig),Body 无法提取。正常通过 request.body 读取不受影响(Django 会缓存,应用仍可正常读取)。

  • Flask:探针通过 request.get_data(cache=True) 读取并缓存请求体,应用后续仍可正常读取,一般无额外限制。

提取到的值和预期不一致?

  • 值以 ... 结尾:超过提取值长度限制(默认 100 字符)被截断,可调大长度限制。

  • 值为 ***:该规则或全局开启了脱敏。

  • 值形如 [a,b]:同名 Header/Query Parameter 存在多个值时的合并结果。

  • JsonPath 命中多个节点时只取第一个结果。

  • 多个规则写入了相同的 Attribute 名称时,后应用的规则会覆盖前者。

请求 Body 是 form 表单,能否用 Query Parameter 来源提取表单字段?

不能。当请求的 Content-Typeapplication/x-www-form-urlencoded 时,为避免探针触发框架的表单解析、影响应用自身读取请求体,Query Parameter 来源会被整体跳过。此类参数建议改为通过 URL 查询串或 Header 传递,或参考下一条使用自定义埋点。

Python 版目前不支持的业务参数来源如何提取?

可通过引入 OpenTelemetry SDK 为 Python 应用添加自定义埋点,将业务参数作为 Attributes 写入 Span。