CnOps 智能运维与可观测社区
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题
导航菜单
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题

CnOps 智能运维与可观测社区

愿景

CnOps 智能运维与可观测社区是一个以"智能运维与可观测"为核心的开放、包容、分享的技术社区,旨在聚集运维专家、开发者和爱好者,共同探讨、学习和分享可观测最佳实践与最新技术,与众多技术社区合作互动,共同探讨交叉领域的技术挑战,推动可观测领域的创新与进步。

内容社区

  • 实践文章
  • 视频课程
  • 开源项目
  • 常见问答
  • 开发者工具

友情链接

  • Prometheus
  • Grafana Lab
  • OpenTelemetry
  • LoongCollector

关注我们

阿里云云原生公众号阿里云云原生
阿里云可观测公众号阿里云可观测

Copyright © 2026 CnOps 社区. All rights reserved.

首页/开源项目/Prometheus/将 Prometheus 用作 OpenTelemetry 后端
文档目录
Docker Swarm使用 Prometheus 查询日志使用 TLS 加密保护 Prometheus API 和 UI 端点使用基本认证保护 Prometheus API 和 UI 端点使用 cAdvisor 监控 Docker 容器指标为 Prometheus 对 Go 应用程序进行插桩理解和使用多目标 Exporter 模式将 Prometheus 用作 OpenTelemetry 后端Prometheus 中的 UTF-8

Prometheus

将 Prometheus 用作 OpenTelemetry 后端

Prometheus 支持通过 HTTP 接收 OTLP(即 "OpenTelemetry Protocol")数据。 默认情况下,OTLP 接收器是禁用的,类似于 Remote Write 接收器。这是因为 Prometheus 可以在没有任何认证的情况下工作,因此除非明确配置,否则接受传入流量是不安全的。 要启用接收器,你需要开启 CLI 标志...

Prometheus 支持通过 HTTP 接收 OTLP(即 "OpenTelemetry Protocol")数据。

启用 OTLP 接收器

默认情况下,OTLP 接收器是禁用的,类似于 Remote Write 接收器。这是因为 Prometheus 可以在没有任何认证的情况下工作,因此除非明确配置,否则接受传入流量是不安全的。

要启用接收器,你需要开启 CLI 标志 --web.enable-otlp-receiver。这将使 Prometheus 在 HTTP /api/v1/otlp/v1/metrics 路径上接收 OTLP 指标。

$ prometheus --web.enable-otlp-receiver

向 Prometheus 服务器发送 OpenTelemetry 指标

通常你需要告诉 OTLP 指标流量的来源关于 Prometheus 端点,以及应该使用 HTTP 模式的 OTLP(gRPC 通常是默认模式)。

OpenTelemetry SDK 和插桩库通常可以通过标准环境变量进行配置。以下是将 OpenTelemetry 指标发送到本地 Prometheus 服务器所需的 OpenTelemetry 变量:

export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:9090/api/v1/otlp/v1/metrics

关闭 traces 和 logs:

export OTEL_TRACES_EXPORTER=none
export OTEL_LOGS_EXPORTER=none

OpenTelemetry 指标的默认推送间隔为 60 秒。以下设置将推送间隔改为 15 秒:

export OTEL_METRIC_EXPORT_INTERVAL=15000

如果你的插桩库没有开箱即用地提供 service.name 和 service.instance.id,强烈建议进行设置。

export OTEL_SERVICE_NAME="my-example-service"
export OTEL_RESOURCE_ATTRIBUTES="service.instance.id=$(uuidgen)"

以上假设你的系统上有 uuidgen 命令可用。确保 service.instance.id 对每个实例是唯一的,并且每当资源属性发生变化时都会生成新的 service.instance.id。推荐的做法是在每次实例启动时生成一个新的 UUID。

配置 Prometheus

本节介绍 Prometheus 服务器的各种推荐配置方面,以启用和调优你的 OpenTelemetry 流程。

