Skip to content

Latest commit

 

History

History
258 lines (204 loc) · 12.2 KB

File metadata and controls

258 lines (204 loc) · 12.2 KB

Mud.HttpUtils.OpenTelemetry

概述

Mud.HttpUtils.OpenTelemetry 是 Mud.HttpUtils 的 OpenTelemetry 适配包,提供 一键开启 Mud.HttpUtils 内置的分布式追踪(Tracing)与指标(Metrics)采集能力,并自动关联 .NET HttpClient 与 ASP.NET Core 的内置 Instrumentation。

目标框架

  • netstandard2.0
  • net8.0
  • net10.0

关于 net6.0:本包不提供 net6.0 资产。其依赖 OpenTelemetry 1.16.0 已不再提供 net6.0 资产, 最接近的资产是 netstandard2.0,而该资产声明依赖 Microsoft.Extensions.* 10.0.0(官方不支持 net6.0)。net6.0 应用消费本包时由 NuGet 自动回落选择 netstandard2.0 资产,功能完全一致 (本包源码不含任何 TFM 相关的行为分支,net6.0 与 netstandard2.0 资产本就针对同一组引用程序集编译)。

安装

<PackageReference Include="Mud.HttpUtils.OpenTelemetry" Version="x.x.x" />

快速开始

1. ASP.NET Core 主机

var builder = WebApplication.CreateBuilder(args);

// 注册 Mud.HttpUtils 客户端(详见 Mud.HttpUtils.Client 文档)
builder.Services.AddMudHttpClient("myApi", c =>
{
    c.BaseAddress = new Uri("https://api.example.com");
});

// 一键开启 Mud.HttpUtils 的 OpenTelemetry 追踪与指标
builder.Services.AddMudHttpOpenTelemetry(options =>
{
    options.OtlpEndpoint = new Uri("http://otel-collector:4317");
});

var app = builder.Build();
app.Run();

2. 控制台应用

var services = new ServiceCollection();
services.AddLogging();
services.AddMudHttpClient("myApi", c => c.BaseAddress = new Uri("https://api.example.com"));
services.AddMudHttpOpenTelemetry();

using var provider = services.BuildServiceProvider();
// 使用 IHttpClientFactory 或 IEnhancedHttpClientFactory 发起请求

配置选项

MudHttpOpenTelemetryOptions

属性 类型 默认值 说明
EnableTracing bool true 是否启用分布式追踪
EnableMetrics bool true 是否启用指标采集
EnableLogging bool false 是否启用 OTLP 日志导出(向后兼容;依赖 .NET 8+ 的 ILogger 集成)
EnableHttpClientInstrumentation bool true 关联 .NET HttpClient 内置 ActivitySource
EnableAspNetCoreInstrumentation bool true 启用 ASP.NET Core 入站请求 Instrumentation(控制台应用无效)
OtlpEndpoint Uri? http://localhost:4317 OTLP 导出端点,null 表示不配置 OTLP 导出器
OtlpExportProtocol OtlpExportProtocol Grpc OTLP 导出协议(Grpc 或 HttpProtobuf)
UseShortExporterTimeout bool false 是否使用 5 秒短超时(开发调试用)
ServiceName string "Mud.HttpUtils.Application" OTel Resource 属性 service.name
ServiceVersion string MudHttpActivitySource.Version OTel Resource 属性 service.version
DeploymentEnvironment string "production" OTel Resource 属性 deployment.environment
SamplingRatio double 1.0 采样比率(0.01.0),生产环境建议 0.10.3。超出范围将在启动时抛出 ArgumentOutOfRangeException
ExportBatchSize int? null OTLP 每批导出最大条目数(映射到 BatchExportProcessorOptions.MaxExportBatchSize):null 或 0 = 使用 SDK 默认值(512),仅 >0 生效;负数启动期抛 OptionsValidationException
ExportIntervalMilliseconds int? null OTLP 批量导出间隔毫秒数(映射到 BatchExportProcessorOptions.ScheduledDelayMilliseconds):null 或 0 = 使用 SDK 默认值(5000ms),仅 >0 生效;负数启动期抛 OptionsValidationException
OtlpHeaders IDictionary<string, string>? null 自定义 OTLP Headers(如认证头)
ConfigureTracing Action<TracerProviderBuilder>? null 自定义追踪配置委托,在 Mud 默认配置之后执行
ConfigureMetrics Action<MeterProviderBuilder>? null 自定义指标配置委托,在 Mud 默认配置之后执行
ConfigureLogging Action<LoggerProviderBuilder>? null 自定义日志配置委托,在 Mud 默认配置之后执行

