如何使用OpenTelemetry收集器将Prometheus提供的直方图数据转换为OTLP格式的数据
现代应用程序通常会通过 ` /metrics ` 端点以 Prometheus 格式公开各种指标数据。 在这些指标中,直方图尤其实用。它们能够显示数值落在不同区间的频率,比如 HTTP 请求的耗时、数据库查询的时间,或者队列处理的延迟等。 与简单的平均值不同,直方图能够呈现完整的图像:你可以清楚地看到有多少请求处理得很快,有多少请求处理得很慢,以及那些偶尔出现的异常值是如何影响用户体验的。 例如,在支付系统中,交易数量的突然增加可能会暴露出隐藏的瓶颈。虽然大多数请求会迅速完成,但那一小部分处理速度缓慢的交易却可能对整个系统产生连锁反应,导致重试次数增加、失败率上升,进而影响整体的吞吐量。直方图
现代应用程序通常会通过 `/metrics` 端点以 Prometheus 格式公开各种指标数据。
在这些指标中,直方图尤其实用。它们能够显示数值落在不同区间的频率,比如 HTTP 请求的耗时、数据库查询的时间,或者队列处理的延迟等。
与简单的平均值不同,直方图能够呈现完整的图像:你可以清楚地看到有多少请求处理得很快,有多少请求处理得很慢,以及那些偶尔出现的异常值是如何影响用户体验的。
例如,在支付系统中,交易数量的突然增加可能会暴露出隐藏的瓶颈。虽然大多数请求会迅速完成,但那一小部分处理速度缓慢的交易却可能对整个系统产生连锁反应,导致重试次数增加、失败率上升,进而影响整体的吞吐量。直方图通过展示数值的分布情况,并突出那些被平均值掩盖的异常值,帮助我们尽早发现这些问题。
然而,并非所有的后端服务都能原生理解 Prometheus 标准。许多现代的可观测性平台更倾向于使用 OTLP(OpenTelemetry 协议)。如果直接转发 Prometheus 数据而不进行转换,就可能会导致数据不完整或被错误解读。因此,我们需要一个流程来抓取、转换这些数据,并将其以 OTLP 格式导出,这样才能确保我们的可观测性系统能够保持一致性并具备实际操作价值。
在本文中,我们将使用 OpenTelemetry Collector 来从应用程序的 `/metrics` 端点抓取 Prometheus 直方图数据,将其映射到 OpenTelemetry 的直方图数据模型中,然后通过 OTLP 将这些数据导出到我们的可观测性后端系统中。Collector 充当了连接桥梁的角色,它在保证数据完整性的同时,也确保了与你的监控平台的兼容性。
为了具体说明这一过程,我们将使用一个模拟支付交易的小型 FastAPI 应用程序作为示例。该应用程序会公开两个 Prometheus 指标:`payment_transaction_duration_seconds`(用于记录每笔交易的耗时)和 `payment_transactions_total`(记录已完成交易的数量)。你也可以使用自己开发的应用程序来进行测试,因为任何在 `/metrics` 端点公开 Prometheus 数据的应用程序,其操作方式都是相同的。这就是我们将在本文中从头到尾使用的示例数据。
我们将涵盖的内容:
先决条件
在开始之前,请确保您具备以下条件:
已安装Docker
有一个应用程序,它通过
/metrics端点公开Prometheus指标拥有一个兼容OpenTelemetry的可观测性后端系统
具备关于Prometheus指标的基本知识
了解YAML语言的基础知识
对Docker和OpenTelemetry有基本的熟悉程度
阅读本教程并不需要掌握高级的OpenTelemetry知识。我会一步步讲解Prometheus直方图的工作原理,以及这些数据在通过OpenTelemetry收集器处理时会发生什么变化。
1. 如何使用Prometheus接收器抓取指标
首先,我们需要从应用程序中收集指标。演示应用程序会将它的Prometheus指标公开在/metrics端点上,而Prometheus接收器会定期访问这个端点,并将收集到的指标纳入可观测性处理流程中。您也可以直接查看/metrics端点上的数据,从而了解在收集器读取这些数据之前它们的实际内容。
配置示例:
receivers:
prometheus:
config:
scrape_configs:
- job_name: payment-demo
scrape_interval: 15s
staticConfigs:
- targets: ["payment-api:8080"]
这里背后实际发生了什么:
scrape_interval决定了收集器访问目标端点的频率。在这里我们设置了15秒的间隔;您可以根据自己对指标更新频率的需求,以及应用程序所能承受的负载来调整这个值。
在像支付平台或实时处理服务这样的高吞吐量系统中,设置合适的抓取间隔尤为重要。如果间隔时间过长,可能会错过一些短暂出现的性能问题或临时性错误;而如果间隔时间过短,则可能会导致收集请求过多,从而使系统负担过重,甚至产生过多的网络流量。
targets列出了那些公开Prometheus指标的具体端点。当需要从多个服务中抓取数据时,可以添加多个目标地址。
最后,job_name是一个标识符,它有助于将收集到的指标进行逻辑分类,这样在它们被传输到后端系统后,就更容易进行管理和分析了。

