mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 18:19:04 +02:00
75 lines
5.0 KiB
Markdown
75 lines
5.0 KiB
Markdown
# mscluster agent notes
|
|
|
|
- All subcollectors read through ClusAPI
|
|
([`internal/headers/clusapi`](../../headers/clusapi)) instead of the
|
|
`root\MSCluster` WMI provider (ClusWMI.dll). The WMI provider is a thin layer
|
|
over ClusAPI: most WMI properties are common properties from
|
|
`CLUSCTL_<OBJECT>_GET_RO_COMMON_PROPERTIES` and
|
|
`CLUSCTL_<OBJECT>_GET_COMMON_PROPERTIES`; `Characteristics`, `Flags` and
|
|
`State` come from their own control codes and `GetCluster<Object>State`.
|
|
Some WMI values are synthesized or never filled (published as 0 from NULL);
|
|
the parity tests show which ones, and the collector reproduces them.
|
|
- Keep WMI types when publishing: `sint32` properties (for example
|
|
`FailbackWindowStart`) are converted from the raw 32-bit value with
|
|
`int32`, `uint32` properties keep the unsigned bit pattern. Unknown states
|
|
(-1) are values, as in WMI, not errors.
|
|
- Each subcollector owns its own `clusapi.Cluster`. A `Cluster` runs one call
|
|
at a time without holding its lock: ClusAPI RPCs cannot be cancelled, so a
|
|
second call fails with `clusapi.ErrBusy`, and `Close` leaves the handle to
|
|
the running call. `callSource` stops waiting at the scrape budget, so one
|
|
stuck RPC does not hold `Collect` and the other subcollectors.
|
|
- `closeSources` drops a source even when its `Close` fails, so `Build` can
|
|
recreate it. Grafana Alloy calls `Build`/`Close` repeatedly.
|
|
- Every subcollector has a fixture test that checks gathered metric families
|
|
and a parity test against its WMI class. The CI cluster (`setup-mscluster`
|
|
in `.github/workflows/ci.yml`) is a single node without storage or
|
|
administrative access point. It has online, offline and failed resources in
|
|
two groups (`CIResources`, `CIFailedResources`) on a private network of an
|
|
internal Hyper-V switch; the parity tests require them. It has no clustered
|
|
disks, so shared volume parity still compares empty sets.
|
|
The "Cluster Group" also holds an offline "Health Service" resource
|
|
without Storage Spaces Direct. It answers `CLUSCTL_RESOURCE_GET_CLASS_INFO`
|
|
with only 4 bytes, like the Health resource of S2D clusters (#2669). S2D
|
|
itself cannot be enabled on the runner: it claims every VHDX disk of the
|
|
other steps, and `Set-ClusterStorageSpacesDirectDisk -CanBeClaimed $false`
|
|
removes those disks from the host instead of leaving them alone. Disks from
|
|
a loopback iSCSI target (with `S2DBusTypes` limited to iSCSI) appear before
|
|
`New-Cluster`, but the session and the target are gone after it: once the
|
|
node is clustered, the iSCSI Target Server only serves clustered targets.
|
|
A clustered target needs a cluster disk for its files, and
|
|
`Get-ClusterAvailableDisk` does not list a host-mounted VHDX.
|
|
- Property lists returned by the cluster service end with an extra
|
|
`CLUSPROP_SYNTAX_ENDMARK` after the last value list; fixtures built only from
|
|
the documentation miss this. The parser validates only the structure and
|
|
accepts zero padding. `TestDumpPropertyLists` logs real lists as hex when
|
|
`WINDOWS_EXPORTER_TEST_CLUSAPI_DUMP` is set on a cluster node.
|
|
- Each `Cluster` owns one control buffer (`controlScratch`). Like the handle,
|
|
it belongs to the running call, so calls never share it and no `sync.Pool`
|
|
is needed. `ParseProperties` returns `Property.Data` slices into it: copy
|
|
values out (`copyResourceProperties`, `readCommonProperties`) before the
|
|
next control, and never keep a parsed list past that point. `get` zeroes
|
|
the bytes, so a reused buffer reads like a new one.
|
|
- `clusapi.Open` reports an unconfigured cluster or a missing ClusAPI with
|
|
`errors.ErrUnsupported`; the shared collector test treats that as an
|
|
unsupported role on hosts where `mscluster` is not a required fixture.
|
|
- Use `ClusterOpenEnum` and the `Open*Ex` functions (Windows Server 2008 R2+),
|
|
not `ClusterOpenEnumEx` (Windows Server 2016+), to keep Windows Server
|
|
2012 R2 support.
|
|
- Cluster, network, node, group and resource metrics are reused between
|
|
scrapes through `internal/metriccache` when every input is unchanged. A
|
|
cache value must hold every input of the cached series: field values and
|
|
whether each field is published (`appendObjectFieldsKey`, which resolves the
|
|
build-dependent rules of `objectField`), owner node and node names. Objects
|
|
with missing fields are not cached, so they report the same errors on every
|
|
scrape. Shared volume sizes change constantly and are not cached.
|
|
- Many cluster, group and resource properties are durations or sizes in
|
|
milliseconds, minutes, hours, KiB or MiB (for example
|
|
`ClusSvcRegroupTickInMilliseconds`, `ShutdownTimeoutInMinutes`,
|
|
`FailoverPeriod` in hours, `S2DCachePageSizeKBytes`, `ClusterLogSize` in
|
|
MiB). Publish them in base units with a unit suffix: set `objectField.scale`
|
|
for cluster and group fields and `fieldScales` for resources. The parity
|
|
tests feed WMI values through the same scale, so they cannot catch a wrong
|
|
factor; check units against a live cluster (`Get-Cluster | Format-List *`).
|
|
The WMI help texts are not reliable: `QuarantineDuration` is seconds
|
|
(default 7200), not milliseconds.
|