Skip to content

Commit

Permalink
Add disk id to logical disk
Browse files Browse the repository at this point in the history
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
  • Loading branch information
jkroepke committed May 18, 2024
1 parent a10ef15 commit f2c14ae
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/collector.logical_disk.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ If given, a disk needs to *not* match the exclude regexp in order for the corres

Name | Description | Type | Labels
-----|-------------|------|-------
`windows_logical_disk_info` | A metric with a constant '1' value labeled with logical disk information | gauge | `filesystem`,`serial_number`,`volume`,`volume_name`
`windows_logical_disk_info` | A metric with a constant '1' value labeled with logical disk information | gauge | `disk`,`partition`,`filesystem`,`serial_number`,`volume`,`volume_name`
`windows_logical_disk_requests_queued` | Number of requests outstanding on the disk at the time the performance data is collected | gauge | `volume`
`windows_logical_disk_avg_read_requests_queued` | Average number of read requests that were queued for the selected disk during the sample interval | gauge | `volume`
`windows_logical_disk_avg_write_requests_queued` | Average number of write requests that were queued for the selected disk during the sample interval | gauge | `volume`
Expand Down
46 changes: 43 additions & 3 deletions pkg/collector/logical_disk/logical_disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"regexp"
"strings"

"github.com/alecthomas/kingpin/v2"
"github.com/go-kit/log"
Expand All @@ -22,7 +23,12 @@ const (
FlagLogicalDiskVolumeExclude = "collector.logical_disk.volume-exclude"
FlagLogicalDiskVolumeInclude = "collector.logical_disk.volume-include"

win32DiskQuery = "SELECT VolumeName,DeviceID,FileSystem,VolumeSerialNumber FROM WIN32_LogicalDisk"
win32LogicalDiskQuery = "SELECT VolumeName,DeviceID,FileSystem,VolumeSerialNumber FROM WIN32_LogicalDisk"
win32LogicalDiskToPartitionQuery = "SELECT Antecedent, Dependent FROM Win32_LogicalDiskToPartition"
)

var (
reDiskID = regexp.MustCompile(`Disk #([0-9]+), Partition #([0-9]+)`)
)

type Win32_LogicalDisk struct {
Expand All @@ -32,6 +38,11 @@ type Win32_LogicalDisk struct {
FileSystem string
}

type Win32_LogicalDiskToPartition struct {
Antecedent string
Dependent string
}

type Config struct {
VolumeInclude string `yaml:"volume_include"`
VolumeExclude string `yaml:"volume_exclude"`
Expand Down Expand Up @@ -115,7 +126,7 @@ func (c *collector) Build() error {
c.Information = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "info"),
"A metric with a constant '1' value labeled with logical disk information",
[]string{"volume", "volume_name", "filesystem", "serial_number"},
[]string{"disk", "partition", "volume", "volume_name", "filesystem", "serial_number"},
nil,
)
c.RequestsQueued = prometheus.NewDesc(
Expand Down Expand Up @@ -260,6 +271,8 @@ func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
type logicalDisk struct {
Name string
VolumeName string
DiskID string
PartID string
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
AvgDiskReadQueueLength float64 `perflib:"Avg. Disk Read Queue Length"`
AvgDiskWriteQueueLength float64 `perflib:"Avg. Disk Write Queue Length"`
Expand All @@ -280,18 +293,27 @@ type logicalDisk struct {

func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
var dst_Win32_LogicalDisk []Win32_LogicalDisk
var dst_Win32_LogicalDiskToPartition []Win32_LogicalDiskToPartition

if err := wmi.Query(win32DiskQuery, &dst_Win32_LogicalDisk); err != nil {
if err := wmi.Query(win32LogicalDiskQuery, &dst_Win32_LogicalDisk); err != nil {
return err
}
if len(dst_Win32_LogicalDisk) == 0 {
return errors.New("WMI query returned empty result set")
}
if err := wmi.Query(win32LogicalDiskToPartitionQuery, &dst_Win32_LogicalDiskToPartition); err != nil {
return err
}
if len(dst_Win32_LogicalDiskToPartition) == 0 {
return errors.New("WMI query returned empty result set")
}

var (
filesystem string
serialNumber string
volumeName string
diskID string
partID string
dst []logicalDisk
)
if err := perflib.UnmarshalObject(ctx.PerfObjects["LogicalDisk"], &dst, c.logger); err != nil {
Expand All @@ -308,6 +330,8 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
filesystem = ""
serialNumber = ""
volumeName = ""
diskID = "-1"
partID = "-1"

for _, logicalDisk := range dst_Win32_LogicalDisk {
if logicalDisk.DeviceID == volume.Name {
Expand All @@ -319,10 +343,26 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
}
}

for _, logicalDisk := range dst_Win32_LogicalDiskToPartition {
if strings.HasSuffix(logicalDisk.Dependent, volume.Name+`"`) {
ret := reDiskID.FindStringSubmatch(logicalDisk.Antecedent)
if len(ret) == 3 {
diskID = ret[1]
partID = ret[2]
} else {
_ = level.Warn(c.logger).Log("msg", "failed to parse disk ID", "antecedent", logicalDisk.Antecedent)
}

break
}
}

ch <- prometheus.MustNewConstMetric(
c.Information,
prometheus.GaugeValue,
1,
diskID,
partID,
volume.Name,
volumeName,
filesystem,
Expand Down

0 comments on commit f2c14ae

Please sign in to comment.