dotnet-counters monitor 连不上进程的主因是目标进程未启用 eventpipe,常见于容器或精简运行时环境;需确认应用为 .net core 3.1+ 或 .net 5+,检查 dotnet_no_eventpipe=1 是否被设置,并验证 ptrace 权限(linux/macos)及提供程序是否已注册并激活。

直接用 dotnet-counters 就行,别绕到 PerformanceCounter 或手动 P/Invoke——它专为 .NET 运行时设计,跨平台、零权限、不侵入代码,且数据源和 ASP.NET Core / Worker Service 内置指标完全对齐。
dotnet-counters monitor 命令为什么连不上进程?
常见现象是报错 Failed to connect to process [12345] 或卡住不动。根本原因不是工具问题,而是目标进程没启用 EventPipe(.NET Core 3.0+ 默认开启,但某些容器或精简运行时可能关闭)。
- 确认目标应用用的是 .NET Core 3.1+ 或 .NET 5+;旧版 .NET Framework 不支持
- 启动应用时加环境变量强制启用:
DOTNET_STARTUP_HOOKS=(清空该变量防干扰),或确保没设DOTNET_NO_EVENTPIPE=1 - Linux/macOS 下若进程由 systemd 或 docker 启动,检查是否禁用了 ptrace(如
ptrace_scope=2);临时修复:echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope - 用
dotnet counters list能看到进程,但monitor失败?大概率是进程已进入“退出中”状态(比如刚调了Environment.Exit()),此时 EventPipe 已关闭
监控 System.Runtime 以外的计数器(如 ASP.NET Core 请求量)
System.Runtime 是默认提供程序,但像 Microsoft.AspNetCore.Hosting、MyApp.Metrics 这类自定义计数器必须显式指定,否则 dotnet-counters 根本不会采集。
- 先查目标进程暴露了哪些提供程序:
dotnet-counters list -p 12345(注意看输出里的 “Provider Name” 列) - 监控多个提供程序时,用逗号分隔:
dotnet counters monitor -p 12345 --counters System.Runtime,Microsoft.AspNetCore.Hosting - 自定义提供程序需在代码中注册
EventSource并调用EventCounter;如果没看到你的提供程序名,说明它没被加载或没触发首次计数(比如 Hosting 计数器只在第一个 HTTP 请求后才激活) - Windows 上可用
PerfView验证提供程序是否真在发事件:打开 PerfView → Collect → Enable Providers → 输入提供程序名 → Start Collection
dotnet-counters 输出数值跳变大或为负数?
这不是 bug,是差分计数器的正常行为。比如 GC 次数、请求总数这类单调递增计数器,在进程回收/重载/崩溃重启后,新实例的初始值可能比上一个低,导致差值为负。
- 跳变常见于短生命周期进程(如 CLI 工具、函数即服务);长期运行的服务一般稳定
- CPU 和内存类指标(如
% Time in GC、Working Set)本身是瞬时快照,波动属正常;但若持续为 0 或 NaN,检查是否用了错误的实例名(如"_Total"写成"_total") - 导出
nettrace文件做离线分析可规避实时跳变干扰:dotnet-counters collect -p 12345 --format nettrace -o trace.nettrace,再用dotnet-trace或 PerfView 解析 - 生产环境别依赖单次
NextValue()结果做告警;应取滑动窗口均值(如最近 30 秒内每秒采样值的中位数)
为什么不用 PerformanceCounter 替代 dotnet-counters?
因为两者定位完全不同:PerformanceCounter 是 Windows 系统级性能计数器,面向整个 OS;dotnet-counters 是 .NET 运行时级事件管道,只反映托管代码行为。
- 想看“这个 .NET 进程到底分配了多少内存”,用
dotnet-counters的GC Heap Size;想看“这台机器物理内存还剩多少”,才用PerformanceCounter("Memory", "Available MBytes", null) -
PerformanceCounter在 Linux/macOS 上不可用(除非用 Mono 兼容层,但不稳定);而dotnet-counters原生支持三端 - 监控 ASP.NET Core 的
Requests In Progress或 EF Core 的Active Connections,这些指标PerformanceCounter根本没有对应项 - 最易被忽略的一点:如果你的应用跑在 Docker 容器里且没加
--cap-add=SYS_PTRACE,PerformanceCounter可能全失效,但dotnet-counters仍能工作(靠 EventPipe,不依赖 ptrace)











