本文介绍如何将以 Prometheus exposition 或 OpenMetrics 格式抓取的指标转换为 OpenTelemetry 数据模型中定义的指标,以及如何从 OpenTelemetry 指标数据中创建Prometheus格式的指标数据。由于 OpenMetrics 是 Prometheus 类型的超集,因此本文中“Prometheus”表示“Prometheus 或 OpenMetrics”。“OpenMetrics”是指仅仅出现在 OpenMetrics 的概念。
Prometheus 指标转换为 OTLP
指标元数据
必须将 OpenMetrics MetricFamily Name 作为 OTLP 指标的名称。默认情况下名称保持不变,但转换过程应提供配置项以确定是否删除指标名称中的类型(例如_total
)和单位(例如_seconds
)后缀。
如果存在OpenMetrics UNIT 元数据, 则必须转换为 OTLP 指标的单位。该单位应通过以下方式进行转换:
- 将完整单词转换为缩写(例如,“milliseconds” 转为 “ms”)。
- 特殊情况:将“ratio”转换为“1”。
- 将“foo_per_bar”转换为“foo/bar”。
如果存在OpenMetrics HELP 元数据, 则必须转换为 OTLP 指标的描述。
如果存在OpenMetrics TYPE 元数据, 则必须用于确定 OTLP 数据类型,后续章节中列出了各种类型的转换规则。不带类型元数据的指标族(MetricFamily),需要遵循后文中unknow类型指标的规则。
计数器(counter)
Prometheus 的counter类型必须转换为is_monotonic
等于true
的 OTLP sum类型。
仪表(gauge)
Prometheus 的gauge类型必须转换为 OTLP gauge类型。
信息(info)
OpenMetrics Info类型指标必须转换为 OTLP 非单调(is_monotonic=false
)的sum类型,除非它是用于填充资源属性的target_info指标。OpenMetrics Info 可以看作是 OpenMetrics Gauge 的一个特例,其值为 1,其标签通常在流程的整个生命周期内保持不变。它被转换为非单调sum,而不是gauge,因为它的值“1”应该被看做是一个计数,在聚合标签时应将其相加。
状态集(StateSet)
OpenMetrics StateSet 指标必须转换为 OTLP 非单调(is_monotonic=false
)的sum类型。OpenMetrics StateSet 可以看作是 OpenMetrics Gauge 的特例,它的值为 0 或 1,并且每个可能的状态都有一个度量点。它被转换为非单调sum,而不是gauge,因为它的值“1”应该被看做是一个计数,在聚合标签时应将其相加。
未知类型(Unknown)
必须将 Prometheus Unknown 转换为 OTLP gauge类型。
直方图(Histogram)
Prometheus Histogram类型必须转换为 OTLP Histogram类型。
Prometheus 直方图的多个指标行必须合并到一个 OTLP Histogram中:
- 以
_bucket
结尾的指标上的le
标签用于对直方图bucket的边界标进行标识和排序。每各 Prometheus 指标行对应目标直方图上的bucket count值。le
标签的每个值(+Inf
除外)都会对应一个bucket边界。 - 带有
_count
和_sum
后缀的指标行用于确定直方图的计数和总和。 - 如果不存在
_count
,则必须删除该指标。 - 如果不存在
_sum
,则不能设置直方图的总和。
摘要(Summary)
Prometheus summary类型必须转换为 OTLP Summary类型。
Prometheus Summary指标的多行将会合并到一个 OTLP Summary指标中:
- 无后缀指标上的
quantile
标签用于标识分位数点。每个不同quantile的 Prometheus 指标行在对应目标Summary指标上的一个分位数。 - 带有
_count
和_sum
后缀的行用于确定目标Summary指标的计数和总和。 - 如果不存在
_count
,则必须删除该指标。 - 如果不存在
_sum
,则Summary指标的总和必须设置为零。
丢弃的类型
必须丢弃以下 Prometheus 类型:
开始时间(startTime)
OpenMetrics 中规定了附带_created
指标来包含开始时间。将 Prometheus Counter类型转换为 OTLP 时,应转换带_created
后缀的指标。如果没有带_created
后缀的指标,则必须遵循 Cumulative streams: handling unknown start time。转化可以提供配置(默认禁用)允许使用process_start_time_seconds
指标作为开始时间。仅当目标上的所有counter指标在进程启动后立刻启动,并且在运行时未重置的情况下,使用process_start_time_seconds
才正确。
样本(examplars)
OpenMetrics Examplar可以附加到 Prometheus Histogram类型指标的bucker指标点和counter类型的指标点上。Histogram类型指标的bucker指标点的Examplar应转换为 OpenTelemetry 的histogram指标上的examplar。counter类型的指标点上的Examplar应该转换为 OpenTelemetry Sum类型上的examplar。如果存在时间戳,则必须添加到 OpenTelemetry 的examplar中。trace_id
和span_id
应从 label 中检索。不是traceId和spanId的其他标签,必须作为属性添加到 OpenTelemetry 的examplar中。
Instrumentation Scope
如果存在otel_scope_name 和otel_scope_version 标签,则必须从所有指标点中删除,并用作scopeMetric的名称和版本号。所有otel_scope_info指标需要从抓取范围中丢弃,它的标签(除了otel_scope_name 和otel_scope_version)必须添加到对应名称和版本的scopeMetric的属性中。
例如,OpenMetric的指标如下:
# TYPE otel_scope_info info
otel_scope_info{otel_scope_name="go.opentelemetry.io.contrib.instrumentation.net.http.otelhttp",otel_scope_version="v0.24.0",library_mascot="bear"} 1
# TYPE http_server_duration counter
http_server_duration{otel_scope_name="go.opentelemetry.io.contrib.instrumentation.net.http.otelhttp",otel_scope_version="v0.24.0"...} 1
会转换为:
# within a resource_metrics
scope_metrics:
scope:
name: go.opentelemetry.io.contrib.instrumentation.net.http.otelhttp
version: v0.24.0
attributes:
library_mascot: bear
metrics:
- name: http_server_duration
data:
sum:
data_points:
- value: 1
不含了otel_scope_name 和otel_scope_version标签的指标,必须被添加到一个能够反映转换过程的scopeMetrics中,例如otel-collector的prometheus receiver。
资源属性
抓取 Prometheus 数据时,必须给指标添加资源属性,以将不同 Prometheus 端点的指标区分开来。特别需要service.name
和service.instance.id
以确保 Prometheus exporter可以使用job
和instance
标签消除歧义,如下所述。
以下属性必须作为指标相关的资源属性,并且不能作为指标属性:
OTLP 资源属性 | 描述 |
---|---|
service.name |
目标所属服务的已配置名称 |
service.instance.id |
目标的唯一标识符。默认情况下,它应该是URL <host>:<port> |
以下属性可以作为指标相关的资源属性,并且不得添加为指标属性:
OTLP 资源属性 | 描述 |
---|---|
server.address |
被抓取的目标 URL 部分<host> |
server.port |
被抓取的目标 URL 部分<port> |
url.scheme |
http 或https |
除上述属性外,target_info指标还提供了其他资源属性。如果存在target_info指标, 必须删除它,并且必须将它的标签转换为资源属性, 附加到其他指标上。默认情况下,标签名和标签值都不得修改(例如将标签名中的_
替换为.
字符)。