跳转至

OpenTelemetry .NET

OpenTelemetry .NET Automatic Instrumentation 通过 CLR Profiler 和 Startup Hook 在运行时加载 SDK 与插桩库。无需修改业务代码,即可采集受支持的 ASP.NET、HTTP 客户端、数据库和消息系统等调用。

本文使用 DataKit 的 OpenTelemetry 采集器接收 OTLP 数据并转发到观测云:

.NET 应用 + OpenTelemetry .NET Automatic Instrumentation -> OTLP -> DataKit -> 观测云

前置条件

  • 使用微软仍在支持期内的 .NET 版本;.NET Framework 最低支持版本为 4.6.2;
  • 使用受支持的 x86、x64 或 ARM64 运行环境,其中 ARM64 支持仍为实验状态;
  • 已安装 DataKit,且 DataKit 已连接到目标观测云工作空间;
  • .NET 应用到 DataKit 的网络可达:OTLP/HTTP 使用 DataKit HTTP 端口 9529,OTLP/gRPC 默认使用 4317

版本支持

保留原文中的版本兼容信息,并以当前官方兼容性声明为最终依据:

.NET 版本 相关 Automatic Instrumentation 版本 说明
.NET 10 v1.13.0 起 v1.13.0 明确加入 .NET 10 支持。
.NET 9 v1.13.0 包含适配 v1.13.0 更新了 .NET 9 STS 生命周期相关规则。
.NET 8 v1.2.0 起 v1.2.0 明确加入 .NET 8 支持。
.NET 7 历史版本曾支持 .NET 7 已结束微软支持,不建议继续用于生产环境。
.NET Framework 4.6.2+ 通用兼容性要求 4.6.2 是当前自动插桩支持的最低 .NET Framework 版本。

安装时不要固定使用旧版 v1.2.0 模块地址,应使用本文提供的 releases/latest/download 官方地址获取当前版本。升级前建议查看 OpenTelemetry .NET Automatic Instrumentation Releases,并在测试环境验证目标应用和依赖。

一、开启 OpenTelemetry 采集器

进入 DataKit 安装目录下的 conf.d/opentelemetry。如果尚未创建采集器配置,复制示例文件:

cd /usr/local/datakit/conf.d/opentelemetry
sudo cp opentelemetry.conf.sample opentelemetry.conf

确认 opentelemetry.conf 至少包含以下接收配置:

[[inputs.opentelemetry]]
  # 将需要在观测云中作为标签保留的自定义属性加入白名单。
  customer_tags = ["team", "project"]

  [inputs.opentelemetry.http]
    http_status_ok = 200
    trace_api = "/otel/v1/traces"
    metric_api = "/otel/v1/metrics"
    logs_api = "/otel/v1/logs"

  [inputs.opentelemetry.grpc]
    addr = "127.0.0.1:4317"
    max_payload = 16777216

接收地址如下:

协议 数据类型 DataKit 接收地址
OTLP/HTTP + Protobuf Trace http://<DataKit-IP>:9529/otel/v1/traces
OTLP/HTTP + Protobuf Metric http://<DataKit-IP>:9529/otel/v1/metrics
OTLP/HTTP + Protobuf Log http://<DataKit-IP>:9529/otel/v1/logs
OTLP/gRPC Trace、Metric、Log http://<DataKit-IP>:4317

如果 .NET 应用与 DataKit 不在同一主机,需按实际部署调整 DataKit 监听地址、防火墙或其他网络访问控制。gRPC 可将 addr 改为应用可访问的监听地址,例如 0.0.0.0:4317。不要将 OTLP 接收端口直接暴露到公网。

重启 DataKit 并检查服务:

sudo datakit service restart
curl http://127.0.0.1:9529/v1/ping

二、应用接入 OpenTelemetry

Linux 和 macOS

从 OpenTelemetry 官方 GitHub Release 下载并执行最新安装脚本:

curl -sSfL \
  https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh \
  -O

sh ./otel-dotnet-auto-install.sh
chmod +x "$HOME/.otel-dotnet-auto/instrument.sh"

设置上报参数,并将自动插桩所需变量注入当前 Shell:

export OTEL_SERVICE_NAME="order-service"
export OTEL_RESOURCE_ATTRIBUTES="env=prod,version=1.0.0,team=backend"

export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="none"
export OTEL_LOGS_EXPORTER="none"

export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:9529/otel"
export OTEL_PROPAGATORS="tracecontext,baggage"

. "$HOME/.otel-dotnet-auto/instrument.sh"
./MyNetApp

通过 dotnet 启动 DLL 时,最后一行改为:

dotnet MyNetApp.dll

instrument.sh 只影响当前 Shell 及其子进程。systemd、Supervisor 或其他进程管理器场景中,需要在服务启动环境中加载该脚本并设置 OTEL_*,然后完整重启应用进程。

