Prometheus 中的 UTF-8
简介
Prometheus 3.0 之前的版本要求度量指标和标签名称遵循严格的字符集要求。从 Prometheus 3.0 开始,所有 UTF-8 字符串都是有效名称,但生态系统的其他部分需要进行一些手动更改才能引入包含任意 UTF-8 字符的名称。
在某些情况下,用户可能希望强制使用传统字符集,这可能是为了与不支持 UTF-8 的旧版 Prometheus 或其他抓取器兼容。
本文档将引导您了解 UTF-8 过渡的详细信息。
Go 语言埋点
目前,Prometheus 官方 client_golang 库 创建的度量指标默认会拒绝 UTF-8 名称。需要更改默认验证方案以允许 UTF-8。在未来的通用库版本中,设置此值的要求将被移除。
import "github.com/prometheus/common/model"
func init() {
model.NameValidationScheme = model.UTF8Validation
}
如果用户希望强制使用传统字符集,可以将验证方案设置为 LegacyValidation
。
验证方案的设置必须在度量指标实例化之前完成,并且如果需要,可以动态设置。
其他语言的埋点
其他客户端库可能也有类似的设置验证方案的要求。请查阅您正在使用的库的文档。
抓取期间配置名称验证
默认情况下,Prometheus 3.0 接受所有 UTF-8 字符串作为有效的度量指标和标签名称。可以为抓取目标覆盖此行为,并拒绝不符合传统字符集的名称。
此选项可以在 Prometheus YAML 文件中全局设置
global:
metric_name_validation_scheme: legacy
或者根据每个抓取配置进行设置
scrape_configs:
- job_name: prometheus
metric_name_validation_scheme: legacy
抓取配置设置将覆盖全局设置。
UTF-8 转义的抓取内容协商
在抓取时,抓取系统必须在 Accept 头中传递 escaping=allow-utf-8
,才能接收到 UTF-8 名称。如果抓取目标未看到此头,它将自动使用下划线替换将 UTF-8 名称转换为传统兼容格式。
如果需要,Prometheus 和兼容的抓取系统也可以通过将 escaping
头设置为不同的值来请求特定的转义方法。
underscores
: 默认值:将传统上无效的字符转换为下划线。dots
: 类似于 UnderscoreEscaping,但点会被转换为_dot_
,而预先存在的下划线会被转换为__
。这允许包含点的简单度量指标名称进行往返转换。values
: 此模式会在名称前加上U__
,并将所有无效字符替换为被下划线包围的 Unicode 值。单个下划线会被替换为双下划线。此模式允许 UTF-8 名称与传统 Prometheus 进行完整的往返转换。
在内容协商中宣布支持 UTF-8 表示 Prometheus 能够接收 UTF-8 字符,但并不要求度量指标名称包含以前不支持的字符。同样,宣称支持 UTF-8 的 Accept 头也不要求度量指标生成器禁用其端的名称转换。精确的名称转换策略选择取决于度量指标生成器。要求是当 Prometheus 请求除 allow-utf-8 之外的转义方案时,生成器以所请求的方式转换名称。
远程写入 2.0
远程写入 2.0 在 Prometheus 3.0 中自动接受所有 UTF-8 名称。远程写入 2.0 无法强制执行传统字符集验证。
OTLP 度量指标
Prometheus 3.0 中的 OTLP 接收器默认仍将所有名称规范化为 Prometheus 格式。您可以在 Prometheus 配置的 otlp
部分中按如下方式更改此设置
otlp:
# Ingest OTLP data keeping UTF-8 characters in metric/label names.
translation_strategy: NoUTF8EscapingWithSuffixes
有关更多详细信息,请参阅OpenTelemetry 指南。
查询
查询带 UTF-8 名称的度量指标需要在 PromQL 中使用稍微不同的语法。
经典查询语法仍适用于传统兼容名称
my_metric{}
但 UTF-8 名称必须加引号并移至花括号内
{"my.metric"}
如果标签名称包含传统不兼容字符,也必须加引号
{"metric.name", "my.label.name"="bar"}
度量指标名称可以出现在花括号内的任何位置,但样式偏好它作为第一个术语。