使用 Prometheus 作为您的 OpenTelemetry 后端

Prometheus 支持通过 OTLP (又名 "OpenTelemetry 协议") 通过 HTTP 进行摄取。

启用 OTLP 接收器

默认情况下,OTLP 接收器处于禁用状态,类似于远程写入接收器。这是因为 Prometheus 可以无需任何身份验证即可工作,因此除非明确配置,否则接受传入的流量是不安全的。

要启用接收器,您需要切换 CLI 标志 --web.enable-otlp-receiver。这将导致 Prometheus 在 HTTP /api/v1/otlp/v1/metrics 路径上提供 OTLP 指标接收服务。

$ prometheus --web.enable-otlp-receiver

将 OpenTelemetry 指标发送到 Prometheus 服务器

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

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

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

关闭跟踪和日志

export OTEL_TRACES_EXPORTER=none
export OTEL_LOGS_EXPORTER=none

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

export OTEL_METRIC_EXPORT_INTERVAL=15000

如果您的插桩库没有提供开箱即用的 service.nameservice.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 收集器鼓励批处理,并且您可能有多个收集器副本向 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
    - cloud.availability_zone
    - cloud.region
    - container.name
    - 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

在查询时包含资源属性

所有未提升的、更详细或唯一的标签都附加到特殊的 target_info

您可以使用此指标在查询时连接一些标签。

这样的查询示例可能如下所示

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]) 的时间序列使用来自共享相同 jobinstance 标签的 target_info 系列的 k8s_cluster_name 标签进行了扩充。换句话说,jobinstance 标签在 http_server_request_duration_seconds_counttarget_info 之间共享,类似于 SQL 外键。另一方面,k8s_cluster_name 标签对应于 OTel 资源属性 k8s.cluster.name(Prometheus 将点转换为下划线)。

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

默认情况下,service.nameservice.namespaceservice.instance.id 本身不会添加到 target_info,因为它们会转换为 jobinstance。但是,可以启用以下配置参数将其直接添加到 target_info(如果 otlp.translation_strategyUnderscoreEscapingWithSuffixes,则会进行规范化以将点替换为下划线),并转换为 jobinstance

otlp:
  keep_identifying_resource_attributes: true

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

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

UTF-8

从 3.x 版本开始,Prometheus 支持指标名称和标签的 UTF-8,因此可以省略来自 OpenTelemetry 的 Prometheus 规范化转换器包

UTF-8 在 Prometheus 存储和 UI 中默认启用,但您需要为 OTLP 指标接收器设置 translation_strategy,默认情况下设置为旧的规范化 UnderscoreEscapingWithSuffixes

将其设置为 NoUTF8EscapingWithSuffixes(我们建议这样做)将禁用将特殊字符更改为 _,从而允许本地使用 OpenTelemetry 指标格式,特别是使用 语义约定。请注意,将附加特殊后缀(如单位和计数器的 _total)。正在进行不生成后缀的工作,请继续关注。

otlp:
  # Ingest OTLP data keeping UTF-8 characters in metric/label names.
  translation_strategy: NoUTF8EscapingWithSuffixes

目前,OTLP 转换包中存在一个已知限制,如果多个 UTF-8 字符在单词之间连接,则会从指标/标签名称中删除字符,例如,my___metric 变为 my_metric。请参阅 https://github.com/prometheus/prometheus/issues/15362 了解更多详细信息。

增量时效性

OpenTelemetry 规范指出,支持增量时效性和累积时效性。

虽然增量时效性在 statsd 和 graphite 等系统中很常见,但累积时效性是 Prometheus 的默认时效性。

目前,Prometheus 不支持增量时效性,但我们正在向 OpenTelemetry 社区学习,并且我们正在考虑将来添加对其的支持。

如果您来自增量时效性系统,我们建议您在您的 OTel 管道中使用增量到累积处理器

此文档是开源的。请通过提交问题或拉取请求来帮助改进它。