OtlpExportProtocol 枚举:本包自定义了 OtlpExportProtocol(Grpc = 0、HttpProtobuf = 1),用于覆盖 OpenTelemetry SDK 的同名类型。可通过 options.OtlpExportProtocol 指定导出协议。

批量导出配置范围:ExportBatchSize / ExportIntervalMilliseconds 仅作用于 Tracing(Activity)的 BatchExportProcessorOptions,不影响 Metrics / Logs 的导出节奏。

EnableHttpClientInstrumentation:同时控制 Tracing 与 Metrics 两侧的 .NET HttpClient 关联(AddHttpClientInstrumentation),不仅关联 ActivitySource。

AddMudHttpOpenTelemetry 的两个重载均返回 OpenTelemetryBuilder,可继续链式追加配置;IConfiguration 重载的 sectionPath 参数默认值为 "MudHttpOpenTelemetry",可自定义绑定节点路径。

从 IConfiguration 绑定

除代码配置外,还支持从 appsettings.json 绑定选项:

builder.Services.AddMudHttpOpenTelemetry(builder.Configuration);

对应 appsettings.json:

{
  "MudHttpOpenTelemetry": {
    "ServiceName": "my-service",
    "ServiceVersion": "1.0.0",
    "DeploymentEnvironment": "production",
    "SamplingRatio": 0.1,
    "EnableTracing": true,
    "EnableMetrics": true,
    "EnableLogging": false,
    "EnableHttpClientInstrumentation": true,
    "EnableAspNetCoreInstrumentation": true,
    "OtlpEndpoint": "http://otel-collector:4317",
    "OtlpExportProtocol": "Grpc",
    "ExportBatchSize": 256,
    "ExportIntervalMilliseconds": 5000,
    "OtlpHeaders": {
      "Authorization": "Bearer my-token"
    }
  }
}

也可同时使用配置绑定和代码配置:AddMudHttpOpenTelemetry(builder.Configuration, configure: options => { ... }),代码配置在配置绑定之后执行,可覆盖绑定值。

热更新限制:OpenTelemetry 配置在应用启动时一次性读取,不支持 IOptionsMonitor 热更新。这是因为 OpenTelemetry SDK 的 TracerProvider/MeterProvider 在构建后不可变。修改 appsettings.json 中的 MudHttpOpenTelemetry 节后需重启应用才能生效。如需运行时可变配置,请使用 AddMudHttpOpenTelemetry(Action<MudHttpOpenTelemetryOptions>?) 重载并在自定义委托中读取动态配置源。

高级配置示例

builder.Services.AddMudHttpOpenTelemetry(options =>
{
    options.OtlpEndpoint = new Uri("http://otel-collector:4318");
    options.OtlpExportProtocol = OtlpExportProtocol.HttpProtobuf;
    options.EnableAspNetCoreInstrumentation = false;

    // 追加自定义 ActivitySource
    options.ConfigureTracing = tp => tp.AddSource("MyApp.Business");

    // 追加 Prometheus 导出器(需额外引用 OpenTelemetry.Exporter.Prometheus.AspNetCore)
    options.ConfigureMetrics = mp => mp.AddPrometheusExporter();
});

自动采集的内容

追踪(Tracing)

ActivitySource 用途
Mud.HttpUtils.HttpClient Mud.HttpUtils 出站 HTTP 请求活动(含 method/url/status/duration)
System.Net.Http(.NET 内置) .NET HttpClient 底层 socket 活动
Microsoft.AspNetCore ASP.NET Core 入站请求活动(由 OpenTelemetry.Instrumentation.AspNetCore 采集)

DiagnosticSource / Span 事件(Listener:Mud.HttpUtils.HttpClient):RequestStarted、RequestStopped、RequestFailed、RetryOccurred、TimeoutOccurred、CircuitBreakerStateChanged、CacheHit、CacheMiss、TokenRefreshed、DownloadStarted、DownloadCompleted、DownloadFailed。

outcome 语义:4xx → client_error 且 Span 设 Ok;5xx / 网络错误 → error(Span Error);取消 → cancelled,Span 不设 Error。

指标(Metrics)