Windows PowerShell

使用管理员权限的 Windows PowerShell Desktop 5.1 执行。PowerShell Core 6.0 及以上版本目前不受安装模块支持:

#Requires -PSEdition Desktop

$moduleUrl = "https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/OpenTelemetry.DotNet.Auto.psm1"
$downloadPath = Join-Path $env:TEMP "OpenTelemetry.DotNet.Auto.psm1"

Invoke-WebRequest -Uri $moduleUrl -OutFile $downloadPath -UseBasicParsing
Import-Module $downloadPath -Force
Install-OpenTelemetryCore

$env:OTEL_SERVICE_NAME = "order-service"
$env:OTEL_RESOURCE_ATTRIBUTES = "env=prod,version=1.0.0,team=backend"
$env:OTEL_TRACES_EXPORTER = "otlp"
$env:OTEL_METRICS_EXPORTER = "none"
$env:OTEL_LOGS_EXPORTER = "none"
$env:OTEL_EXPORTER_OTLP_PROTOCOL = "http/protobuf"
$env:OTEL_EXPORTER_OTLP_ENDPOINT = "http://127.0.0.1:9529/otel"
$env:OTEL_PROPAGATORS = "tracecontext,baggage"

Register-OpenTelemetryForCurrentSession -OTelServiceName "order-service"
.\MyNetApp.exe

以上变量只作用于当前 PowerShell 会话和从该会话启动的子进程,不会自动影响已运行的 Windows Service 或 IIS 工作进程。

Windows 全局环境变量

原文提供了 Machine 级环境变量方案,适合需要统一配置多项上报参数的专用主机。以下命令只设置 OpenTelemetry 数据参数,不会代替 Register-OpenTelemetryForCurrentSessionRegister-OpenTelemetryForWindowsServiceRegister-OpenTelemetryForIIS 对目标进程执行自动插桩注册。

请使用管理员 PowerShell 执行:

[Environment]::SetEnvironmentVariable("OTEL_SERVICE_NAME", "order-service", "Machine")
[Environment]::SetEnvironmentVariable("OTEL_RESOURCE_ATTRIBUTES", "env=prod,version=1.0.0,team=backend", "Machine")
[Environment]::SetEnvironmentVariable("OTEL_TRACES_EXPORTER", "otlp", "Machine")
[Environment]::SetEnvironmentVariable("OTEL_METRICS_EXPORTER", "none", "Machine")
[Environment]::SetEnvironmentVariable("OTEL_LOGS_EXPORTER", "none", "Machine")
[Environment]::SetEnvironmentVariable("OTEL_EXPORTER_OTLP_PROTOCOL", "http/protobuf", "Machine")
[Environment]::SetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT", "http://127.0.0.1:9529/otel", "Machine")
[Environment]::SetEnvironmentVariable("OTEL_LOG_LEVEL", "info", "Machine")
[Environment]::SetEnvironmentVariable("OTEL_DOTNET_AUTO_LOGGER", "file", "Machine")
[Environment]::SetEnvironmentVariable(
  "OTEL_DOTNET_AUTO_LOG_DIRECTORY",
  "C:\ProgramData\OpenTelemetry .NET AutoInstrumentation\logs",
  "Machine"
)

检查 Machine 级变量:

$names = @(
  "OTEL_SERVICE_NAME",
  "OTEL_RESOURCE_ATTRIBUTES",
  "OTEL_TRACES_EXPORTER",
  "OTEL_METRICS_EXPORTER",
  "OTEL_LOGS_EXPORTER",
  "OTEL_EXPORTER_OTLP_PROTOCOL",
  "OTEL_EXPORTER_OTLP_ENDPOINT",
  "OTEL_LOG_LEVEL",
  "OTEL_DOTNET_AUTO_LOGGER",
  "OTEL_DOTNET_AUTO_LOG_DIRECTORY"
)

foreach ($name in $names) {
  "{0} = {1}" -f $name, [Environment]::GetEnvironmentVariable($name, "Machine")
}

Machine 级变量只会被新启动的进程读取。配置后需要重启目标 Windows Service、IIS Application Pool 或 IIS:

Restart-WebAppPool -Name "OrderAppPool"
# 或在确认影响范围后重启 IIS
iisreset

Machine 级配置会影响主机上的多个进程,不建议在共享主机上作为默认方案。优先使用当前会话、指定 Windows Service 或指定 IIS Application Pool 的配置方式。

Windows Service

安装核心文件后,可使用官方模块注册指定服务:

Import-Module $downloadPath -Force
Install-OpenTelemetryCore

Register-OpenTelemetryForWindowsService `
  -WindowsServiceName "OrderService" `
  -OTelServiceName "order-service"

Register-OpenTelemetryForWindowsService 会重启目标服务。还需确保数据上报所需的 OTEL_* 参数存在于该 Windows Service 的进程环境中;修改参数后再次重启服务。

