使用OpenTelemetry向本地Prometheus远程写入指标失败求助
问题分析与解决方案
核心问题点
1. 第一次代码的错误逻辑
你误用了prometheus_client.start_http_server:这个函数是用来在本地启动小型HTTP服务,暴露本地Prometheus格式指标的工具,并非接收远程写入请求的Prometheus服务。OTel的远程写入导出器需要指向真正的Prometheus服务的/api/v1/write端点,而非这个本地小服务的地址。
2. 第二次代码的关键缺失
虽然你开启了Prometheus的remote-writer-receiver特性,但启动容器时未配置端口映射,导致本地localhost:9090无法访问容器内的Prometheus服务,这是问题的核心。此外还有几个需验证的细节点。
分步修正方案
步骤1:正确启动支持远程写入的Prometheus容器
添加端口映射参数,确保本地能访问容器内的9090端口,完整命令如下:
docker run -d -p 9090:9090 \ prom/prometheus:latest \ --config.file=/etc/prometheus/prometheus.yml \ --enable-feature=remote-writer-receiver
-d:后台运行容器-p 9090:9090:将本地9090端口映射到容器内的9090端口,这是本地访问容器内Prometheus的必要条件
步骤2:验证Prometheus远程写入端点可达
启动容器后,先访问http://localhost:9090确认Prometheus服务正常运行,再用curl测试远程写入端点是否可用:
curl -X POST http://localhost:9090/api/v1/write -d 'test_metric 123'
返回空响应(HTTP 200)说明端点正常;若返回404,需检查remote-writer-receiver特性是否正确开启,或容器启动命令是否有误。
步骤3:修正Python代码并添加错误排查逻辑
在代码中添加日志,便于排查OTel导出过程中的错误,同时确保Meter和Counter的使用符合规范:
import random import time import logging from opentelemetry import metrics from opentelemetry.exporter.prometheus_remote_write import PrometheusRemoteWriteMetricsExporter from opentelemetry.sdk.metrics import MeterProvider from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader from opentelemetry.sdk.resources import Resource # 开启OTel日志,方便排查导出错误 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # 配置资源(可选,有助于指标分类) resource = Resource(attributes={"service.name": "test-service"}) # 初始化导出器,指向正确的远程写入端点 exporter = PrometheusRemoteWriteMetricsExporter( endpoint="http://localhost:9090/api/v1/write", headers={}, ) # 初始化指标读取器,设置导出间隔(毫秒) reader = PeriodicExportingMetricReader( exporter, export_interval_millis=1000, # 每秒导出一次 ) # 初始化MeterProvider provider = MeterProvider(metric_readers=[reader], resource=resource) metrics.set_meter_provider(provider) # 获取Meter并创建Counter meter = metrics.get_meter("my_meter") requests_counter = meter.create_counter( name="test_counter", description="Random counter", unit="1" ) while True: num = random.randint(0, 50) print(f"Adding {num} to test_counter") # 添加标签(可选,丰富维度) requests_counter.add(num, {"env": "staging", "label": "9999"}) time.sleep(1)
步骤4:验证指标是否被Prometheus接收
运行修正后的代码后,访问http://localhost:9090/graph,在查询框输入test_counter,若能看到指标数据,说明导出成功。
额外排查点
- 检查Python依赖版本:确保
opentelemetry-sdk、opentelemetry-exporter-prometheus-remote-write为最新兼容版本,可用pip list查看,必要时更新:pip install --upgrade opentelemetry-sdk opentelemetry-exporter-prometheus-remote-write - 查看容器日志:若仍无法接收指标,查看Prometheus容器日志排查远程写入相关错误:
docker logs <容器ID或名称>
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

