首页
/ OpenTelemetry-dotnet中健康检查请求的路由属性缺失问题解析

OpenTelemetry-dotnet中健康检查请求的路由属性缺失问题解析

2025-06-24 14:55:07作者:蔡丛锟

在基于OpenTelemetry-dotnet的ASP.NET Core应用监控实践中,开发者可能会遇到一个特殊的现象:当使用传统中间件方式配置的健康检查端点(/hc)时,生成的HTTP服务器请求时长指标(http.server.request.duration)中会缺失关键的路由属性(http.route)。本文将深入分析这一现象的技术背景、产生原因及解决方案。

现象描述

在ASP.NET Core应用中配置健康检查时,开发者通常有两种方式:

  1. 通过app.UseHealthChecks()注册中间件
  2. 通过app.MapHealthChecks()注册端点路由

当使用第一种方式时,OpenTelemetry采集的指标数据中会缺失http.route属性,而第二种方式则能正常记录该属性。这种差异会导致在监控系统中无法按路由维度对健康检查请求进行聚合分析。

技术背景解析

OpenTelemetry的指标采集机制

OpenTelemetry的ASP.NET Core instrumentation通过监听应用管道中的事件来收集指标。对于路由信息的采集,它依赖于ASP.NET Core的终结点路由系统(Endpoint Routing)提供的RouteEndpoint元数据。

ASP.NET Core的两种路由实现

  1. 中间件方式

    • 基于传统的请求管道中间件
    • 不参与终结点路由系统
    • 简单直接但功能有限
  2. 终结点路由方式

    • 基于ASP.NET Core 3.0引入的终结点路由系统
    • 提供丰富的路由元数据
    • 支持路由模板、参数等高级特性

问题本质

这不是一个bug,而是两种不同架构设计导致的结果差异。UseHealthChecks作为遗留的中间件实现,不参与现代ASP.NET Core的终结点路由系统,因此OpenTelemetry无法从中提取路由信息。

解决方案与实践建议

推荐方案

在生产环境中,建议统一使用终结点路由方式注册健康检查:

app.MapHealthChecks("/hc", new HealthCheckOptions {
    Predicate = check => check.Tags.Contains("live")
});

兼容性考虑

对于必须使用中间件方式的场景,可以通过OpenTelemetry的Enrich功能手动添加路由属性:

builder.Services.AddOpenTelemetry()
    .WithMetrics(metrics => {
        metrics.AddAspNetCoreInstrumentation(options => {
            options.Enrich = (activity, eventName, rawObject) => {
                if(eventName == "OnStartActivity" && rawObject is HttpRequest request) {
                    if(request.Path.StartsWithSegments("/hc")) {
                        activity.SetTag("http.route", "/hc");
                    }
                }
            };
        });
    });

架构启示

这个案例很好地展示了ASP.NET Core从传统中间件模型向现代终结点路由系统的演进。开发者应当注意:

  1. 新项目应优先采用终结点路由方式
  2. 遗留系统迁移时要特别注意监控数据的完整性
  3. 理解监控工具对框架特性的依赖关系
登录后查看全文
热门项目推荐