IIS 中的 ASP.NET Framework

以下方式适用于托管在 IIS 中的 ASP.NET .NET Framework 应用:

Import-Module $downloadPath -Force
Install-OpenTelemetryCore
Register-OpenTelemetryForIIS

Register-OpenTelemetryForIIS 会重启 IIS。常用上报参数可写入应用的 Web.config

<configuration>
  <appSettings>
    <add key="OTEL_SERVICE_NAME" value="order-service" />
    <add key="OTEL_RESOURCE_ATTRIBUTES" value="env=prod,version=1.0.0,team=backend" />
    <add key="OTEL_TRACES_EXPORTER" value="otlp" />
    <add key="OTEL_METRICS_EXPORTER" value="none" />
    <add key="OTEL_LOGS_EXPORTER" value="none" />
    <add key="OTEL_EXPORTER_OTLP_PROTOCOL" value="http/protobuf" />
    <add key="OTEL_EXPORTER_OTLP_ENDPOINT" value="http://127.0.0.1:9529/otel" />
  </appSettings>
</configuration>

环境变量的优先级高于 App.configWeb.config。同一 IIS Application Pool 中的多个 .NET Framework 应用共享工作进程时,最先启动的应用会决定该进程使用的 OpenTelemetry SDK 配置;需要独立服务名和上报参数时,应使用独立应用池。

IIS Application Pool 定点配置

原文还提供了直接在 applicationHost.config 中为指定 Application Pool 设置环境变量的方式,适合只采集部分站点。修改前应备份:

C:\Windows\System32\inetsrv\config\applicationHost.config

<system.applicationHost> 下找到 <applicationPools>,向目标应用池的 <add> 节点加入:

<applicationPools>
  <add name="OrderAppPool">
    <environmentVariables>
      <add name="OTEL_SERVICE_NAME" value="order-service" />
      <add name="OTEL_RESOURCE_ATTRIBUTES" value="env=prod,version=1.0.0,team=backend" />
      <add name="OTEL_TRACES_EXPORTER" value="otlp" />
      <add name="OTEL_METRICS_EXPORTER" value="none" />
      <add name="OTEL_LOGS_EXPORTER" value="none" />
      <add name="OTEL_EXPORTER_OTLP_PROTOCOL" value="http/protobuf" />
      <add name="OTEL_EXPORTER_OTLP_ENDPOINT" value="http://127.0.0.1:9529/otel" />
      <add name="OTEL_LOG_LEVEL" value="info" />
      <add name="OTEL_DOTNET_AUTO_LOGGER" value="file" />
      <add
        name="OTEL_DOTNET_AUTO_LOG_DIRECTORY"
        value="C:\ProgramData\OpenTelemetry .NET AutoInstrumentation\logs" />
    </environmentVariables>
  </add>
</applicationPools>

完成配置后重启目标 Application Pool。Application Pool 级环境变量会覆盖同名的 Machine 级变量;如果希望统一使用全局值,需要删除或调整应用池中的同名 OTEL_*。该配置同样只负责参数作用域,IIS 自动插桩仍需先执行 Register-OpenTelemetryForIIS

OTLP/gRPC 限制

.NET Automatic Instrumentation 默认使用 http/protobuf,推荐使用前面的 HTTP 配置接入 DataKit。.NET Framework 不支持 OTLP/gRPC;.NET 8 及以上使用 gRPC 时,应用还必须引用兼容的 Grpc.Net.Client 包,因此不再是完全不改依赖的接入方式。

三、数据上报参数

基础参数

环境变量 说明 建议值或示例
OTEL_SERVICE_NAME 设置 service.name;未设置时自动插桩会根据应用生成名称。 order-service,生产环境建议显式设置。
OTEL_RESOURCE_ATTRIBUTES 资源属性,格式为逗号分隔的 key=value env=prod,version=1.0.0,team=backend
OTEL_TRACES_EXPORTER Trace 导出器。 上报到 DataKit 时设为 otlp;关闭时设为 none
OTEL_METRICS_EXPORTER Metric 导出器。 需要上报指标时设为 otlp,否则设为 none
OTEL_LOGS_EXPORTER Log 导出器。 需要上报日志时设为 otlp,否则设为 none
OTEL_PROPAGATORS 跨服务上下文传播格式。 默认 tracecontext,baggage;还支持 b3b3multi
OTEL_SDK_DISABLED 禁用 OpenTelemetry SDK。 默认 false;应急关闭时设为 true

service.name 用于观测云中的服务归属;建议同时设置 envversion,用于按环境和版本筛选。其他自定义资源属性需要加入 DataKit customer_tags 白名单后才会作为标签保留,属性名中的 . 会转换为 _

.NET 自动插桩参数

