使用 OTLP 与 Prometheus 双路导出 .NET 指标

许多应用直接将指标导出到 Prometheus。如果你还不熟悉它,可以把它理解为用于保存计数器、直方图等指标的时序数据库。将指标存入 Prometheus 的应用通常会使用一种常见的 Prometheus 客户端完成集成。

如今,OpenTelemetry 已成为 CNCF 毕业项目,越来越多的公司希望迁移到 OpenTelemetry,在可观测性架构中加入指标之外的信号。日志和追踪是常见选择,可以帮助深入了解应用的行为。性能剖析数据也开始成为受欢迎的第四种遥测信号,用来获得更深层的理解。

这带来了迁移难题:怎样把应用的指标从一个系统迁移到另一个系统,同时避免一次性切换?为了降低迁移风险,更合适的是渐进方式:在一段时间内同时向两个系统导出指标,比较并检查迁移前后的状态,确保任一系统中的生产可见性都没有损失,无论是观察指标还是驱动告警。

使用 .NET 的 OpenTelemetry Prometheus 导出器

.NET 的 OpenTelemetry Prometheus 导出器最新版本允许对生产指标采用这种方式。你可以在应用和框架代码中使用 .NET Meter 类采集指标,同时把它们导出到 Prometheus 及另一个导出器,例如由 OpenTelemetry.Exporter.OpenTelemetryProtocol NuGet 包提供的 OTLP 导出器。

这个 Prometheus 导出器实际上是一种构建在 OpenTelemetry SDK 之上的 Prometheus 客户端库。它在应用中提供 HTTP 抓取端点,让 Prometheus 服务器定期采集应用指标。

该导出器实现 OpenTelemetry 的 Prometheus 规范,并实现所有已记录的文本暴露格式,以兼容 OpenMetrics;仍处于实验阶段的 OpenMetrics 2.0 除外。规范实现矩阵可用于核对实现情况。

flowchart LR
    subgraph APP["Application"]
        AC["Application code"]
        SDK["OpenTelemetry SDK"]
        PE["Prometheus exporter"]
        OE["OTLP exporter (Client)"]
        EP["GET /metrics HTTP endpoint (Server)"]

        AC -->|"Generates metrics"| SDK
        SDK -->|"Feeds metrics"| PE
        PE -->|"Serves metrics as text/plain"| EP
        SDK -->|"Feeds metrics"| OE
    end

    P["Prometheus (Client)"]
    OTB["OpenTelemetry Backend (Server)"]

    P -->|"HTTP GET /metrics (scrape request)"| EP
    EP -->|"Metrics response (text format)"| P

    OE -->|"OTLP export request"| OTB
    OTB -->|"OTLP response/ack"| OE

在 .NET 应用代码中,只使用 Meter 类及 Counter<T>、Gauge<T>、Histogram<T> 指标工具,就能采集指标,无需同时使用 .NET OpenTelemetry SDK 和专门的 Prometheus 客户端。

public class BlogPostComments
{
    private readonly Meter _meter;
    private readonly Counter<long> _likes;

    public BlogPostComments(IMeterFactory meterFactory)
    {
        _meter = meterFactory.Create("OpenTelemetry.Blog");
        _likes = _meter.CreateCounter<long>("blog_post_likes");
    }

    public void BlogPostLiked(long id) =>
        _likes.Add(1, new KeyValuePair<string, object?>("post_id", id));
}

随后,在项目中加入 OpenTelemetry.Exporter.Prometheus.AspNetCore NuGet 包,再用少量代码配置 OpenTelemetry SDK,就可以同时向 Prometheus 和支持 OpenTelemetry 的后端通过 OTLP 导出指标。

using OpenTelemetry;
using OpenTelemetry.Exporter;
using OpenTelemetry.Metrics;

using var meterProvider = Sdk.CreateMeterProviderBuilder()
    .SetResourceBuilder(CreateResourceBuilder())
    .AddMeter("OpenTelemetry.Blog")
    .AddOtlpExporter()
    .AddPrometheusExporter()
    .Build();

应用还需要暴露 Prometheus 用于采集指标的 HTTP 抓取端点。原文说明可以在 Startup 类的 Configure 方法中,为 IApplicationBuilder 添加 UseOpenTelemetryPrometheusScrapingEndpoint 扩展方法,并给出以下示例:

var builder = WebApplication.CreateBuilder(args);

// Configure services here

var app = builder.Build();

// Configure other middleware here

app.MapPrometheusScrapingEndpoint();

app.Run();

使用 Meter API 导出指标,会让应用代码更易移植,并解除它与 Prometheus 专用 API 的耦合。因此可以移除应用代码对 Prometheus 客户端库的依赖。除了让代码能够接入 OpenTelemetry 生态,这也让你可以使用其他 .NET 生态工具,例如用 dotnet-counters 查看指标。

如果应用现在只使用原生 Prometheus 客户端,例如 prometheus-net,就需要先逐步迁移到 Meter API。迁移需要多长时间,取决于现有 Prometheus 埋点的复杂程度,以及可投入修改的资源。

迁移中可能遇到一些 Prometheus 功能没有对应的 Meter API,因此不受支持,包括:

  • Prometheus 的 summary 数据类型;
  • 原生直方图。

使用 OTLP 向 Prometheus 推送指标

另一种情况是:你只有 Prometheus 服务器,没有兼容 OTLP 的后端,而且只希望导出指标。Prometheus 本身提供一项需要显式启用的功能,可以接收通过 OTLP 推送过来的指标。

首先,确保运行 Prometheus 时使用 --web.enable-otlp-receiver 命令行标志。

然后,采用与上面相似的方式配置 OTLP 导出器,但这种情况下无需同时使用 Prometheus 导出器。还要注意,示例为 OTLP 指标端点指定路径,并将导出协议设为 HTTP/protobuf。

using OpenTelemetry;
using OpenTelemetry.Exporter;
using OpenTelemetry.Metrics;

using var meterProvider = Sdk.CreateMeterProviderBuilder()
    .SetResourceBuilder(CreateResourceBuilder())
    .AddMeter("OpenTelemetry.Blog")
    .AddOtlpExporter((options, _) =>
    {
        options.Endpoint = new Uri("http://prometheus:9090/api/v1/otlp/v1/metrics");
        options.Protocol = OtlpExportProtocol.HttpProtobuf;
    })
    .Build();

这种方式允许使用 OpenTelemetry .NET SDK,通过 OTLP 向 Prometheus 推送指标,应用代码无需依赖 Prometheus 客户端库。

完整示例见 OpenTelemetry .NET 仓库中的 Getting Started with Prometheus and Grafana。

总结

应用可以用较小的运行时开销,同时推送 OTLP 指标,并让 Prometheus 拉取指标。这样两个系统便可以并行使用,直到你决定将指标完全迁移到兼容 OpenTelemetry 的后端。


原文:Dual-exporting .NET metrics with OTLP and Prometheus。作者:Martin Costello(Grafana Labs);发布日期:2026-09-18。原站内容仓库采用 CC BY 4.0,本稿为中文翻译,原内容按许可“按原样”提供,不附加担保。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容