mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 18:19:04 +02:00
storage_spaces: add primordial label to pool info (#2650)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3e013fe22b
commit
ec82f90a79
@@ -20,14 +20,19 @@ Matching is case-sensitive.
|
||||
|
||||
### Pool
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|-------|----------------------------------|
|
||||
| `windows_storage_spaces_pool_info` | Storage pool information (value is always 1) | gauge | `name`, `unique_id` |
|
||||
| `windows_storage_spaces_pool_health_status` | Health status of the storage pool. 0: Healthy, 1: Warning, 2: Unhealthy, 5: Unknown | gauge | `name`, `unique_id` |
|
||||
| `windows_storage_spaces_pool_size_bytes` | Total size of the storage pool in bytes | gauge | `name`, `unique_id` |
|
||||
| `windows_storage_spaces_pool_allocated_size_bytes` | Allocated size of the storage pool in bytes | gauge | `name`, `unique_id` |
|
||||
| `windows_storage_spaces_pool_operational_status` | Operational status codes reported for the storage pool (one series per status value) | gauge | `name`, `unique_id`, `status` |
|
||||
| `windows_storage_spaces_pool_thin_provisioning_alert_thresholds` | Thin provisioning alert thresholds configured for the storage pool, in percent (one series per configured threshold) | gauge | `name`, `unique_id`, `threshold` |
|
||||
| Name | Description | Type | Labels |
|
||||
|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|-------|-----------------------------------|
|
||||
| `windows_storage_spaces_pool_info` | Storage pool information (value is always 1). `primordial` is `true` for the built-in primordial pool | gauge | `name`, `unique_id`, `primordial` |
|
||||
| `windows_storage_spaces_pool_health_status` | Health status of the storage pool. 0: Healthy, 1: Warning, 2: Unhealthy, 5: Unknown | gauge | `name`, `unique_id` |
|
||||
| `windows_storage_spaces_pool_size_bytes` | Total size of the storage pool in bytes | gauge | `name`, `unique_id` |
|
||||
| `windows_storage_spaces_pool_allocated_size_bytes` | Allocated size of the storage pool in bytes | gauge | `name`, `unique_id` |
|
||||
| `windows_storage_spaces_pool_operational_status` | Operational status codes reported for the storage pool (one series per status value) | gauge | `name`, `unique_id`, `status` |
|
||||
| `windows_storage_spaces_pool_thin_provisioning_alert_thresholds` | Thin provisioning alert thresholds configured for the storage pool, in percent (one series per configured threshold) | gauge | `name`, `unique_id`, `threshold` |
|
||||
|
||||
Windows always reports a built-in pool named `Primordial` next to the concrete pools.
|
||||
It groups every local physical disk that can be pooled but is not yet part of a concrete pool, so its size is the sum of those disks and not usable pool capacity.
|
||||
Only `windows_storage_spaces_pool_info` carries the `primordial` label.
|
||||
Join on `unique_id` to restrict other pool metrics to concrete pools, as shown in the queries below.
|
||||
|
||||
### Virtual Disk
|
||||
|
||||
@@ -42,13 +47,20 @@ Matching is case-sensitive.
|
||||
|
||||
### Example metric
|
||||
|
||||
`windows_storage_spaces_pool_size_bytes{name="Pool01",unique_id="{8f2c...}"} 1.0995116277760e+12`
|
||||
```
|
||||
windows_storage_spaces_pool_info{name="Pool01",primordial="false",unique_id="{8f2c...}"} 1
|
||||
windows_storage_spaces_pool_size_bytes{name="Pool01",unique_id="{8f2c...}"} 1.0995116277760e+12
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
|
||||
Storage pool usage in percent
|
||||
Storage pool usage in percent, excluding the primordial pool
|
||||
```
|
||||
windows_storage_spaces_pool_allocated_size_bytes / windows_storage_spaces_pool_size_bytes * 100
|
||||
(
|
||||
windows_storage_spaces_pool_allocated_size_bytes / windows_storage_spaces_pool_size_bytes * 100
|
||||
)
|
||||
* on (instance, unique_id) group_left ()
|
||||
windows_storage_spaces_pool_info{primordial="false"}
|
||||
```
|
||||
|
||||
Find virtual disks with low storage efficiency (over-provisioned)
|
||||
@@ -66,7 +78,12 @@ sum(windows_storage_spaces_virtual_disk_size_bytes) / sum(windows_storage_spaces
|
||||
#### Unhealthy storage pool
|
||||
```yaml
|
||||
- alert: StoragePoolUnhealthy
|
||||
expr: windows_storage_spaces_pool_health_status != 0
|
||||
expr: |
|
||||
(
|
||||
windows_storage_spaces_pool_health_status != 0
|
||||
)
|
||||
* on (instance, unique_id) group_left ()
|
||||
windows_storage_spaces_pool_info{primordial="false"}
|
||||
for: 10m
|
||||
labels:
|
||||
severity: warning
|
||||
|
||||
@@ -44,6 +44,7 @@ type collectorStoragePool struct {
|
||||
type msftStoragePool struct {
|
||||
FriendlyName string `mi:"FriendlyName"`
|
||||
UniqueId string `mi:"UniqueId"`
|
||||
IsPrimordial bool `mi:"IsPrimordial"`
|
||||
HealthStatus uint16 `mi:"HealthStatus"`
|
||||
Size uint64 `mi:"Size"`
|
||||
AllocatedSize uint64 `mi:"AllocatedSize"`
|
||||
@@ -53,7 +54,7 @@ type msftStoragePool struct {
|
||||
}
|
||||
|
||||
func (c *Collector) buildStoragePool() error {
|
||||
wmiSelect := "FriendlyName,UniqueId,HealthStatus,Size,AllocatedSize,OperationalStatus,ThinProvisioningAlertThresholds"
|
||||
wmiSelect := "FriendlyName,UniqueId,IsPrimordial,HealthStatus,Size,AllocatedSize,OperationalStatus,ThinProvisioningAlertThresholds"
|
||||
|
||||
storagePoolMIQuery, err := mi.NewQuery(fmt.Sprintf("SELECT %s FROM MSFT_StoragePool", wmiSelect))
|
||||
if err != nil {
|
||||
@@ -64,8 +65,8 @@ func (c *Collector) buildStoragePool() error {
|
||||
|
||||
c.storagePoolInfo = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, nameStoragePool, "info"),
|
||||
"Storage pool information (value is always 1)",
|
||||
[]string{"name", "unique_id"},
|
||||
"Storage pool information (value is always 1). primordial is true for the built-in primordial pool",
|
||||
[]string{"name", "unique_id", "primordial"},
|
||||
nil,
|
||||
)
|
||||
|
||||
@@ -127,6 +128,7 @@ func (c *Collector) collectStoragePool(ch chan<- prometheus.Metric, maxScrapeDur
|
||||
1.0,
|
||||
pool.FriendlyName,
|
||||
pool.UniqueId,
|
||||
strconv.FormatBool(pool.IsPrimordial),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
|
||||
@@ -36,7 +36,7 @@ func TestCollector(t *testing.T) {
|
||||
pool := prometheus.Labels{"name": "GitHubActions"}
|
||||
virtualDisk := prometheus.Labels{"name": "CIVirtualDisk"}
|
||||
|
||||
testutils.RequireFixtureMetric(t, metrics, storage_spaces.Name, "windows_storage_spaces_pool_info", pool)
|
||||
testutils.RequireFixtureMetric(t, metrics, storage_spaces.Name, "windows_storage_spaces_pool_info", prometheus.Labels{"name": "GitHubActions", "primordial": "false"})
|
||||
testutils.RequireFixtureMetric(t, metrics, storage_spaces.Name, "windows_storage_spaces_virtual_disk_info", virtualDisk)
|
||||
|
||||
for _, tc := range []struct {
|
||||
@@ -66,4 +66,18 @@ func TestCollector(t *testing.T) {
|
||||
require.Greater(t, value, 0.0)
|
||||
require.LessOrEqual(t, value, 100.0)
|
||||
}
|
||||
|
||||
// Every pool, including the built-in primordial pool, must carry a boolean primordial label.
|
||||
for _, metric := range metrics["windows_storage_spaces_pool_info"].GetMetric() {
|
||||
var primordial []string
|
||||
|
||||
for _, label := range metric.GetLabel() {
|
||||
if label.GetName() == "primordial" {
|
||||
primordial = append(primordial, label.GetValue())
|
||||
}
|
||||
}
|
||||
|
||||
require.Len(t, primordial, 1, "pool info metric %s", metric)
|
||||
require.Contains(t, []string{"true", "false"}, primordial[0], "pool info metric %s", metric)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user