Add label volume_name to logical_disk collector (#1442)

This commit is contained in:
Andrey Burtasov
2024-04-25 09:57:38 +03:00
committed by GitHub
parent e7464d9fcf
commit f21c119c74

View File

@@ -3,6 +3,7 @@
package logical_disk package logical_disk
import ( import (
"errors"
"fmt" "fmt"
"regexp" "regexp"
@@ -11,6 +12,7 @@ import (
"github.com/go-kit/log/level" "github.com/go-kit/log/level"
"github.com/prometheus-community/windows_exporter/pkg/perflib" "github.com/prometheus-community/windows_exporter/pkg/perflib"
"github.com/prometheus-community/windows_exporter/pkg/types" "github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/pkg/wmi"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@@ -19,8 +21,15 @@ const (
FlagLogicalDiskVolumeExclude = "collector.logical_disk.volume-exclude" FlagLogicalDiskVolumeExclude = "collector.logical_disk.volume-exclude"
FlagLogicalDiskVolumeInclude = "collector.logical_disk.volume-include" FlagLogicalDiskVolumeInclude = "collector.logical_disk.volume-include"
win32DiskQuery = "SELECT VolumeName,DeviceID FROM WIN32_LogicalDisk"
) )
type Win32_LogicalDisk struct {
VolumeName string
DeviceID string
}
type Config struct { type Config struct {
VolumeInclude string `yaml:"volume_include"` VolumeInclude string `yaml:"volume_include"`
VolumeExclude string `yaml:"volume_exclude"` VolumeExclude string `yaml:"volume_exclude"`
@@ -103,112 +112,112 @@ func (c *collector) Build() error {
c.RequestsQueued = prometheus.NewDesc( c.RequestsQueued = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "requests_queued"), prometheus.BuildFQName(types.Namespace, Name, "requests_queued"),
"The number of requests queued to the disk (LogicalDisk.CurrentDiskQueueLength)", "The number of requests queued to the disk (LogicalDisk.CurrentDiskQueueLength)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.AvgReadQueue = prometheus.NewDesc( c.AvgReadQueue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "avg_read_requests_queued"), prometheus.BuildFQName(types.Namespace, Name, "avg_read_requests_queued"),
"Average number of read requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskReadQueueLength)", "Average number of read requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskReadQueueLength)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.AvgWriteQueue = prometheus.NewDesc( c.AvgWriteQueue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "avg_write_requests_queued"), prometheus.BuildFQName(types.Namespace, Name, "avg_write_requests_queued"),
"Average number of write requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskWriteQueueLength)", "Average number of write requests that were queued for the selected disk during the sample interval (LogicalDisk.AvgDiskWriteQueueLength)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.ReadBytesTotal = prometheus.NewDesc( c.ReadBytesTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "read_bytes_total"), prometheus.BuildFQName(types.Namespace, Name, "read_bytes_total"),
"The number of bytes transferred from the disk during read operations (LogicalDisk.DiskReadBytesPerSec)", "The number of bytes transferred from the disk during read operations (LogicalDisk.DiskReadBytesPerSec)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.ReadsTotal = prometheus.NewDesc( c.ReadsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "reads_total"), prometheus.BuildFQName(types.Namespace, Name, "reads_total"),
"The number of read operations on the disk (LogicalDisk.DiskReadsPerSec)", "The number of read operations on the disk (LogicalDisk.DiskReadsPerSec)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.WriteBytesTotal = prometheus.NewDesc( c.WriteBytesTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "write_bytes_total"), prometheus.BuildFQName(types.Namespace, Name, "write_bytes_total"),
"The number of bytes transferred to the disk during write operations (LogicalDisk.DiskWriteBytesPerSec)", "The number of bytes transferred to the disk during write operations (LogicalDisk.DiskWriteBytesPerSec)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.WritesTotal = prometheus.NewDesc( c.WritesTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "writes_total"), prometheus.BuildFQName(types.Namespace, Name, "writes_total"),
"The number of write operations on the disk (LogicalDisk.DiskWritesPerSec)", "The number of write operations on the disk (LogicalDisk.DiskWritesPerSec)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.ReadTime = prometheus.NewDesc( c.ReadTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "read_seconds_total"), prometheus.BuildFQName(types.Namespace, Name, "read_seconds_total"),
"Seconds that the disk was busy servicing read requests (LogicalDisk.PercentDiskReadTime)", "Seconds that the disk was busy servicing read requests (LogicalDisk.PercentDiskReadTime)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.WriteTime = prometheus.NewDesc( c.WriteTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "write_seconds_total"), prometheus.BuildFQName(types.Namespace, Name, "write_seconds_total"),
"Seconds that the disk was busy servicing write requests (LogicalDisk.PercentDiskWriteTime)", "Seconds that the disk was busy servicing write requests (LogicalDisk.PercentDiskWriteTime)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.FreeSpace = prometheus.NewDesc( c.FreeSpace = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "free_bytes"), prometheus.BuildFQName(types.Namespace, Name, "free_bytes"),
"Free space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace)", "Free space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.TotalSpace = prometheus.NewDesc( c.TotalSpace = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "size_bytes"), prometheus.BuildFQName(types.Namespace, Name, "size_bytes"),
"Total space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace_Base)", "Total space in bytes, updates every 10-15 min (LogicalDisk.PercentFreeSpace_Base)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.IdleTime = prometheus.NewDesc( c.IdleTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "idle_seconds_total"), prometheus.BuildFQName(types.Namespace, Name, "idle_seconds_total"),
"Seconds that the disk was idle (LogicalDisk.PercentIdleTime)", "Seconds that the disk was idle (LogicalDisk.PercentIdleTime)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.SplitIOs = prometheus.NewDesc( c.SplitIOs = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "split_ios_total"), prometheus.BuildFQName(types.Namespace, Name, "split_ios_total"),
"The number of I/Os to the disk were split into multiple I/Os (LogicalDisk.SplitIOPerSec)", "The number of I/Os to the disk were split into multiple I/Os (LogicalDisk.SplitIOPerSec)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.ReadLatency = prometheus.NewDesc( c.ReadLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "read_latency_seconds_total"), prometheus.BuildFQName(types.Namespace, Name, "read_latency_seconds_total"),
"Shows the average time, in seconds, of a read operation from the disk (LogicalDisk.AvgDiskSecPerRead)", "Shows the average time, in seconds, of a read operation from the disk (LogicalDisk.AvgDiskSecPerRead)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.WriteLatency = prometheus.NewDesc( c.WriteLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "write_latency_seconds_total"), prometheus.BuildFQName(types.Namespace, Name, "write_latency_seconds_total"),
"Shows the average time, in seconds, of a write operation to the disk (LogicalDisk.AvgDiskSecPerWrite)", "Shows the average time, in seconds, of a write operation to the disk (LogicalDisk.AvgDiskSecPerWrite)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
c.ReadWriteLatency = prometheus.NewDesc( c.ReadWriteLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "read_write_latency_seconds_total"), prometheus.BuildFQName(types.Namespace, Name, "read_write_latency_seconds_total"),
"Shows the time, in seconds, of the average disk transfer (LogicalDisk.AvgDiskSecPerTransfer)", "Shows the time, in seconds, of the average disk transfer (LogicalDisk.AvgDiskSecPerTransfer)",
[]string{"volume"}, []string{"volume", "volume_name"},
nil, nil,
) )
@@ -241,6 +250,7 @@ func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
// - https://msdn.microsoft.com/en-us/library/ms803973.aspx - LogicalDisk object reference // - https://msdn.microsoft.com/en-us/library/ms803973.aspx - LogicalDisk object reference
type logicalDisk struct { type logicalDisk struct {
Name string Name string
VolumeName string
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"` CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
AvgDiskReadQueueLength float64 `perflib:"Avg. Disk Read Queue Length"` AvgDiskReadQueueLength float64 `perflib:"Avg. Disk Read Queue Length"`
AvgDiskWriteQueueLength float64 `perflib:"Avg. Disk Write Queue Length"` AvgDiskWriteQueueLength float64 `perflib:"Avg. Disk Write Queue Length"`
@@ -260,6 +270,15 @@ type logicalDisk struct {
} }
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) { func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
var dst_Win32_LogicalDisk []Win32_LogicalDisk
if err := wmi.Query(win32DiskQuery, &dst_Win32_LogicalDisk); err != nil {
return nil, err
}
if len(dst_Win32_LogicalDisk) == 0 {
return nil, errors.New("WMI query returned empty result set")
}
var dst []logicalDisk var dst []logicalDisk
if err := perflib.UnmarshalObject(ctx.PerfObjects["LogicalDisk"], &dst, c.logger); err != nil { if err := perflib.UnmarshalObject(ctx.PerfObjects["LogicalDisk"], &dst, c.logger); err != nil {
return nil, err return nil, err
@@ -271,118 +290,144 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
!c.volumeIncludePattern.MatchString(volume.Name) { !c.volumeIncludePattern.MatchString(volume.Name) {
continue continue
} }
for _, logicalDisk := range dst_Win32_LogicalDisk {
if logicalDisk.VolumeName == "" {
logicalDisk.VolumeName = "Local Disk"
}
if logicalDisk.DeviceID == volume.Name {
ch <- prometheus.MustNewConstMetric(
c.RequestsQueued,
prometheus.GaugeValue,
volume.CurrentDiskQueueLength,
volume.Name,
logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.RequestsQueued, c.AvgReadQueue,
prometheus.GaugeValue, prometheus.GaugeValue,
volume.CurrentDiskQueueLength, volume.AvgDiskReadQueueLength*perflib.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.AvgReadQueue, c.AvgWriteQueue,
prometheus.GaugeValue, prometheus.GaugeValue,
volume.AvgDiskReadQueueLength*perflib.TicksToSecondScaleFactor, volume.AvgDiskWriteQueueLength*perflib.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.AvgWriteQueue, c.ReadBytesTotal,
prometheus.GaugeValue, prometheus.CounterValue,
volume.AvgDiskWriteQueueLength*perflib.TicksToSecondScaleFactor, volume.DiskReadBytesPerSec,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.ReadBytesTotal, c.ReadsTotal,
prometheus.CounterValue, prometheus.CounterValue,
volume.DiskReadBytesPerSec, volume.DiskReadsPerSec,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.ReadsTotal, c.WriteBytesTotal,
prometheus.CounterValue, prometheus.CounterValue,
volume.DiskReadsPerSec, volume.DiskWriteBytesPerSec,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.WriteBytesTotal, c.WritesTotal,
prometheus.CounterValue, prometheus.CounterValue,
volume.DiskWriteBytesPerSec, volume.DiskWritesPerSec,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.WritesTotal, c.ReadTime,
prometheus.CounterValue, prometheus.CounterValue,
volume.DiskWritesPerSec, volume.PercentDiskReadTime,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.ReadTime, c.WriteTime,
prometheus.CounterValue, prometheus.CounterValue,
volume.PercentDiskReadTime, volume.PercentDiskWriteTime,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.WriteTime, c.FreeSpace,
prometheus.CounterValue, prometheus.GaugeValue,
volume.PercentDiskWriteTime, volume.PercentFreeSpace_Base*1024*1024,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.FreeSpace, c.TotalSpace,
prometheus.GaugeValue, prometheus.GaugeValue,
volume.PercentFreeSpace_Base*1024*1024, volume.PercentFreeSpace*1024*1024,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.TotalSpace, c.IdleTime,
prometheus.GaugeValue, prometheus.CounterValue,
volume.PercentFreeSpace*1024*1024, volume.PercentIdleTime,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.IdleTime, c.SplitIOs,
prometheus.CounterValue, prometheus.CounterValue,
volume.PercentIdleTime, volume.SplitIOPerSec,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.SplitIOs, c.ReadLatency,
prometheus.CounterValue, prometheus.CounterValue,
volume.SplitIOPerSec, volume.AvgDiskSecPerRead*perflib.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.ReadLatency, c.WriteLatency,
prometheus.CounterValue, prometheus.CounterValue,
volume.AvgDiskSecPerRead*perflib.TicksToSecondScaleFactor, volume.AvgDiskSecPerWrite*perflib.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.WriteLatency, c.ReadWriteLatency,
prometheus.CounterValue, prometheus.CounterValue,
volume.AvgDiskSecPerWrite*perflib.TicksToSecondScaleFactor, volume.AvgDiskSecPerTransfer*perflib.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) logicalDisk.VolumeName,
)
break
}
}
ch <- prometheus.MustNewConstMetric(
c.ReadWriteLatency,
prometheus.CounterValue,
volume.AvgDiskSecPerTransfer*perflib.TicksToSecondScaleFactor,
volume.Name,
)
} }
return nil, nil return nil, nil