Prometheus 中的 UTF-8
简介
Prometheus 3.0 之前的版本要求指标和标签名称必须遵守严格的字符要求。在 Prometheus 3.0 中,所有 UTF-8 字符串均为合法的名称,但为了在生态系统的其他部分引入包含任意 UTF-8 字符的名称,可能需要进行一些手动更改。
在某些情况下,用户可能希望强制使用传统的字符集,例如为了兼容旧版本的 Prometheus 或其他尚不支持 UTF-8 的抓取程序。
本文档将引导您了解有关 UTF-8 过渡的详细信息。
Go 语言埋点
目前,由官方 Prometheus client_golang 库 创建的指标默认接受 UTF-8 名称。
之前,文档建议用户覆盖 model.NameValidationScheme 的值,以默认选择传统验证。该布尔值现已弃用,应始终设置为 UTF8Validation。如果需要强制执行传统验证,应由个别实现调用相应的验证 API,这不再是一个库功能。
其他语言的埋点
其他客户端库可能尚不支持 UTF-8,并且可能需要特殊的处理或配置。请查看您所使用库的文档。
配置抓取期间的名称验证
默认情况下,Prometheus 3.0 接受所有 UTF-8 字符串作为有效的指标和标签名称。您可以为抓取的目标覆盖此行为,并拒绝不符合传统字符集的名称。
此选项可以在 Prometheus YAML 文件中进行全局设置
global:
metric_name_validation_scheme: legacy
或按抓取配置进行设置
scrape_configs:
- job_name: prometheus
metric_name_validation_scheme: legacy
抓取配置设置会覆盖全局设置。如果设置了抓取配置验证,但未设置转义方案,则将根据验证方案推断出转义方案。这允许用户仅在抓取配置中设置 metric_name_validation_scheme,而无需指定 metric_name_escaping_scheme。
用于 UTF-8 转义的抓取内容协商
在抓取时,抓取系统必须在 Accept 标头中传递 escaping=allow-utf-8,才能被提供 UTF-8 名称。如果抓取目标未看到此标头,它将自动通过下划线替换,将 UTF-8 名称转换为传统兼容格式。
Prometheus 和兼容的抓取系统如果需要,也可以通过将 escaping 标头设置为不同的值来请求特定的转义方法。
underscores:默认方式:将传统无效字符转换为下划线。dots:类似于 UnderscoreEscaping,不同之处在于点被转换为_dot_,预先存在的下划线被转换为__。这允许对也包含点的简单指标名称进行往返转换。values:此模式在名称前加上U__,并将所有无效字符替换为 Unicode 值(由下划线包围)。单个下划线被替换为双下划线。此模式允许在传统 Prometheus 中对 UTF-8 名称进行完全往返转换。
在内容协商中宣布支持 UTF-8 表示 Prometheus 能够接收 UTF-8 字符,但这并不要求指标名称必须包含以前不支持的字符。Accept 标头宣布支持 UTF-8 也不要求指标生产者在他们那一端禁用名称翻译。确切的名称翻译策略由指标生产者决定。要求是当 Prometheus 请求除 allow-utf-8 之外的转义方案时,生产者必须按请求的方式转换名称。
远程写入 2.0
Remote Write 2.0 在 Prometheus 3.0 中自动接受所有 UTF-8 名称。在 Remote Write 2.0 中没有办法强制执行传统字符集验证。
OTLP 指标
Prometheus 3.0 中的 OTLP 接收器默认仍将所有名称归一化为 Prometheus 格式。您可以在 Prometheus 配置的 otlp 部分按如下方式进行更改
otlp:
# Ingest OTLP data keeping UTF-8 characters in metric/label names.
translation_strategy: NoTranslation
请注意,当不附加类型和单位后缀时,如果有两个名称相同但类型或单位不同的指标,这些指标将在 Prometheus 中发生冲突。一旦 Prometheus 原生支持类型和单位元数据,这个问题就会消失。
详情请参阅 OpenTelemetry 指南。
查询
使用 UTF-8 名称查询指标在 PromQL 中需要稍微不同的语法。
经典的查询语法仍适用于传统兼容的名称
my_metric{}
但 UTF-8 名称必须加引号并移入大括号内
{"my.metric"}
如果标签名称包含传统不兼容的字符,也必须加引号
{"metric.name", "my.label.name"="bar"}
指标名称可以出现在大括号内的任何位置,但从样式上讲,建议将其作为第一个项。