后端与接口
在 ASP.NET Core 中配置…
当需要为 ASP.NET Core 应用添加可观测性、配置 OTLP 导出器、创建自定义指标/跨度或排查分布式追踪关联问题时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 ASP.NET Core 中配置 O通用
解决思路
- 安装正确的 NuGet 包:OpenTelemetry.Extensions.Hosting、OpenTelemetry.Instrumentation.AspNetCore、OpenTelemetry.Instrumentation.Http,以及导出器 OpenTelemetry.Exporter.OpenTelemetryProtocol(用于 traces、metrics 和 logs)。不要只安装 OpenTelemetry 包,必须安装 OpenTelemetry.Extensions.Hosting 以获得正确的 DI 集成。
- 仅在开发/本地调试时可选安装 OpenTelemetry.Exporter.Console,不要包含在生产部署中。
- 按应用实际使用的库选择性安装额外的自动埋点包:OpenTelemetry.Instrumentation.SqlClient(SQL Server 查询)、OpenTelemetry.Instrumentation.EntityFrameworkCore(EF Core)、OpenTelemetry.Instrumentation.GrpcNetClient(gRPC 调用)、OpenTelemetry.Instrumentation.Runtime(GC、线程池指标)。
- 在 Program.cs 中通过 builder.Services.AddOpenTelemetry() 配置所有信号:用 ConfigureResource 设置 AddService(serviceName: builder.Environment.ApplicationName)。
- 在 WithTracing 中调用 AddAspNetCoreInstrumentation 并通过 options.Filter 过滤掉健康检查端点(如 /healthz);调用 AddHttpClientInstrumentation 并设置 options.RecordException = true;如直接使用 SqlClient,可调用 AddSqlClientInstrumentation 并设置 SetDbStatementForText = true 和 RecordException = true。
- 在 WithTracing 中通过 AddSource("MyApp.Orders")、AddSource("MyApp.Payments")、AddSource("MyApp.Messaging") 注册自定义 ActivitySource 名称,必须与代码中的名称完全匹配。
- 在 WithMetrics 中调用 AddAspNetCoreInstrumentation 和 AddHttpClientInstrumentation;可选调用 AddRuntimeInstrumentation 获取 GC 和线程池指标(需安装 OpenTelemetry.Instrumentation.Runtime 包);通过 AddMeter("MyApp.Metrics") 注册自定义 Meter 名称。
- 在 WithLogging 中设置 logging.IncludeScopes = true;如需在日志导出中包含格式化消息字符串,可启用 logging.IncludeFormattedMessage = true。
- 调用 UseOtlpExporter() 为所有信号使用单一 OTLP 导出器,它会读取 OTEL_EXPORTER_OTLP_ENDPOINT 环境变量(默认 http://localhost:4317),可通过环境变量或 appsettings.json 覆盖。
- 理解日志-追踪关联:WithLogging() 会将 ILogger 与 OpenTelemetry 集成,每条日志自动包含 TraceId 和 SpanId,ConfigureResource 中的服务资源会自动传播到日志,UseOtlpExporter() 同时应用于日志、追踪和指标,无需额外包或单独的 SetResourceBuilder 调用。
- 创建自定义跨度:定义静态 ActivitySource(名称与 AddSource 注册一致),使用 ActivitySource.StartActivity("ProcessOrder") 启动跨度,用 activity?.SetTag() 添加属性,用 ActivityKind.Client 标记出站调用,用 SetStatus(ActivityStatusCode.Ok) 或 SetStatus(ActivityStatusCode.Error, ex.Message) 设置状态。
- 异常处理时优先通过 ILogger.LogError 记录异常(OpenTelemetry 会带追踪关联捕获),而非 activity.RecordException(),因为 OTel 正在弃用跨度事件记录异常,转而采用基于日志的异常记录。
- 创建自定义指标:通过 DI 注入 IMeterFactory,用 meterFactory.Create("MyApp.Metrics") 创建 Meter(名称与 AddMeter 注册一致)。用 CreateCounter<long> 记录只增不减的值,用 CreateHistogram<double> 记录分布(延迟、大小),用 CreateUpDownCounter<int> 记录可增可减的值。
- 记录指标时使用 TagList 添加维度标签(如 region、order.type)以支持按维度过滤。在 DI 中注册指标类:builder.Services.AddSingleton<OrderMetrics>()。
- 配置分布式场景的上下文传播:使用 AddHttpClientInstrumentation() 时 HTTP 调用的追踪上下文传播是自动的。对于非 HTTP 场景(如消息队列),在发送端用 Propagators.DefaultTextMapPropagator.Inject 将当前 Activity 上下文和 Baggage 注入到 carrier 字典中并作为消息头发送;在接收端用 propagator.Extract 提取父上下文,设置 Baggage.Current,并用 MessageSource.StartActivity("ProcessMessage", ActivityKind.Consumer, parentContext.ActivityContext) 链接到父追踪。
- 验证配置:确认追踪出现在可观测性后端(Jaeger、Aspire dashboard 等);HTTP 请求自动创建带正确 verb、URL、状态码的跨度;自定义 ActivitySource 名称与 AddSource() 注册匹配;自定义 Meter 名称与 AddMeter() 注册匹配;日志包含 TraceId 和 SpanId;健康检查端点已从追踪中过滤;错误跨度上出现异常详情。
- 排查常见问题:ActivitySource.StartActivity 返回 null 说明源名称与 AddSource() 不匹配(必须完全一致);追踪未出现在导出器中检查 OTLP 端点(gRPC 用 4317,HTTP 用 4318);缺少 HTTP 客户端跨度确保注册了 AddHttpClientInstrumentation();避免高基数标签(不要用用户 ID、请求 ID 或 UUID 作为指标标签);OTLP gRPC 与 HTTP 不匹配时默认是 gRPC(4317),如收集器只接受 HTTP 则设置 OtlpExportProtocol.HttpProtobuf;ActivitySource 应为静态,Meter 应通过 DI 的 IMeterFactory 创建(不要用 new Meter())以确保生命周期管理和可测试性。
适用边界 · 注意事项
- 用户只需要应用级日志(应使用 ILogger、Serilog)
- 用户直接使用 Application Insights SDK(API 不同)
- 用户需要商业厂商专有 SDK 的 APM