环境变量 说明 默认值或示例
OTEL_DOTNET_AUTO_TRACES_ENABLED 启用自动 Trace 管道。 默认 true
OTEL_DOTNET_AUTO_METRICS_ENABLED 启用自动 Metric 管道。 默认 true;即使 exporter 为 none,也可设为 false 进一步关闭。
OTEL_DOTNET_AUTO_LOGS_ENABLED 启用自动 Log 管道。 默认 true;不采集 OTLP Log 时可设为 false
OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES 排除不应加载自动插桩的进程,多个可执行文件名用逗号分隔。 powershell.exe,ReservedProcess.exe;不要排除承载目标应用的 dotnet 进程。
OTEL_DOTNET_AUTO_RESOURCE_DETECTOR_ENABLED 启用自动插桩内置资源探测器。 默认 true
OTEL_DOTNET_AUTO_LOGGER 自动插桩内部诊断日志输出方式。 默认 file;还支持 consolenone
OTEL_DOTNET_AUTO_LOG_DIRECTORY 自动插桩内部日志目录。 Windows 默认位于 %ProgramData% 下;Linux/macOS 默认 /var/log/opentelemetry/dotnet
OTEL_LOG_LEVEL SDK 和自动插桩日志级别。 默认 info;排障时短暂使用 debug

不要在系统或用户级别全局启用 CLR Profiler,除非已明确评估主机上的所有 .NET 进程。全局注入可能影响 dotnet CLI、PowerShell 或其他非目标服务;优先使用当前会话、指定 Windows Service 或指定 IIS 场景的注册方式。

OTLP 参数

环境变量 说明 建议值或示例
OTEL_EXPORTER_OTLP_PROTOCOL 所有信号的 OTLP 协议。 自动插桩默认 http/protobuf;推荐显式设置。
OTEL_EXPORTER_OTLP_ENDPOINT 所有信号共用的基础地址。 HTTP:http://datakit-host:9529/otel
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT 仅 Trace 使用的地址,优先于共用地址。 http://datakit-host:9529/otel/v1/traces
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT 仅 Metric 使用的地址,优先于共用地址。 http://datakit-host:9529/otel/v1/metrics
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT 仅 Log 使用的地址,优先于共用地址。 http://datakit-host:9529/otel/v1/logs
OTEL_EXPORTER_OTLP_HEADERS 所有 OTLP 请求携带的请求头,多个值用逗号分隔。 x-tenant=tenant-a;需与 DataKit expected_headers 一致。
OTEL_EXPORTER_OTLP_COMPRESSION OTLP 请求压缩方式。 默认 none;跨主机上报可设为 gzip
OTEL_EXPORTER_OTLP_TIMEOUT 单次导出超时,单位毫秒。 默认 10000

DataKit 的 OTLP/HTTP 采集仅支持 Protobuf,请使用 http/protobuf,不要使用 http/json。统一 endpoint 与某类数据的 endpoint 同时存在时,某类数据的配置优先。

采样和批量上报参数

环境变量 说明 默认值或示例
OTEL_TRACES_SAMPLER Trace 头部采样器。 默认 parentbased_always_on;按比例采样使用 parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG 采样器参数。 0.1 表示根 Trace 采样 10%。
OTEL_BSP_SCHEDULE_DELAY Span 批量导出间隔,单位毫秒。 默认 5000
OTEL_BSP_MAX_QUEUE_SIZE 待导出的 Span 队列上限。 默认 2048
OTEL_BSP_MAX_EXPORT_BATCH_SIZE 每批最多导出的 Span 数。 默认 512
OTEL_BSP_EXPORT_TIMEOUT Span 批量导出超时,单位毫秒。 默认 30000
OTEL_METRIC_EXPORT_INTERVAL Metric 导出间隔,单位毫秒。 OTLP exporter 默认 60000

生产环境应根据流量和数据预算设置采样率。应用侧头部采样与 DataKit 侧采样同时开启时,最终保留率会叠加降低,应统一规划采样位置。

验证接入

请求一个经过受支持插桩库处理的应用路由,然后在 DataKit 主机检查接收日志:

curl http://127.0.0.1:8080/
sudo tail -f /usr/local/datakit/log/gin.log | grep '/otel/v1/'

出现 /otel/v1/tracesPOST 请求且响应码为 200,表示 DataKit 已接收 Trace。然后进入观测云的「应用性能监测 > 链路」按 service:order-service 查询。

如果没有数据,依次检查:安装脚本是否完成、启动应用的实际进程是否继承 CLR Profiler 和 OTEL_* 环境变量、应用使用的库是否在支持列表中,以及 OTLP endpoint 是否可达。可临时设置 OTEL_LOG_LEVEL=debug,并检查自动插桩内部日志;排障完成后恢复为 info

参考

文档评价

文档内容是否对您有帮助? ×