2021-12-18 18:01:29 +00:00
//go:build windows
2018-11-30 00:51:12 +00:00
// +build windows
2016-09-01 12:55:35 +00:00
package collector
2016-08-27 09:34:27 +00:00
import (
2023-04-01 07:48:23 +00:00
"errors"
2016-08-27 09:34:27 +00:00
"fmt"
"regexp"
2023-03-12 23:32:17 +00:00
"github.com/alecthomas/kingpin/v2"
2021-01-30 10:16:53 +00:00
"github.com/prometheus-community/windows_exporter/log"
2016-08-27 09:34:27 +00:00
"github.com/prometheus/client_golang/prometheus"
)
2023-04-16 09:45:07 +00:00
const (
2023-04-01 07:48:23 +00:00
FlagLogicalDiskVolumeOldExclude = "collector.logical_disk.volume-blacklist"
FlagLogicalDiskVolumeOldInclude = "collector.logical_disk.volume-whitelist"
FlagLogicalDiskVolumeExclude = "collector.logical_disk.volume-exclude"
FlagLogicalDiskVolumeInclude = "collector.logical_disk.volume-include"
2023-04-16 09:45:07 +00:00
)
2016-08-27 09:34:27 +00:00
var (
2023-04-01 07:48:23 +00:00
volumeOldInclude * string
volumeOldExclude * string
volumeInclude * string
volumeExclude * string
volumeIncludeSet bool
volumeExcludeSet bool
2016-08-27 09:34:27 +00:00
)
2019-09-19 12:49:33 +00:00
// A LogicalDiskCollector is a Prometheus collector for perflib logicalDisk metrics
2016-08-27 09:34:27 +00:00
type LogicalDiskCollector struct {
2019-03-26 17:29:17 +00:00
RequestsQueued * prometheus . Desc
2022-12-30 02:15:06 +00:00
AvgReadQueue * prometheus . Desc
AvgWriteQueue * prometheus . Desc
2019-03-26 17:29:17 +00:00
ReadBytesTotal * prometheus . Desc
ReadsTotal * prometheus . Desc
WriteBytesTotal * prometheus . Desc
WritesTotal * prometheus . Desc
ReadTime * prometheus . Desc
WriteTime * prometheus . Desc
TotalSpace * prometheus . Desc
FreeSpace * prometheus . Desc
IdleTime * prometheus . Desc
SplitIOs * prometheus . Desc
ReadLatency * prometheus . Desc
WriteLatency * prometheus . Desc
ReadWriteLatency * prometheus . Desc
2016-08-27 09:34:27 +00:00
2023-04-01 07:48:23 +00:00
volumeIncludePattern * regexp . Regexp
volumeExcludePattern * regexp . Regexp
2016-08-27 09:34:27 +00:00
}
2023-04-16 09:45:07 +00:00
// newLogicalDiskCollectorFlags ...
func newLogicalDiskCollectorFlags ( app * kingpin . Application ) {
2023-04-01 07:48:23 +00:00
volumeInclude = app . Flag (
FlagLogicalDiskVolumeInclude ,
"Regexp of volumes to include. Volume name must both match include and not match exclude to be included." ,
) . Default ( ".+" ) . PreAction ( func ( c * kingpin . ParseContext ) error {
volumeIncludeSet = true
return nil
} ) . String ( )
volumeExclude = app . Flag (
FlagLogicalDiskVolumeExclude ,
"Regexp of volumes to exclude. Volume name must both match include and not match exclude to be included." ,
) . Default ( "" ) . PreAction ( func ( c * kingpin . ParseContext ) error {
volumeExcludeSet = true
return nil
} ) . String ( )
volumeOldInclude = app . Flag (
FlagLogicalDiskVolumeOldInclude ,
"DEPRECATED: Use --collector.logical_disk.volume-include" ,
) . Hidden ( ) . String ( )
volumeOldExclude = app . Flag (
FlagLogicalDiskVolumeOldExclude ,
"DEPRECATED: Use --collector.logical_disk.volume-exclude" ,
) . Hidden ( ) . String ( )
2023-04-16 09:45:07 +00:00
}
2022-12-21 05:44:29 +00:00
// newLogicalDiskCollector ...
func newLogicalDiskCollector ( ) ( Collector , error ) {
2023-04-01 07:48:23 +00:00
if * volumeOldExclude != "" {
if ! volumeExcludeSet {
log . Warnln ( "msg" , "--collector.logical_disk.volume-blacklist is DEPRECATED and will be removed in a future release, use --collector.logical_disk.volume-exclude" )
* volumeExclude = * volumeOldExclude
} else {
return nil , errors . New ( "--collector.logical_disk.volume-blacklist and --collector.logical_disk.volume-exclude are mutually exclusive" )
}
}
if * volumeOldInclude != "" {
if ! volumeIncludeSet {
log . Warnln ( "msg" , "--collector.logical_disk.volume-whitelist is DEPRECATED and will be removed in a future release, use --collector.logical_disk.volume-include" )
* volumeInclude = * volumeOldInclude
} else {
return nil , errors . New ( "--collector.logical_disk.volume-whitelist and --collector.logical_disk.volume-include are mutually exclusive" )
}
}
2016-08-27 14:33:23 +00:00
const subsystem = "logical_disk"
2016-08-27 09:34:27 +00:00
return & LogicalDiskCollector {
RequestsQueued : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "requests_queued" ) ,
2016-08-27 09:34:27 +00:00
"The number of requests queued to the disk (LogicalDisk.CurrentDiskQueueLength)" ,
[ ] string { "volume" } ,
nil ,
) ,
2022-12-30 02:15:06 +00:00
AvgReadQueue : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "avg_read_requests_queued" ) ,
"Average number of read requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskReadQueueLength)" ,
[ ] string { "volume" } ,
nil ,
) ,
AvgWriteQueue : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "avg_write_requests_queued" ) ,
"Average number of write requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskWriteQueueLength)" ,
[ ] string { "volume" } ,
nil ,
) ,
2016-08-27 09:34:27 +00:00
ReadBytesTotal : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "read_bytes_total" ) ,
2016-08-27 09:34:27 +00:00
"The number of bytes transferred from the disk during read operations (LogicalDisk.DiskReadBytesPerSec)" ,
[ ] string { "volume" } ,
nil ,
) ,
ReadsTotal : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "reads_total" ) ,
2016-08-27 09:34:27 +00:00
"The number of read operations on the disk (LogicalDisk.DiskReadsPerSec)" ,
[ ] string { "volume" } ,
nil ,
) ,
WriteBytesTotal : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "write_bytes_total" ) ,
2016-08-27 09:34:27 +00:00
"The number of bytes transferred to the disk during write operations (LogicalDisk.DiskWriteBytesPerSec)" ,
[ ] string { "volume" } ,
nil ,
) ,
WritesTotal : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "writes_total" ) ,
2016-08-27 09:34:27 +00:00
"The number of write operations on the disk (LogicalDisk.DiskWritesPerSec)" ,
[ ] string { "volume" } ,
nil ,
) ,
ReadTime : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "read_seconds_total" ) ,
2016-08-27 09:34:27 +00:00
"Seconds that the disk was busy servicing read requests (LogicalDisk.PercentDiskReadTime)" ,
[ ] string { "volume" } ,
nil ,
) ,
WriteTime : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "write_seconds_total" ) ,
2016-08-27 09:34:27 +00:00
"Seconds that the disk was busy servicing write requests (LogicalDisk.PercentDiskWriteTime)" ,
[ ] string { "volume" } ,
nil ,
) ,
FreeSpace : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "free_bytes" ) ,
2021-09-30 20:56:00 +00:00
"Free space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace)" ,
2016-08-27 09:34:27 +00:00
[ ] string { "volume" } ,
nil ,
) ,
TotalSpace : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "size_bytes" ) ,
2021-09-30 20:56:00 +00:00
"Total space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace_Base)" ,
2016-08-27 09:34:27 +00:00
[ ] string { "volume" } ,
nil ,
) ,
IdleTime : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "idle_seconds_total" ) ,
2016-08-27 09:34:27 +00:00
"Seconds that the disk was idle (LogicalDisk.PercentIdleTime)" ,
[ ] string { "volume" } ,
nil ,
) ,
SplitIOs : prometheus . NewDesc (
2016-09-01 14:04:43 +00:00
prometheus . BuildFQName ( Namespace , subsystem , "split_ios_total" ) ,
2016-08-27 09:34:27 +00:00
"The number of I/Os to the disk were split into multiple I/Os (LogicalDisk.SplitIOPerSec)" ,
[ ] string { "volume" } ,
nil ,
) ,
2019-03-26 17:29:17 +00:00
ReadLatency : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "read_latency_seconds_total" ) ,
"Shows the average time, in seconds, of a read operation from the disk (LogicalDisk.AvgDiskSecPerRead)" ,
[ ] string { "volume" } ,
nil ,
) ,
WriteLatency : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "write_latency_seconds_total" ) ,
"Shows the average time, in seconds, of a write operation to the disk (LogicalDisk.AvgDiskSecPerWrite)" ,
[ ] string { "volume" } ,
nil ,
) ,
ReadWriteLatency : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "read_write_latency_seconds_total" ) ,
"Shows the time, in seconds, of the average disk transfer (LogicalDisk.AvgDiskSecPerTransfer)" ,
[ ] string { "volume" } ,
nil ,
) ,
2023-04-01 07:48:23 +00:00
volumeIncludePattern : regexp . MustCompile ( fmt . Sprintf ( "^(?:%s)$" , * volumeInclude ) ) ,
volumeExcludePattern : regexp . MustCompile ( fmt . Sprintf ( "^(?:%s)$" , * volumeExclude ) ) ,
2016-09-01 14:04:43 +00:00
} , nil
2016-08-27 09:34:27 +00:00
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
2019-04-05 13:59:40 +00:00
func ( c * LogicalDiskCollector ) Collect ( ctx * ScrapeContext , ch chan <- prometheus . Metric ) error {
2019-09-19 12:49:33 +00:00
if desc , err := c . collect ( ctx , ch ) ; err != nil {
2018-04-05 05:27:26 +00:00
log . Error ( "failed collecting logical_disk metrics:" , desc , err )
2016-09-01 14:04:43 +00:00
return err
2016-08-27 09:34:27 +00:00
}
2016-09-01 14:04:43 +00:00
return nil
2016-08-27 09:34:27 +00:00
}
2018-10-04 19:35:33 +00:00
// Win32_PerfRawData_PerfDisk_LogicalDisk docs:
// - https://msdn.microsoft.com/en-us/windows/hardware/aa394307(v=vs.71) - Win32_PerfRawData_PerfDisk_LogicalDisk class
// - https://msdn.microsoft.com/en-us/library/ms803973.aspx - LogicalDisk object reference
2019-09-19 12:49:33 +00:00
type logicalDisk struct {
2022-12-30 02:15:06 +00:00
Name string
CurrentDiskQueueLength float64 ` perflib:"Current Disk Queue Length" `
AvgDiskReadQueueLength float64 ` perflib:"Avg. Disk Read Queue Length" `
AvgDiskWriteQueueLength float64 ` perflib:"Avg. Disk Write Queue Length" `
DiskReadBytesPerSec float64 ` perflib:"Disk Read Bytes/sec" `
DiskReadsPerSec float64 ` perflib:"Disk Reads/sec" `
DiskWriteBytesPerSec float64 ` perflib:"Disk Write Bytes/sec" `
DiskWritesPerSec float64 ` perflib:"Disk Writes/sec" `
PercentDiskReadTime float64 ` perflib:"% Disk Read Time" `
PercentDiskWriteTime float64 ` perflib:"% Disk Write Time" `
PercentFreeSpace float64 ` perflib:"% Free Space_Base" `
PercentFreeSpace_Base float64 ` perflib:"Free Megabytes" `
PercentIdleTime float64 ` perflib:"% Idle Time" `
SplitIOPerSec float64 ` perflib:"Split IO/Sec" `
AvgDiskSecPerRead float64 ` perflib:"Avg. Disk sec/Read" `
AvgDiskSecPerWrite float64 ` perflib:"Avg. Disk sec/Write" `
AvgDiskSecPerTransfer float64 ` perflib:"Avg. Disk sec/Transfer" `
2016-08-27 09:34:27 +00:00
}
2019-09-19 12:49:33 +00:00
func ( c * LogicalDiskCollector ) collect ( ctx * ScrapeContext , ch chan <- prometheus . Metric ) ( * prometheus . Desc , error ) {
var dst [ ] logicalDisk
if err := unmarshalObject ( ctx . perfObjects [ "LogicalDisk" ] , & dst ) ; err != nil {
2016-08-27 09:34:27 +00:00
return nil , err
}
for _ , volume := range dst {
if volume . Name == "_Total" ||
2023-04-01 07:48:23 +00:00
c . volumeExcludePattern . MatchString ( volume . Name ) ||
! c . volumeIncludePattern . MatchString ( volume . Name ) {
2016-08-27 09:34:27 +00:00
continue
}
ch <- prometheus . MustNewConstMetric (
c . RequestsQueued ,
prometheus . GaugeValue ,
2019-09-19 12:49:33 +00:00
volume . CurrentDiskQueueLength ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
2022-12-30 02:15:06 +00:00
ch <- prometheus . MustNewConstMetric (
c . AvgReadQueue ,
2023-01-01 22:16:06 +00:00
prometheus . GaugeValue ,
2022-12-30 02:15:06 +00:00
volume . AvgDiskReadQueueLength * ticksToSecondsScaleFactor ,
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . AvgWriteQueue ,
2023-01-01 22:16:06 +00:00
prometheus . GaugeValue ,
2022-12-30 02:15:06 +00:00
volume . AvgDiskWriteQueueLength * ticksToSecondsScaleFactor ,
volume . Name ,
)
2016-08-27 09:34:27 +00:00
ch <- prometheus . MustNewConstMetric (
c . ReadBytesTotal ,
prometheus . CounterValue ,
2019-09-19 12:49:33 +00:00
volume . DiskReadBytesPerSec ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . ReadsTotal ,
prometheus . CounterValue ,
2019-09-19 12:49:33 +00:00
volume . DiskReadsPerSec ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . WriteBytesTotal ,
prometheus . CounterValue ,
2019-09-19 12:49:33 +00:00
volume . DiskWriteBytesPerSec ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . WritesTotal ,
prometheus . CounterValue ,
2019-09-19 12:49:33 +00:00
volume . DiskWritesPerSec ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . ReadTime ,
prometheus . CounterValue ,
2019-09-19 12:49:33 +00:00
volume . PercentDiskReadTime ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . WriteTime ,
prometheus . CounterValue ,
2019-09-19 12:49:33 +00:00
volume . PercentDiskWriteTime ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . FreeSpace ,
prometheus . GaugeValue ,
2019-09-19 12:49:33 +00:00
volume . PercentFreeSpace_Base * 1024 * 1024 ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . TotalSpace ,
prometheus . GaugeValue ,
2019-09-19 12:49:33 +00:00
volume . PercentFreeSpace * 1024 * 1024 ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . IdleTime ,
prometheus . CounterValue ,
2019-09-19 12:49:33 +00:00
volume . PercentIdleTime ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . SplitIOs ,
prometheus . CounterValue ,
2019-09-19 12:49:33 +00:00
volume . SplitIOPerSec ,
2016-08-27 09:34:27 +00:00
volume . Name ,
)
2019-03-26 17:29:17 +00:00
ch <- prometheus . MustNewConstMetric (
c . ReadLatency ,
prometheus . CounterValue ,
2019-09-22 06:38:40 +00:00
volume . AvgDiskSecPerRead * ticksToSecondsScaleFactor ,
2019-03-26 17:29:17 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . WriteLatency ,
prometheus . CounterValue ,
2019-09-22 06:38:40 +00:00
volume . AvgDiskSecPerWrite * ticksToSecondsScaleFactor ,
2019-03-26 17:29:17 +00:00
volume . Name ,
)
ch <- prometheus . MustNewConstMetric (
c . ReadWriteLatency ,
prometheus . CounterValue ,
2019-09-22 06:38:40 +00:00
volume . AvgDiskSecPerTransfer * ticksToSecondsScaleFactor ,
2019-03-26 17:29:17 +00:00
volume . Name ,
)
2016-08-27 09:34:27 +00:00
}
return nil , nil
}