Layout.WatchDog.NET.OpenTelemetry
1.5.0-beta.7
dotnet add package Layout.WatchDog.NET.OpenTelemetry --version 1.5.0-beta.7
NuGet\Install-Package Layout.WatchDog.NET.OpenTelemetry -Version 1.5.0-beta.7
<PackageReference Include="Layout.WatchDog.NET.OpenTelemetry" Version="1.5.0-beta.7" />
<PackageVersion Include="Layout.WatchDog.NET.OpenTelemetry" Version="1.5.0-beta.7" />
<PackageReference Include="Layout.WatchDog.NET.OpenTelemetry" />
paket add Layout.WatchDog.NET.OpenTelemetry --version 1.5.0-beta.7
#r "nuget: Layout.WatchDog.NET.OpenTelemetry, 1.5.0-beta.7"
#:package Layout.WatchDog.NET.OpenTelemetry@1.5.0-beta.7
#addin nuget:?package=Layout.WatchDog.NET.OpenTelemetry&version=1.5.0-beta.7&prerelease
#tool nuget:?package=Layout.WatchDog.NET.OpenTelemetry&version=1.5.0-beta.7&prerelease
WatchDog.OpenTelemetry
可选扩展包 Layout.WatchDog.NET.OpenTelemetry,目标框架 net8.0 / net10.0,
依赖 OpenTelemetry SDK、Hosting、OTLP Exporter 1.20.1。
WatchDog 作为指标生产端,持续采集当前宿主可见的节点和进程资源,通过标准 OTLP 向外发送 Metrics。 本包不提供 OTLP 接收端、历史数据库、历史查询 API,也不启用 Logs / Traces 导出。 已有看板仍使用快照接口和浏览器短期缓存。
交互助手可通过 MCP 的可选 get_resource_snapshot 工具复用本包的持续采样缓存,不会因工具调用增加采样。
IWatchDogMetricsSnapshotProvider.GetSnapshotInfo() 同时返回缓存内容、单调时钟计算的年龄与有效期;
原有 GetSnapshot() 行为保留。未实现新方法的自定义提供商仍可使用默认实现,由工具校验样本 UTC 时间。
资源问答的开关、过期与缺失语义见 Agent 接入指南。
安装与接入
dotnet add package Layout.WatchDog.NET.OpenTelemetry --version 1.5.0-beta.7
using OpenTelemetry.Exporter;
using OpenTelemetry.Resources;
using WatchDog;
using WatchDog.OpenTelemetry;
builder.Services.AddWatchDog(wd => wd.WithAuth("admin", "your-password"));
builder.Services.AddOpenTelemetry().ConfigureResource(resource => resource.AddService(
"orders-api", serviceInstanceId: Guid.NewGuid().ToString("N")));
// 必须在 AddWatchDog 后调用,且只调用一次。
builder.Services.AddWatchDogOpenTelemetry(
configure: options =>
{
options.SampleInterval = TimeSpan.FromSeconds(2);
options.ExportIntervalMilliseconds = 10_000;
},
configureOtlpExporter: exporter =>
{
exporter.Protocol = OtlpExportProtocol.HttpProtobuf;
exporter.Endpoint = new Uri("http://localhost:4318/v1/metrics");
});
ASP.NET Core 宿主按原有方式调用 app.UseWatchDog();导出本身不需要新增任何 HTTP 端点。
Generic Host 也能通过 AddWatchDog + AddWatchDogOpenTelemetry 运行采样与导出。
Dashboard.Features.Metrics 只控制看板 API 是否开放,不控制后台采集和导出。
配置与已有 OTel 管线
| 配置项 | 默认值 / 含义 |
|---|---|
SampleInterval |
2 秒;允许 200 毫秒至 1 天 |
UseOtlpExporter |
true;添加一个 Metrics OTLP Exporter |
ExportIntervalMilliseconds |
null;保留 SDK 默认 60 秒及 OTEL_METRIC_EXPORT_INTERVAL 配置 |
ExportTimeoutMilliseconds |
null;保留 SDK 默认及 OTEL_METRIC_EXPORT_TIMEOUT 配置 |
configureOtlpExporter |
可配置 SDK 原生 Endpoint、Protocol、Headers、Timeout 等选项 |
未显式配置 Exporter 时,使用 SDK 的 OTEL_EXPORTER_OTLP_* 配置。
默认传输是 gRPC,端点为 http://localhost:4317。HTTP/protobuf 的显式 Endpoint
必须包含完整的指标路径,如 http://localhost:4318/v1/metrics。
代码设置的选项优先于对应的 SDK 配置;采样周期与导出周期分别控制。
已有 Metrics Exporter 的宿主,关闭本包的 Exporter,避免向相同目的地重复发送:
builder.Services.AddWatchDogOpenTelemetry(options => options.UseOtlpExporter = false);
// 继续使用宿主原有 AddOpenTelemetry().WithMetrics(...) 或 UseOtlpExporter() 配置。
本包向宿主共享的 MeterProvider 订阅 WatchDog.Resources,不替换宿主的 Resource、
service.name 或 service.instance.id。生产环境请为应用配置服务名称和实例标识。
仅引用核心包时不引入任何 OpenTelemetry NuGet 依赖。
指标契约
Meter 名称:WatchDog.Resources。指标使用 watchdog.* 命名空间,以保留现有采集器的真实口径;
“标准 OTel 支持”指标准 OTLP 编码和传输,不宣称这些自定义指标符合所有 system.* 语义约定。
所有指标带 host.name、watchdog.platform、watchdog.scope 属性。
| 指标名称 | 类型 | 单位 / 口径 |
|---|---|---|
watchdog.node.cpu.utilization |
Gauge | 1;节点 CPU 百分比 / 100,附 watchdog.estimated |
watchdog.process.cpu.logical_count |
Gauge | {cpu};进程可用逻辑处理器数,不宣称是宿主机总核数 |
watchdog.node.memory.usage / .available / .limit |
Gauge | By;已用、可用、总量或 cgroup 限额 |
watchdog.node.memory.utilization |
Gauge | 1;内存使用比例 |
watchdog.node.filesystem.usage / .available / .limit |
Gauge | By;可见文件系统容量,按 system.filesystem.mountpoint 区分 |
watchdog.node.filesystem.utilization |
Gauge | 1;文件系统容量使用比例,不是磁盘 I/O |
watchdog.node.network.io.rate |
Gauge | By/s;按 network.io.direction=receive/transmit 区分 |
watchdog.node.load_average |
Gauge | 1;按 watchdog.load.interval=1m/5m/15m 区分 |
watchdog.process.cpu.usage |
Gauge | 1;1 表示占满一个核,可超过 1 |
watchdog.process.memory.working_set / .private / .managed_heap |
Gauge | By;工作集、私有内存、托管内存 |
watchdog.process.gc.collections |
ObservableCounter | {collection};进程启动以来累计次数,按 dotnet.gc.heap.generation=0/1/2 区分 |
watchdog.process.thread.count |
Gauge | {thread} |
watchdog.process.handle.count |
Gauge | {handle};仅在平台能报告时出现 |
watchdog.process.thread_pool.thread.count |
Gauge | {thread} |
watchdog.process.thread_pool.queue.length |
Gauge | {work_item} |
watchdog.process.uptime |
Gauge | s |
范围按指标分别判断:CPU、负载为可见内核的 host 口径;内存由数据来源区分 host、
container、process_estimate,并附 watchdog.memory.source;网络与文件系统分别标为
visible_network / visible_filesystem;进程指标标为 process。不能根据 cgroup 内存限额
把整组节点指标都解释为容器资源。多进程部署也不要直接累加各应用重复采集的节点资源。
内存和容量基于现有快照的 MiB / GiB 换算为字节,保留其已有舍入精度;网络 Mbps 使用十进制 换算为字节/秒。首次 CPU / 网络差分无基线、不支持或非有限数值均不产生观测值,不用 0 代替。
采样、故障与关闭
启用扩展包后,后台服务是唯一的采样入口,看板和 OTel Observable 回调都读取同一份最新缓存, 不会各自推进差分基线。各宿主使用自己的采集状态,差分耗时使用单调时钟。
采样失败不会终止宿主。OTel 不再观测超过 max(3 × SampleInterval, 1 秒) 的旧数据;
看板继续收到原快照时间戳,可据此识别旧数据。宿主停止时取消后台定时器,SDK 负责导出器的关闭。
Gauge 导出最新采样值,不保存两次导出之间的每个样本,也不自动保留峰值。 接收端不可用时,后续周期仍会尝试发送;这不是持久化重试队列或无损交付保证。 有重试、队列、过滤需求时,可在外部部署 OTel Collector。
后续对接 GreptimeDB
不需要新增 WatchDog 存储驱动。将 HTTP/protobuf Exporter 指向 GreptimeDB 的完整 OTLP Metrics 地址, 并通过 Headers 配置数据库和认证即可:
builder.Services.AddWatchDogOpenTelemetry(
configureOtlpExporter: exporter =>
{
exporter.Protocol = OtlpExportProtocol.HttpProtobuf;
exporter.Endpoint = new Uri("http://localhost:4000/v1/otlp/v1/metrics");
exporter.Headers = "X-Greptime-DB-Name=public";
// 按部署要求追加 Authorization;凭据从宿主配置/密钥系统读取。
});
这是标准 OTLP 接入配置示例,不包含数据库部署、表管理或历史查询功能。 本仓库测试验证自定义路径、请求头及真实 OTLP protobuf 请求,未依赖在线 GreptimeDB 服务。 地址与请求头以 GreptimeDB 官方 OTLP 文档 为准。
示例与验证
仓库示例:samples/Test.WatchDog.OpenTelemetry。PowerShell 向本机 Collector 导出:
$env:OTEL_EXPORTER_OTLP_PROTOCOL = 'http/protobuf'
$env:OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = 'http://localhost:4318/v1/metrics'
dotnet run --project samples/Test.WatchDog.OpenTelemetry
测试工程:test/WatchDog.OpenTelemetry.Tests,覆盖指标契约、采样生命周期、宿主管线共存和 OTLP HTTP 协议。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Layout.WatchDog.NET (>= 1.5.0-beta.7)
- OpenTelemetry (>= 1.20.1)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.20.1)
- OpenTelemetry.Extensions.Hosting (>= 1.20.1)
-
net8.0
- Layout.WatchDog.NET (>= 1.5.0-beta.7)
- OpenTelemetry (>= 1.20.1)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.20.1)
- OpenTelemetry.Extensions.Hosting (>= 1.20.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.5.0-beta.7 | 53 | 11/7/2026 |
| 1.5.0-beta.6 | 53 | 11/3/2026 |