- 可观测性
- 指标监控
【免费下载链接】windows_exporter
Prometheus exporter for Windows machines
本篇以 windows_exporter 的 memory collector 文档为核心,系统讲解该采集器的数据来源(Windows Performance Counters 与GlobalMemoryStatusExAPI)、全部 35 项windows_memory_*指标的含义与类型,并结合仓库源码说明其采集调用链、PromQL 查询示例与告警规则写法。读完后你可以独立完成 Windows 主机的内存用量监控、Commit 告警配置,并能看懂指标背后的 Windows 分页机制语义。
一、memory collector 概览
memory collector 是 windows_exporter 用于暴露系统内存使用情况的采集器,其基本属性如下(与 collector 文档 一致):
| 属性 | 说明 |
|---|---|
| Metric name prefix | memory(完整指标名带windows_前缀,如windows_memory_available_bytes) |
| Data source | Performance Counters(性能计数器) |
| Classes | 无 WMI Class,直接读取Memory性能对象 |
| Enabled by default? | 是(默认启用) |
memory 属于默认启用的采集器之一。从源码 DefaultCollectors 定义 可以确认:
const DefaultCollectors = "cpu,memory,logical_disk,physical_disk,net,os,service,system"因此只要以默认参数启动 windows_exporter,无需任何额外配置即可采集全部内存指标;如需手动指定采集器列表,也无需为 memory 传任何 Flag(该 collector 无命令行参数,源码 NewWithFlags 直接返回空Collector{},其 Config 为空结构体)。
二、数据来源:两条并行的采集路径
从 memory collector 实现 的Collect方法可以看到,一次采集由两个子过程组成,错误会分别包装后合并返回:
func (c *Collector) Collect(ch chan<- prometheus.Metric, _ time.Duration) error { errs := make([]error, 0) if err := c.collectPDH(ch); err != nil { errs = append(errs, fmt.Errorf("failed collecting memory metrics: %w", err)) } if err := c.collectGlobalMemoryStatus(ch); err != nil { errs = append(errs, fmt.Errorf("failed collecting global memory metrics: %w", err)) } return errors.Join(errs...) }2.1 路径一:PDH 性能计数器(绝大多数指标)
在Build阶段,采集器通过通用 PDH 框架订阅Memory性能对象的全部实例(_Total):
c.perfDataCollector, err = pdh.NewCollectorperfDataCounterValues), pdh.CounterTypeRaw, "Memory", pdh.InstancesAll)- 第 3 个参数
"Memory"即 Windows 性能对象Memory(对应 Win32 计数器库中的 PerfOS/Memory); pdh.CounterTypeRaw表示读取 Raw 计数器类型,保证跨采样周期数值可直接累积为 counter 语义;- 泛型参数
perfDataCounterValues是 types.go 中定义的映射结构体,用perfdatatag 把每个字段与 Windows 计数器名一一绑定,例如:
type perfDataCounterValues struct { AvailableBytes float64 `perfdata:"Available Bytes"` CommitLimit float64 `perfdata:"Commit Limit"` PageFaultsPerSec float64 `perfdata:"Page Faults/sec"` StandbyCacheCoreBytes float64 `perfdata:"Standby Cache Core Bytes"` // ... 共 35 个计数器 }PDH 框架(见 internal/pdh/collector.go)基于反射解析这些 tag,自动完成计数器句柄的创建、采样与按字段回填,memory collector 本身无需手写任何 Win32 调用。
2.2 路径二:GlobalMemoryStatusEx(3 项全局状态指标)
另外 3 项指标来自 Win32 API,由 collectGlobalMemoryStatus 完成:
memoryStatusEx, err := sysinfoapi.GlobalMemoryStatusEx()sysinfoapi 通过kernel32.dll的GlobalMemoryStatusEx进程序调用读取MEMORYSTATUSEX结构体,并将 3 个字段映射为 Prometheus 指标:
| 指标 | MEMORYSTATUSEX 字段 | 含义 |
|---|---|---|
windows_memory_process_memory_limit_bytes | UllTotalVirtual | 调用进程用户态虚拟地址空间大小,取决于进程类型、处理器与系统配置 |
windows_memory_physical_total_bytes | UllTotalPhys | 操作系统可见的物理内存总量 |
windows_memory_physical_free_bytes | UllAvailPhys | 立即可重用的物理内存(standby、free、zero 三个页表之和) |
注意源码中的指标命名差异:PDH 路径的“可用内存”对应windows_memory_available_bytes(来自Available Bytes计数器),而 API 路径的physical_free_bytes对应AvailPhys。两者语义相近(都包含可回收页),日常使用任一方均可计算内存使用率,官方示例查询采用的是physical_free_bytes。
三、完整指标清单(35 项)
以下为 memory collector 暴露的全部指标,与 collector 文档 保持一致,按功能域分组说明。所有指标均无标签(Labels 为 None)。
3.1 物理内存与可用内存
| 指标名 | 类型 | 说明 |
|---|---|---|
windows_memory_available_bytes | gauge | 可立即分配给进程或系统使用的物理内存,等于 standby(缓存)、free 与 zero 页表之和 |
windows_memory_physical_free_bytes | gauge | 当前未使用且可立即可用的物理内存字节数(来自GlobalMemoryStatusEx) |
windows_memory_physical_total_bytes | gauge | 操作系统可用的物理内存总量。该值不一定等于真实物理内存,而是报告给操作系统的可用量 |
windows_memory_process_memory_limit_bytes | gauge | 单个进程可分配的最大内存字节数(用户态虚拟地址空间大小) |
3.2 文件系统缓存与页表
| 指标名 | 类型 | 说明 |
|---|---|---|
windows_memory_cache_bytes | gauge | 当前文件系统缓存占用的字节数 |
windows_memory_cache_bytes_peak | gauge | 自系统上次重启以来 CacheBytes 的峰值 |
windows_memory_cache_faults_total | counter | 在文件系统缓存中找不到目标页、需从内存其他位置(软故障)或磁盘(硬故障)取回的故障次数 |
windows_memory_free_and_zero_page_list_bytes | gauge | 分配给 free/zero 页表的物理内存,不含缓存数据,可立即分配 |
windows_memory_modified_page_list_bytes | gauge | 分配给 modified 页表的物理内存,含已被修改、需先写回磁盘才能释放的缓存数据 |
windows_memory_standby_cache_core_bytes | gauge | core 优先级 standby 缓存页表占用的物理内存。系统缺少 free/zero 内存时,低优先级 standby 页先被征用 |
windows_memory_standby_cache_normal_priority_bytes | gauge | 普通优先级 standby 缓存页表占用的物理内存 |
windows_memory_standby_cache_reserve_bytes | gauge | reserve 优先级 standby 缓存页表占用的物理内存 |
windows_memory_standby_cache_lifetime_seconds | gauge | 页驻留于 standby 缓存页表的长期平均时长(秒),数值偏低通常意味着内存压力 |
windows_memory_system_cache_resident_bytes | gauge | 系统文件缓存中当前驻留并活跃于物理内存的部分 |
3.3 Commit(提交内存)
| 指标名 | 类型 | 说明 |
|---|---|---|
windows_memory_commit_limit_bytes | gauge | 无需扩展分页文件即可提交的虚拟内存上限(物理内存 + 分页文件容量) |
windows_memory_committed_bytes | gauge | 当前已提交的虚拟内存字节数 |
Commit 接近 limit 时,即使物理内存尚有剩余,新的内存分配也会失败——这是与“物理内存使用率”不同维度的故障模式,mixin 中为此单独立了WindowsMemoryCommitHighUsage告警。
3.4 页故障与分页(Paging)
| 指标名 | 类型 | 说明 |
|---|---|---|
windows_memory_page_faults_total | counter | CPU 处理故障页的总速率(所有页故障之和) |
windows_memory_demand_zero_faults_total | counter | 用清零页满足的故障次数。清零页是 Windows 的安全特性,防止进程读到此前使用者留下的数据 |
windows_memory_transition_faults_total | counter | 通过回收“正被其他共享进程使用、位于 modified/standby 页表、或正在写回磁盘”的页而无需额外磁盘活动解决的故障数 |
windows_memory_transition_pages_repurposed_total | counter | 过渡缓存页被改作他用的速率(这些页本可留在页缓存中提供软故障加速) |
windows_memory_write_copies_total | counter | 因写操作触发、通过从物理内存其他位置拷贝页而满足的页故障数(Copy-on-Write) |
windows_memory_swap_page_reads_total | counter | 磁盘页读取操作次数(一次读多页只计一次) |
windows_memory_swap_pages_read_total | counter | 所有页读操作中读回的页总数(即使同批读取也逐页计数) |
windows_memory_swap_pages_written_total | counter | 所有页写操作中写出的页总数 |
windows_memory_swap_page_operations_total | counter | 换页读 + 写的总次数(PagesPerSec 计数器) |
windows_memory_swap_page_writes_total | counter | 磁盘页写操作次数(一次写多页只计一次) |
其中swap_page_reads_total(硬故障读盘)是最能反映“内存压力是否真实导致换页”的指标:物理内存使用率高但页读为 0,说明被占用的主要是可回收的缓存。
3.5 内核内存池(Pool)
| 指标名 | 类型 | 说明 |
|---|---|---|
windows_memory_pool_nonpaged_bytes | gauge | non-paged pool 占用字节数。该区域存放不能写盘、只要被分配就必须常驻物理内存的对象 |
windows_memory_pool_nonpaged_allocs_total | gauge* | non-paged pool 的分配调用次数(文档标注为 gauge,对应计数器PoolNonpagedAllocs) |
windows_memory_pool_paged_bytes | gauge | paged pool 占用字节数 |
windows_memory_pool_paged_resident_bytes | gauge | paged pool 中当前驻留于物理内存且活跃的部分 |
windows_memory_pool_paged_allocs_total | counter | paged pool 的分配调用次数(不论每次分配多少空间) |
non-paged pool 持续增长而应用工作集没有变化时,通常指向内核驱动内存泄漏——官方 Memory 仪表盘面板的描述即如此提示(见 memory 仪表盘定义:“A steadily growing nonpaged pool usually means a driver leaks memory.”)。
3.6 系统代码与驱动
| 指标名 | 类型 | 说明 |
|---|---|---|
windows_memory_system_code_resident_bytes | gauge | 当前驻留并活跃于物理内存的可分页操作系统代码 |
windows_memory_system_code_total_bytes | gauge | 已映射进系统虚拟地址空间的可分页 OS 代码总量(Ntoskrnl.exe、Hal.dll、启动驱动与文件系统驱动之和);不含必须常驻物理内存的代码 |
windows_memory_system_driver_resident_bytes | gauge | 设备驱动占用的可分页物理内存(驱动工作集),是System Driver Total Bytes的组成部分 |
windows_memory_system_driver_total_bytes | gauge | 设备驱动占用的可分页虚拟内存总量,含物理部分与已换出到磁盘的代码/数据 |
四、常用 PromQL 查询
文档给出的“查看某实例内存使用率(%)”的示例查询:
100 - 100 * windows_memory_physical_free_bytes{instance="localhost"} / windows_memory_physical_total_bytesmixin 中基于同一指标组的派生查询(见 lib/queries.libsonnet 与 rules.libsonnet)值得在实际环境直接复用:
# 内存使用率比例(0~1) 1 - windows_memory_available_bytes / windows_memory_physical_total_bytes # 已用物理内存(total - available) windows_memory_physical_total_bytes - windows_memory_available_bytes # Commit 使用比例(0~1) windows_memory_committed_bytes / windows_memory_commit_limit_bytes # 换页操作速率(硬故障信号) rate(windows_memory_swap_page_operations_total[5m]) # 缓存合计(mixin 的 windows:memory_cached:bytes 记录规则) windows_memory_cache_bytes + windows_memory_modified_page_list_bytes + windows_memory_standby_cache_core_bytes + windows_memory_standby_cache_normal_priority_bytes + windows_memory_standby_cache_reserve_bytesmixin 将上述表达式固化为记录规则(windows:memory_usage:ratio、windows:memory_used:bytes、windows:memory_committed:ratio等),仪表盘与告警统一引用记录规则而不是重复计算,告警规则见 alerts.libsonnet。配套的可视化定义在 memory 仪表盘 中,包含 Physical memory、Commit charge、Paging、Kernel pools and cache 四组面板。
五、告警示例
文档提供了两条可直接使用的告警规则示例:
prometheus.rules
# Alert on hosts that have exhausted all available physical memory - alert: MemoryExhausted expr: windows_memory_physical_free_bytes == 0 for: 10m labels: severity: high annotations: summary: "Host {{ $labels.instance }} is out of memory" description: "{{ $labels.instance }} has exhausted all available physical memory" # Alert on hosts with greater than 90% memory usage - alert: MemoryLow expr: 100 - 100 * windows_memory_physical_free_bytes{instance="localhost"} / windows_memory_physical_total_bytes > 90 for: 10m labels: severity: warning annotations: summary: "Memory usage for host {{ $labels.instance }} is greater than 90%"两点使用说明:
- 示例中
{instance="localhost"}需要替换为你实际的实例标签,或使用instance=~"..."形式匹配多台主机; MemoryExhausted用“free 恒等于 0”判定内存耗尽,语义严格但可能滞后;生产实践中更常见的是按阈值比例告警。
仓库 mixin 提供的等价生产级告警(阈值可通过配置调整,默认 90%,持续 15 分钟):
alert( 'WindowsMemoryHighUsage', q.metric('windows:memory_usage:ratio') + ' * 100 > %s' % c.memoryHighUsageThreshold, '15m', 'warning', 'Windows memory usage is high', ... ), alert( 'WindowsMemoryCommitHighUsage', q.metric('windows:memory_committed:ratio') + ' * 100 > %s' % c.memoryCommitHighUsageThreshold, '15m', 'warning', 'Windows memory commit usage is high', ... ),两条告警分别对应两份 Runbook,可直接作为处置参考:
- WindowsMemoryHighUsage 处置手册:按“确认使用率比例 → 检查换页速率与 Commit 比例 → 资源监视器查工作集/硬故障 → 检查内核 pool 是否增长”的顺序排查,强调“高使用率比例本身不等于系统正在大量换页”;
- WindowsMemoryCommitHighUsage 处置手册:Commit 告警时即使物理内存仍有剩余,系统也可能拒绝新的内存提交导致应用失败,手册给出了检查分页文件的 PowerShell 命令(
Get-CimInstance Win32_PageFileUsage等),并说明调整分页文件会影响 Commit 上限但不增加物理内存。
六、验证与测试
memory collector 的行为由 memory_test.go 覆盖:TestCollector通过testutils.TestCollector在 Windows 环境完成一次真实采集,断言指标命名、类型与一致性;BenchmarkCollector提供采集耗时的基准测试。该测试文件带//go:build windows约束,只能在 Windows 上运行,与整个 exporter 的构建目标一致。
七、小结
- memory collector 默认启用、无配置项,数据来源为 PDH
Memory性能对象(CounterTypeRaw、全实例订阅)+GlobalMemoryStatusExAPI,两条路径分别产出 32 项与 3 项指标; - 指标分五类语义域:物理内存/可用内存、缓存与页表、Commit、页故障与分页、内核池与系统代码,排查“内存压力”时应组合使用(如高使用率 +
rate(windows_memory_swap_page_reads_total)判断真实换页); - 告警建议同时覆盖“物理内存使用率”与“Commit 比例”两个维度,并参考仓库 mixin 的记录规则与 Runbook 落地为完整监控方案。
- 可观测性
- 指标监控
【免费下载链接】windows_exporter
Prometheus exporter for Windows machines
相关推荐
windows_exporter license collector 详解:监控 Windows 授权状态的指标、告警与 slc.dll 实现原理
windows_exporter license collector 详解:监控 Windows 授权状态的指标、告警与 slc.dll 实现原理 本文围绕 w
可观测性指标监控windows_exporter DNS 采集器深度解析:指标清单、子采集器配置与源码实现
windows_exporter DNS 采集器深度解析:指标清单、子采集器配置与源码实现 本文围绕 windows_exporter 的 DNS 采集器展开:
可观测性指标监控windows_exporter container 采集器:Hyper-V 容器与 Windows Pod 指标监控完整指南
windows_exporter container 采集器:Hyper V 容器与 Windows Pod 指标监控完整指南 导读 container 采集器
可观测性指标监控
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考