logical_disk: remove the avg_*_requests_queued gauges (#2724)

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-15 19:46:00 +02:00
committed by GitHub
parent d10875c43d
commit b90371616b
7 changed files with 32 additions and 83 deletions
+4 -4
View File
@@ -21,7 +21,9 @@ multi-instance. These notes were recorded on a Windows Server 2025
cumulative busy time in 100 ns ticks. `internal/pdh` converts the
`PERF_PRECISION_100NS_TIMER` counters to seconds. The queue length and
`PERF_AVERAGE_TIMER` values arrive in ticks and need the 1e-7 factor; the
counter time base is 10 MHz here.
counter time base is 10 MHz here. The queue length counters duplicate the
busy time, so the collector no longer reads them; the average queue length is
`rate(windows_logical_disk_{read,write}_seconds_total[5m])`.
- `Avg. Disk sec/Read`, `/Write` and `/Transfer` are `PERF_AVERAGE_TIMER`.
Their base is the operation count and equals `Disk Reads/sec` (3073),
`Disk Writes/sec` (1698) and their sum (4771).
@@ -50,11 +52,9 @@ Counters the collector reads:
| `% Disk Write Time` | `PERF_PRECISION_100NS_TIMER` | 11319205 | |
| `% Free Space` | `PERF_RAW_FRACTION` | 49907 | 129254 |
| `% Idle Time` | `PERF_PRECISION_100NS_TIMER` | 115960642 | |
| `Avg. Disk Read Queue Length` | `PERF_COUNTER_100NS_QUEUELEN_TYPE` | 9858832 | |
| `Avg. Disk sec/Read` | `PERF_AVERAGE_TIMER` | 9858832 | 3073 |
| `Avg. Disk sec/Transfer` | `PERF_AVERAGE_TIMER` | 21178037 | 4771 |
| `Avg. Disk sec/Write` | `PERF_AVERAGE_TIMER` | 11319205 | 1698 |
| `Avg. Disk Write Queue Length` | `PERF_COUNTER_100NS_QUEUELEN_TYPE` | 11319205 | |
| `Current Disk Queue Length` | `PERF_COUNTER_RAWCOUNT` | 0 | |
| `Disk Read Bytes/sec` | `PERF_COUNTER_BULK_COUNT` | 131518976 | |
| `Disk Reads/sec` | `PERF_COUNTER_COUNTER` | 3073 | |
@@ -66,7 +66,7 @@ Counters the collector reads:
Not read by the collector:
- `PERF_AVERAGE_BULK`: `Avg. Disk Bytes/Read`, `Avg. Disk Bytes/Transfer`, `Avg. Disk Bytes/Write`
- `PERF_COUNTER_100NS_QUEUELEN_TYPE`: `Avg. Disk Queue Length`
- `PERF_COUNTER_100NS_QUEUELEN_TYPE`: `Avg. Disk Queue Length`, `Avg. Disk Read Queue Length` (raw 9858832), `Avg. Disk Write Queue Length` (raw 11319205)
- `PERF_COUNTER_BULK_COUNT`: `Disk Bytes/sec`
- `PERF_COUNTER_COUNTER`: `Disk Transfers/sec`
- `PERF_PRECISION_100NS_TIMER`: `% Disk Time`
@@ -93,8 +93,6 @@ type Collector struct {
// lastMountErr is the last logged error of getAllMountedVolumes.
lastMountErr string
avgReadQueue *prometheus.Desc
avgWriteQueue *prometheus.Desc
freeSpace *prometheus.Desc
idleTime *prometheus.Desc
information *prometheus.Desc
@@ -230,22 +228,6 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
nil,
)
c.avgReadQueue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "avg_read_requests_queued"),
"DEPRECATED: use rate(windows_logical_disk_read_seconds_total). "+
"Cumulative read queue length in seconds, identical to windows_logical_disk_read_seconds_total (LogicalDisk.AvgDiskReadQueueLength)",
[]string{"volume"},
nil,
)
c.avgWriteQueue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "avg_write_requests_queued"),
"DEPRECATED: use rate(windows_logical_disk_write_seconds_total). "+
"Cumulative write queue length in seconds, identical to windows_logical_disk_write_seconds_total (LogicalDisk.AvgDiskWriteQueueLength)",
[]string{"volume"},
nil,
)
c.readBytesTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "read_bytes_total"),
"The number of bytes transferred from the disk during read operations (LogicalDisk.DiskReadBytesPerSec)",
@@ -421,24 +403,6 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric, _ time.Duration) error
data.Name,
)
// The raw value of a PERF_COUNTER_100NS_QUEUELEN_TYPE counter is the queue length
// integrated over time in 100ns ticks, not an average. It shares its source with
// "% Disk Read/Write Time". Kept as gauge for compatibility: as a counter,
// OpenMetrics exposition would rename the series to *_total.
ch <- prometheus.MustNewConstMetric(
c.avgReadQueue,
prometheus.GaugeValue,
data.AvgDiskReadQueueLength*pdh.TicksToSecondScaleFactor,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.avgWriteQueue,
prometheus.GaugeValue,
data.AvgDiskWriteQueueLength*pdh.TicksToSecondScaleFactor,
data.Name,
)
ch <- prometheus.MustNewConstMetric(
c.readBytesTotal,
prometheus.CounterValue,
@@ -46,28 +46,21 @@ func TestCollector(t *testing.T) {
})
}
// TestCollectorAvgQueueIsCumulative checks that the raw "Avg. Disk Read/Write Queue Length"
// values are not averages, but the same cumulative values as "% Disk Read/Write Time".
// This is why the avg_*_requests_queued metrics are kept only for compatibility.
func TestCollectorAvgQueueIsCumulative(t *testing.T) {
// TestCollectorAvgQueueRemoved checks that the removed avg_*_requests_queued gauges are
// gone while their replacements are still emitted. The raw "Avg. Disk Read/Write Queue
// Length" values were the same cumulative values as "% Disk Read/Write Time".
func TestCollectorAvgQueueRemoved(t *testing.T) {
metrics := testutils.TestCollector(t, logical_disk.New, &logical_disk.Config{
CollectorsEnabled: logical_disk.ConfigDefaults.CollectorsEnabled,
VolumeInclude: types.RegExpAny,
})
for deprecated, replacement := range map[string]string{
for removed, replacement := range map[string]string{
"windows_logical_disk_avg_read_requests_queued": "windows_logical_disk_read_seconds_total",
"windows_logical_disk_avg_write_requests_queued": "windows_logical_disk_write_seconds_total",
} {
want := testutils.MetricValuesByLabel(metrics, replacement, "volume")
values := testutils.MetricValuesByLabel(metrics, deprecated, "volume")
require.NotEmpty(t, values, "%s was not emitted", deprecated)
for volume, got := range values {
require.Contains(t, want, volume)
require.InDelta(t, want[volume], got, 1e-6, "%s{volume=%q}", deprecated, volume)
}
require.Empty(t, testutils.MetricValuesByLabel(metrics, removed, "volume"), "%s is still emitted", removed)
require.NotEmpty(t, testutils.MetricValuesByLabel(metrics, replacement, "volume"), "%s was not emitted", replacement)
}
}
+14 -16
View File
@@ -20,20 +20,18 @@ package logical_disk
type perfDataCounterValues struct {
Name string
AvgDiskReadQueueLength float64 `perfdata:"Avg. Disk Read Queue Length"`
AvgDiskSecPerRead float64 `perfdata:"Avg. Disk sec/Read"`
AvgDiskSecPerTransfer float64 `perfdata:"Avg. Disk sec/Transfer"`
AvgDiskSecPerWrite float64 `perfdata:"Avg. Disk sec/Write"`
AvgDiskWriteQueueLength float64 `perfdata:"Avg. Disk Write Queue Length"`
CurrentDiskQueueLength float64 `perfdata:"Current Disk Queue Length"`
FreeSpace float64 `perfdata:"Free Megabytes"`
DiskReadBytesPerSec float64 `perfdata:"Disk Read Bytes/sec"`
DiskReadsPerSec float64 `perfdata:"Disk Reads/sec"`
DiskWriteBytesPerSec float64 `perfdata:"Disk Write Bytes/sec"`
DiskWritesPerSec float64 `perfdata:"Disk Writes/sec"`
PercentDiskReadTime float64 `perfdata:"% Disk Read Time"`
PercentDiskWriteTime float64 `perfdata:"% Disk Write Time"`
PercentFreeSpace float64 `perfdata:"% Free Space,secondvalue"`
PercentIdleTime float64 `perfdata:"% Idle Time"`
SplitIOPerSec float64 `perfdata:"Split IO/Sec"`
AvgDiskSecPerRead float64 `perfdata:"Avg. Disk sec/Read"`
AvgDiskSecPerTransfer float64 `perfdata:"Avg. Disk sec/Transfer"`
AvgDiskSecPerWrite float64 `perfdata:"Avg. Disk sec/Write"`
CurrentDiskQueueLength float64 `perfdata:"Current Disk Queue Length"`
FreeSpace float64 `perfdata:"Free Megabytes"`
DiskReadBytesPerSec float64 `perfdata:"Disk Read Bytes/sec"`
DiskReadsPerSec float64 `perfdata:"Disk Reads/sec"`
DiskWriteBytesPerSec float64 `perfdata:"Disk Write Bytes/sec"`
DiskWritesPerSec float64 `perfdata:"Disk Writes/sec"`
PercentDiskReadTime float64 `perfdata:"% Disk Read Time"`
PercentDiskWriteTime float64 `perfdata:"% Disk Write Time"`
PercentFreeSpace float64 `perfdata:"% Free Space,secondvalue"`
PercentIdleTime float64 `perfdata:"% Idle Time"`
SplitIOPerSec float64 `perfdata:"Split IO/Sec"`
}