参见我们将在下面章节中使用的示例 Prometheus 配置文件。

启用乱序写入

有多种原因可能需要启用乱序写入。

例如,OpenTelemetry collector 鼓励批量处理,你可能有多个 collector 副本向 Prometheus 发送数据。因为没有机制对这些样本进行排序,它们可能会出现乱序。

要启用乱序写入,你需要在 Prometheus 配置文件中添加以下内容:

storage:
  tsdb:
    out_of_order_time_window: 30m

30 分钟的乱序窗口对大多数情况已经足够,但可以根据你的需要调整此值。

提升资源属性

基于经验和与社区的交流,我们发现在所有常见的资源属性中,有一些值得附加到你所有的 OTLP 指标上。

默认情况下,Prometheus 不会提升任何属性。如果你想提升其中一些,可以在 Prometheus 配置文件的此部分进行设置。以下代码片段分享了推荐提升的最佳实践属性集:

otlp:
  # Recommended attributes to be promoted to labels.
  promote_resource_attributes:
    - service.instance.id
    - service.name
    - service.namespace
    - service.version
    - cloud.availability_zone
    - cloud.region
    - container.name
    - deployment.environment
    - deployment.environment.name
    - k8s.cluster.name
    - k8s.container.name
    - k8s.cronjob.name
    - k8s.daemonset.name
    - k8s.deployment.name
    - k8s.job.name
    - k8s.namespace.name
    - k8s.pod.name
    - k8s.replicaset.name
    - k8s.statefulset.name

在查询时包含资源属性

默认情况下,除了 service.instance.id、service.namespace 和 service.name 之外,所有 OTel 资源属性都被转换为特殊 target_info 指标上的标签。
这意味着,对于你未提升的 OTel 资源属性,你仍然可以通过与 target_info 进行连接(join)在查询中包含相应的标签。
为此,我们建议通过以下标志启用实验性的 PromQL 函数 info 以便于连接:

--enable-feature=promql-experimental-functions

这种查询的一个示例如下:

info(rate(http_server_request_duration_seconds_count[2m]), {k8s_cluster_name=~".+"})

或者,也可以通过原始 join 查询来实现同样的效果:

rate(http_server_request_duration_seconds_count[2m])
* on (job, instance) group_left (k8s_cluster_name)
target_info

以上两个查询的作用是,将 rate(http_server_request_duration_seconds_count[2m]) 产生的时间序列用共享相同 job 和 instance 标签的 target_info 序列中的 k8s_cluster_name 标签进行增强。
换句话说,job 和 instance 标签在 http_server_request_duration_seconds_count 和 target_info 之间是共享的,类似于 SQL 的外键。
另一方面,k8s_cluster_name 标签对应 OTel 资源属性 k8s.cluster.name(Prometheus 将点转换为下划线,除非另有配置)。

但请注意,info 函数通常比原始 join 查询性能更好,因为它只选择具有匹配 job 和 instance 标签的 target_info 序列。
更重要的是,info 函数解决了 join 查询方法中一个古老且相当深奥的问题。
当被连接标签以外的其他标签(即所谓的标识标签)的值发生变化(即流转)时,除非旧的 target_info 版本被标记为过时,否则在 PromQL 回溯时间窗口内(默认 5 分钟),旧版本和新版本的 target_info 之间会存在重叠。
在此期间,针对 target_info 的 join 查询将因为存在两个匹配的不同 target_info 时间序列而失败。
幸运的是,info 函数不会受到这个问题的影响,因为它总是选择具有最新样本的时间序列!

那么,target_info 指标和 OTel 资源属性之间的关系是什么?
当 Prometheus 处理 OTLP 写入请求时,如果包含的资源包括 service.instance.id 和/或 service.name 属性,Prometheus 会为每个(OTel)资源生成 info 指标 target_info。
它在每个 target_info 序列上添加 instance 标签(值为 service.instance.id 资源属性的值)和 job 标签(值为 service.name 资源属性的值)。
如果存在 service.namespace 资源属性,它会作为前缀添加到 job 标签值中(即 <service.namespace>/<service.name>)。