Meter 指标 说明
Mud.HttpUtils.HttpClient mud.http.requests HTTP 请求计数
Mud.HttpUtils.HttpClient mud.http.request.duration HTTP 请求耗时直方图(ms)
Mud.HttpUtils.HttpClient mud.http.cache 缓存命中/未命中计数
Mud.HttpUtils.HttpClient mud.token.refresh 令牌刷新次数
Mud.HttpUtils.HttpClient mud.token.refresh.duration 令牌刷新耗时直方图(ms)
Mud.HttpUtils.HttpClient mud.http.retry 重试次数
Mud.HttpUtils.HttpClient mud.http.circuit_breaker.state 熔断器状态 Gauge
Mud.HttpUtils.HttpClient mud.token.recovery 令牌恢复(401 重试)次数与结果
Mud.HttpUtils.HttpClient mud.token.refresh.suppressed 失败负缓存窗口抑制的刷新次数
Mud.HttpUtils.HttpClient mud.http.download.bytes 下载字节数
Mud.HttpUtils.HttpClient mud.http.download.duration 下载耗时直方图(ms,仅响应体下载阶段)
System.Net.Http(.NET 内置) http.client.* .NET HttpClient 内置指标

遥测脱敏与高基数治理(默认开启)

MudHttpObservabilityOptions(静态开关,建议进程启动时设置):

开关 默认 说明
RedactUrlInTelemetry true Span tag / 日志 / 诊断事件中的 URL 掩码 access_token 等敏感 query 值
RecordFullUrlOnSuccess false 成功请求仅记录 scheme://host/path;错误路径始终保留完整 URI,由 IExceptionRedactor 兜底擦除
EmitDiagnosticEvents true 诊断事件(ActivityEvent / DiagnosticSource)总开关
MetricTagAllowlist 全部内建维度 指标 tag 白名单:client_name / method / host / outcome / status_code / policy_key / token_manager_key / retry_count,白名单外维度丢弃
// 设置示例(进程启动时)
MudHttpObservabilityOptions.RedactUrlInTelemetry = true;
MudHttpObservabilityOptions.RecordFullUrlOnSuccess = false;
MudHttpObservabilityOptions.EmitDiagnosticEvents = true;
MudHttpObservabilityOptions.MetricTagAllowlist = new HashSet<string> { "client_name", "outcome" }; // 收缩维度、降低基数

与健康检查配合

AddMudHttpOpenTelemetry 与 AddMudHttpHealthChecks 可同时使用(AddMudHttpHealthChecks 定义于 Mud.HttpUtils.Client 包,需同时安装 Client 包):

builder.Services.AddMudHttpClient("myApi", c => c.BaseAddress = new Uri("https://api.example.com"));
builder.Services.AddMudHttpHealthChecks();
builder.Services.AddMudHttpOpenTelemetry();

设计原则

  • 零侵入:用户代码无需任何改动,仅在 DI 注册时调用一次扩展方法
  • 可观测性零开销:无监听器时 ActivitySource.StartActivity 返回 null,Counter.Add 直接短路
  • 默认即生产可用:默认开启 Tracing + Metrics + OTLP gRPC 导出至本地 4317
  • 可扩展:通过 ConfigureTracing / ConfigureMetrics 委托追加自定义配置
  • AOT 兼容:委托式重载无反射;IConfiguration 绑定依赖 ConfigurationBinder(反射),AOT 场景请使用 Action<MudHttpOpenTelemetryOptions> 委托重载

依赖项

包 版本 说明
Mud.HttpUtils.Abstractions — 提供 MudHttpActivitySource / MudHttpMeter 静态源
OpenTelemetry 1.16.0 OpenTelemetry SDK 核心
OpenTelemetry.Extensions.Hosting 1.16.0 DI 集成扩展
OpenTelemetry.Exporter.OpenTelemetryProtocol 1.16.0 OTLP 导出器
OpenTelemetry.Instrumentation.Http 1.16.0 HttpClient Instrumentation
OpenTelemetry.Instrumentation.AspNetCore 1.16.0 ASP.NET Core Instrumentation

部署 OTLP 收集器

最简 Jaeger 部署(接收 OTLP gRPC 4317):

docker run -d --name jaeger \
  -p 16686:16686 \
  -p 4317:4317 \
  jaegertracing/all-in-one:1.62

启动应用后访问 http://localhost:16686 查看 Mud.HttpUtils 出站请求 span。

Prometheus + Grafana 抓取 Mud.HttpUtils.HttpClient Meter:

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
exporters:
  prometheus:
    endpoint: 0.0.0.0:8889
service:
  pipelines:
    metrics:
      receivers: [otlp]
      exporters: [prometheus]
    traces:
      receivers: [otlp]
      exporters: [otlp]  # 转发至 Jaeger