OpenTelemetry .NET¶
OpenTelemetry .NET Automatic Instrumentation 通过 CLR Profiler 和 Startup Hook 在运行时加载 SDK 与插桩库。无需修改业务代码,即可采集受支持的 ASP.NET、HTTP 客户端、数据库和消息系统等调用。
本文使用 DataKit 的 OpenTelemetry 采集器接收 OTLP 数据并转发到观测云:
前置条件¶
- 使用微软仍在支持期内的 .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。如果尚未创建采集器配置,复制示例文件:
确认 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 并检查服务:
二、应用接入 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 时,最后一行改为:
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-OpenTelemetryForCurrentSession、Register-OpenTelemetryForWindowsService 或 Register-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:
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 应用:
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.config 或 Web.config。同一 IIS Application Pool 中的多个 .NET Framework 应用共享工作进程时,最先启动的应用会决定该进程使用的 OpenTelemetry SDK 配置;需要独立服务名和上报参数时,应使用独立应用池。
IIS Application Pool 定点配置¶
原文还提供了直接在 applicationHost.config 中为指定 Application Pool 设置环境变量的方式,适合只采集部分站点。修改前应备份:
在 <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;还支持 b3、b3multi。 |
OTEL_SDK_DISABLED |
禁用 OpenTelemetry SDK。 | 默认 false;应急关闭时设为 true。 |
service.name 用于观测云中的服务归属;建议同时设置 env 和 version,用于按环境和版本筛选。其他自定义资源属性需要加入 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;还支持 console、none。 |
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 主机检查接收日志:
出现 /otel/v1/traces 的 POST 请求且响应码为 200,表示 DataKit 已接收 Trace。然后进入观测云的「应用性能监测 > 链路」按 service:order-service 查询。
如果没有数据,依次检查:安装脚本是否完成、启动应用的实际进程是否继承 CLR Profiler 和 OTEL_* 环境变量、应用使用的库是否在支持列表中,以及 OTLP endpoint 是否可达。可临时设置 OTEL_LOG_LEVEL=debug,并检查自动插桩内部日志;排障完成后恢复为 info。