默认情况下,service.name、service.namespace 和 service.instance.id 本身不会添加到 target_info,因为它们已转换为 job 和 instance。
但是,可以启用以下配置参数,在转换为 job 和 instance 的基础上,将它们直接添加到 target_info(如果 otlp.translation_strategy 是 UnderscoreEscapingWithSuffixes,则经过规范化将点替换为下划线)。

otlp:
  keep_identifying_resource_attributes: true

其余的资源属性也作为标签添加到 target_info 序列中,如果 otlp.translation_strategy 是 UnderscoreEscapingWithSuffixes,名称会转换为 Prometheus 格式(例如点转换为下划线)。
如果资源同时缺少 service.instance.id 和 service.name 属性,则不会生成相应的 target_info 序列。

对于资源的每个 OTel 指标,Prometheus 将其转换为相应的 Prometheus 时间序列,并(如果生成了 target_info)为其添加正确的 instance 和 job 标签。

UTF-8

从 3.x 版本开始,Prometheus 支持指标名称和标签的 UTF-8,因此可以省略 OpenTelemetry 的 Prometheus normalization translator 包。请注意,当 Prometheus 通过内容协商宣告它允许 UTF-8 字符时,并不要求指标名称必须包含以前不支持的字符。OTLP 指标可能会根据端点的配置以几种不同的方式进行转换。因此,虽然 UTF-8 在 Prometheus 存储和 UI 中默认启用,但你需要为 OTLP 指标接收器设置 translation_strategy,默认设置为旧的规范化方式 UnderscoreEscapingWithSuffixes。

有四种可能的转换策略,其中两种需要在 Prometheus 中启用 UTF-8 支持:

  • UnderscoreEscapingWithSuffixes,默认策略。完全转义指标名称以兼容经典的 Prometheus 指标命名规范,并包括附加类型和单位后缀。
  • UnderscoreEscapingWithoutSuffixes。类似于 UnderscoreEscapingWithSuffixes 完全转义指标名称,但不附加类型和单位后缀。从多个角度来看,此模式并不理想,用户应该意识到缺少后缀可能导致指标名称冲突,只有在仔细测试后才应启用此模式。一些组织偏好这种 OTel 对称性和有限字符支持之间的平衡。
  • NoUTF8EscapingWithSuffixes 将禁用将特殊字符更改为 _,允许原生使用 OpenTelemetry 指标格式,特别是与语义约定配合使用。请注意,特殊后缀如单位和计数器的 _total 仍会附加,以防止具有相同名称但不同类型或单位的多个指标之间可能的冲突。此模式需要启用 UTF-8。
  • NoTranslation。此策略绕过所有指标和标签名称的转换,原样传递。此模式需要启用 UTF-8。请注意,没有后缀时,如果具有相同名称但不同类型或单位的多个指标可能会发生冲突。
otlp:
  # Ingest OTLP data keeping UTF-8 characters in metric/label names.
  translation_strategy: NoTranslation

Delta 时间性

OpenTelemetry 规范说明 Delta 时间性和 Cumulative 时间性都受支持。虽然 Delta 时间性在 statsd 和 graphite 等系统中很常见,但 Cumulative 时间性是 Prometheus 的默认方式。

目前,Prometheus 内嵌了来自 OpenTelemetry-Collector-contrib 的 delta to cumulative 处理器,能够接收 delta 数据并将其转换为等效的累积表示形式,然后存储在 Prometheus 的 TSDB 中。

此功能是实验性的,因此请使用功能标志 otlp-deltatocumulative 启用 Prometheus 来使用它。

团队仍在致力于开发更高效的 OTLP delta 处理方式。

文章大纲