2. 转换 Prometheus 直方图
在获取到这些指标数据后,下一步就是对它们进行转换。Prometheus 将直方图以多种时间序列的形式呈现出来:
_bucket用于显示有多少请求的耗时低于某个特定值。_sum表示所有观测到的耗时值的总和。_count代表观测到的数据条目数量。
payment_transaction_duration_seconds 直方图记录了每笔支付交易所花费的时间。Prometheus 将该数据以 _bucket、_count 和 _sum 这三种形式呈现出来。当 Prometheus 收集器获取到这些指标后,会将其转换为 OpenTelemetry 直方图的数据模型,然后通过 OTLP 导出这些数据,在此过程中所有用于分析交易延迟及计算百分位数的信息都会被保留下来。
如果没有直方图,平均值就无法反映真实的延迟分布情况。例如,如果大多数请求的耗时为 50 毫秒,但有 5% 的请求耗时超过 2 秒,那么 150 毫秒的平均值就会掩盖这一严重的性能问题。而直方图通过记录落入不同延迟区间的数据条目数量,从而呈现出完整的延迟分布情况。
了解这种延迟分布有助于你发现其中的变化,并进一步排查诸如数据库查询缓慢、服务负载过重,或是下游依赖项导致的延迟等问题。
实际的 Prometheus 直方图
以下就是你的实际 /metrics 输出结果示例:
而以下则是 OpenTelemetry 所呈现的直方图形式:
上述两种输出方式实际上表示的是相同的数据——即每笔交易所花费的时间。不过,OpenTelemetry 直方图将这三个独立的 Prometheus 数据序列合并成了一个直方图,其中包含了数据条目数量、总和、具体的延迟区间以及每个区间的数据条目数量等信息。
3. 通过 OTLP 导出指标数据
在获取并处理完这些指标数据后,收集器会使用 OTLP 将它们发送到你的可观测性后端系统。OTLP 输出工具会将处理后的指标数据(包括直方图、计数器等信息)传输到后端系统。
exporters:
otlp:
endpoint: "otlpbackend.example.com:4317"
tls:
insecure: false
endpoint指定了用于接收OTLP指标的后端地址。这个地址通常指向一个中央观测平台,该平台会汇总来自您基础设施中多个服务的指标数据。
tls确保收集器与后端之间的数据传输安全。只有当您有意连接到不使用TLS的终端点时,才应设置insecure: true,例如在某些本地开发环境中。
4. 将各个组件组合起来
我们已经分别了解了管道中的每个组成部分。现在,让我们将它们连接起来,追踪一个指标从应用程序开始,一直传输到后端。
service:
pipelines:
metrics:
receivers: [prometheus]
exporters: [otlp]
这就是我们的payment_transaction_duration_seconds指标所经过的完整路径,从FastAPI应用程序一直传输到观测后端。上面的图表展示了这一流程。下一节将介绍如何实际运行这个流程,并将其连接到SigNoz。
管道流程:
上述架构图显示了一个FastAPI应用程序,它通过//metrics路径暴露指标数据;OpenTelemetry收集器使用Prometheus接收器抓取这些数据,然后对它们进行处理,并通过OTLP将其传输到观测后端。
5. 运行OpenTelemetry收集器
我们将运行整个管道流程,确认交易指标数据能够从应用程序顺利传输到SigNoz。请按照以下步骤操作(下面我会详细说明每个步骤):
配置SigNoz Cloud:设置收集器将使用的终端点和数据导入密钥。
启动FastAPI应用程序:该应用程序会在
/metrics路径上暴露Prometheus指标数据。启动OpenTelemetry收集器:收集器会使用Prometheus接收器开始抓取应用程序的
/metrics端点上的数据。生成测试交易记录:向应用程序发送请求,以创建用于测量交易时长的数据。
验证收集器和后端的运行状态:检查收集器的日志,确认整个管道流程正在正常运行;然后打开SigNoz,确认
payment_transaction_duration_seconds指标数据已经到达。故障排除
5.1 配置SigNoz Cloud
SigNoz提供了用于接收OpenTelemetry收集器所导出指标数据的观测后端。在这个演示中,我们将使用SigNoz Cloud作为观测后端,因此无需在本地进行任何安装操作。
首先,前往signoz.io注册一个免费账户。在SigNoz Cloud控制面板中,选择设置 → 数据采集键选项。该页面会显示您的数据采集URL、所在地区以及数据采集键。
将这些信息添加到项目目录中的.env文件中:
SIGNOZ_ingESTION_KEY=你的实际密钥
SIGNOZ_OTLP_ENDPOINT=ingest..signoz.cloud:443
请将这个数据采集键视为密码,切勿将其提交或公开分享。
在收集器的配置文件中引用这些变量:
exporters:
otlp:
endpoint: "${SIGNOZ_OTLP_ENDPOINT}"
tls:
insecure: false
headers:
signoz-ingestion-key: "${SIGNOZ_ingESTION_KEY}"
接下来,将.env文件添加到.gitignore中,这样这个密钥就不会被提交到代码仓库中:
echo ".env" >> .gitignore
5.2 启动FastAPI应用程序。
在8080端口上启动该应用程序:
uvicorn app.main:app --reload --port 8080
确认应用程序已经成功运行:
curl http://localhost:8080/
现在可以查看Prometheus提供的指标数据了:
curl -Ls http://localhost:8080/metrics
/metrics端点会公开应用程序的Prometheus指标数据,其中就包括收集器会抓取的payment_transaction_duration_seconds直方图。
5.3 启动收集器
在应用程序已经运行且收集器的配置也已完成之后,就可以启动收集器了:
docker compose up --build
请查看收集器的日志,以确认数据采集流程是否正常进行,以及指标数据是否正在被处理。
通过这些步骤,系统会生成payment-api镜像,在共享的telemetry网络中启动两个容器,同时收集器也会立即开始使用Prometheus接收器从应用程序中抓取/metrics端点的数据,并自动读取来自.env文件中的数据采集键和URL信息。
5.4 生成测试交易记录
生成处理时间各不相同的交易记录:
curl -X POST "http://localhost:8080/transactions?delay_ms=50"
curl -X POST "http://localhost:8080/transactions?delay_ms=250"
curl -X POST "http://localhost:8080/transactions?delay_ms=2500"
如果希望在直方图中看到更多数据,可以再生成一些请求记录。
这些请求会生成用于记录交易处理时长的数据,这些数据会被保存到payment_transaction_duration_seconds直方图中。收集器会在下一次数据采集时获取这些更新后的指标值。
5.5 确认后端是否已接收数据
打开SigNoz Cloud,然后搜索以下内容:
payment_transaction_duration_seconds
该指标应该以直方图的形式呈现,其各个分桶的统计数据_bucket、_sum和_count应当被后端系统接收和处理,而不会作为无关的Prometheus指标系列显示出来。
5.6 故障排除
如果指标数据没有正常传输,首先检查日志信息:
docker logs
查找其中是否包含连接错误、认证失败、数据采集失败或配置错误等信息。
同时还需要验证以下内容:
FastAPI应用程序是否正在运行中。
能否正常访问
/metrics路径。收集器是否能够成功连接到该应用程序。
SigNoz的端点地址和数据导入配置是否正确。
收集器是否能够读取到
.env文件中的配置变量。接收器和导出器的名称是否与管道配置相匹配。
如果可能的话,可以使用--dry-run参数在部署前进行验证测试。
结论
Prometheus直方图能够通过展示数据在不同分桶中的分布情况,帮助我们更直观地了解交易处理的延迟情况,而不会将所有数据简化为单一的平均值。
在本教程中,我们展示了如何通过OpenTelemetry Collector将FastAPI应用程序/metrics端点提供的payment_transaction_duration_seconds指标数据导入到SigNoz系统中。
Prometheus的接收器会将_bucket、_count和_sum这些指标系列映射到OpenTelemetry直方图的数据模型中,从而保留交易处理时长的分布信息,便于后端进行分析和处理。
相关文章
使用OpenTelemetry实现Claude Code的可观测性
像 Claude Code 、 OpenAI Codex 、 Google Antigravity 以及 Cursor 这样的代理编码工具,在日常软件开发中已经变得无处不在。 随着代理系统的不断发展,开发者让这些系统完成的大部分工作都是通过逐个分配子任务来实现的。许多团队也在探索并使用共享的、多租户式的代理基础设施,这种架构的成本不会与某个特定的所有者挂钩。在这种情况下,可观测性就成为了监控基础设施成本的关键因素。 在本指南中,您将了解可观测性的工作原理,然后学习如何启用Claude Code内置的遥测功能,运行后端程序来收集数据,并读取该系统生成的各类指标、日志及追踪信息。这些内容将帮助您更
阅读全文
人工智能评估工程:从零开始构建一款可用于生产环境的大型语言模型评估平台【完整使用手册】
一个令人印象深刻的演示与一个值得信赖的系统之间的差距,其实是通过各种评估来衡量的。 我想先讲一个目前正在数百个工程团队中发生的真实案例。 有一个团队为法律研究开发了一个RAG应用程序。他们用40个精心挑选的问题对该程序进行了测试,结果看起来很不错,于是便向合作方展示了这个系统。合作方对它印象深刻,随后便决定将其正式投入使用。 然而在系统投入生产三周后,一名法律助理发现其中一个答案错误地引用了某项法规。工程团队查看了相关数据,发现“准确性得分”为0.91,这个数值看起来是正常的;他们还检查了答案的相关性,结果也符合标准。 但他们忽略了一个重要的指标:即“上下文完整性”。这个指标用于判断系统是否检
阅读全文
人工智能如何改变补丁更新流程,以及开发人员需要了解哪些关于漏洞暴露管理的相关知识
当漏洞扫描工具报告你的应用程序存在23个安全漏洞时,其中4个属于严重等级,7个为较高风险等级,剩下的12个则为中等风险等级,乍一看,解决办法似乎很明确:立即开始修补这些漏洞。但究竟应该先修复哪一个呢? 这在漏洞管理中一直是个棘手的问题。虽然安全团队可能会及时发现存在漏洞的代码依赖项,但并不总能立刻对其进行修复。开发人员需要确保这些有漏洞的代码仍在被使用中,并在将修复方案部署到生产环境之前完成所有必要的测试。 不过,最近在利用人工智能来检测软件漏洞及攻击手段方面确实取得了一些显著的进展。例如,这篇 研究 就详细介绍了相关的研究成果以及未来的发展方向。 但这一切究竟如何才能真正帮助开发社区呢?我们
阅读全文
演示主题:如何通过一份数据同时完成从S3存储系统到GPU的计算任务——重新思考用于机器学习训练的数据加载方式
Onur Satici详细解释了如何利用Vortex这一由Linux基金会推出的开源列式文件格式来彻底改变高吞吐量数据加载的方式。他说明了如何通过层叠式的轻量级编码技术、基于文件结构的数据分段优化机制以及零拷贝内存传输技术,消除CPU与NVMe之间的性能瓶颈,从而让S3存储中的数据能够以高达60 Gbps的速度直接传输到GPU上,而无需在进行任何预处理操作。 作者:Onur Satici
阅读全文