1
0
mirror of https://github.com/prometheus-community/windows_exporter.git synced 2025-04-18 19:24:05 +03:00
Jan-Otto Kröpke e6a15d4ec4
chore: Remove registry based perfdata collector (#1742)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-17 21:51:12 +01:00

1751 lines
56 KiB
Go

//go:build windows
package hyperv
import (
"errors"
"fmt"
"log/slog"
"strings"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
)
const Name = "hyperv"
type Config struct{}
var ConfigDefaults = Config{}
// Collector is a Prometheus Collector for hyper-v.
type Collector struct {
config Config
miSession *mi.Session
// Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
healthCritical *prometheus.Desc
healthOk *prometheus.Desc
// Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition
physicalPagesAllocated *prometheus.Desc
preferredNUMANodeIndex *prometheus.Desc
remotePhysicalPages *prometheus.Desc
// Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition
addressSpaces *prometheus.Desc
attachedDevices *prometheus.Desc
depositedPages *prometheus.Desc
deviceDMAErrors *prometheus.Desc
deviceInterruptErrors *prometheus.Desc
deviceInterruptMappings *prometheus.Desc
deviceInterruptThrottleEvents *prometheus.Desc
gpaPages *prometheus.Desc
gpaSpaceModifications *prometheus.Desc
ioTLBFlushCost *prometheus.Desc
ioTLBFlushes *prometheus.Desc
recommendedVirtualTLBSize *prometheus.Desc
skippedTimerTicks *prometheus.Desc
value1Gdevicepages *prometheus.Desc
value1GGPApages *prometheus.Desc
value2Mdevicepages *prometheus.Desc
value2MGPApages *prometheus.Desc
value4Kdevicepages *prometheus.Desc
value4KGPApages *prometheus.Desc
virtualTLBFlushEntires *prometheus.Desc
virtualTLBPages *prometheus.Desc
// Win32_PerfRawData_HvStats_HyperVHypervisor
logicalProcessors *prometheus.Desc
virtualProcessors *prometheus.Desc
// Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor
hostLPGuestRunTimePercent *prometheus.Desc
hostLPHypervisorRunTimePercent *prometheus.Desc
hostLPTotalRunTimePercent *prometheus.Desc
// Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor
hostGuestRunTime *prometheus.Desc
hostHypervisorRunTime *prometheus.Desc
hostRemoteRunTime *prometheus.Desc
hostTotalRunTime *prometheus.Desc
hostCPUWaitTimePerDispatch *prometheus.Desc
// Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor
vmGuestRunTime *prometheus.Desc
vmHypervisorRunTime *prometheus.Desc
vmRemoteRunTime *prometheus.Desc
vmTotalRunTime *prometheus.Desc
vmCPUWaitTimePerDispatch *prometheus.Desc
// Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch
broadcastPacketsReceived *prometheus.Desc
broadcastPacketsSent *prometheus.Desc
bytes *prometheus.Desc
bytesReceived *prometheus.Desc
bytesSent *prometheus.Desc
directedPacketsReceived *prometheus.Desc
directedPacketsSent *prometheus.Desc
droppedPacketsIncoming *prometheus.Desc
droppedPacketsOutgoing *prometheus.Desc
extensionsDroppedPacketsIncoming *prometheus.Desc
extensionsDroppedPacketsOutgoing *prometheus.Desc
learnedMacAddresses *prometheus.Desc
multicastPacketsReceived *prometheus.Desc
multicastPacketsSent *prometheus.Desc
numberOfSendChannelMoves *prometheus.Desc
numberOfVMQMoves *prometheus.Desc
packetsFlooded *prometheus.Desc
packets *prometheus.Desc
packetsReceived *prometheus.Desc
packetsSent *prometheus.Desc
purgedMacAddresses *prometheus.Desc
// Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter
adapterBytesDropped *prometheus.Desc
adapterBytesReceived *prometheus.Desc
adapterBytesSent *prometheus.Desc
adapterFramesDropped *prometheus.Desc
adapterFramesReceived *prometheus.Desc
adapterFramesSent *prometheus.Desc
// Win32_PerfRawData_Counters_HyperVVirtualStorageDevice
vmStorageErrorCount *prometheus.Desc
vmStorageQueueLength *prometheus.Desc
vmStorageReadBytes *prometheus.Desc
vmStorageReadOperations *prometheus.Desc
vmStorageWriteBytes *prometheus.Desc
vmStorageWriteOperations *prometheus.Desc
// Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter
vmStorageBytesReceived *prometheus.Desc
vmStorageBytesSent *prometheus.Desc
vmStorageDroppedPacketsIncoming *prometheus.Desc
vmStorageDroppedPacketsOutgoing *prometheus.Desc
vmStoragePacketsReceived *prometheus.Desc
vmStoragePacketsSent *prometheus.Desc
// Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM
vmMemoryAddedMemory *prometheus.Desc
vmMemoryAveragePressure *prometheus.Desc
vmMemoryCurrentPressure *prometheus.Desc
vmMemoryGuestVisiblePhysicalMemory *prometheus.Desc
vmMemoryMaximumPressure *prometheus.Desc
vmMemoryMemoryAddOperations *prometheus.Desc
vmMemoryMemoryRemoveOperations *prometheus.Desc
vmMemoryMinimumPressure *prometheus.Desc
vmMemoryPhysicalMemory *prometheus.Desc
vmMemoryRemovedMemory *prometheus.Desc
}
func New(config *Config) *Collector {
if config == nil {
config = &ConfigDefaults
}
c := &Collector{
config: *config,
}
return c
}
func NewWithFlags(_ *kingpin.Application) *Collector {
return &Collector{}
}
func (c *Collector) GetName() string {
return Name
}
func (c *Collector) Close() error {
return nil
}
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
if miSession == nil {
return errors.New("miSession is nil")
}
c.miSession = miSession
buildSubsystemName := func(component string) string { return "hyperv_" + component }
c.healthCritical = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("health"), "critical"),
"This counter represents the number of virtual machines with critical health",
nil,
nil,
)
c.healthOk = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("health"), "ok"),
"This counter represents the number of virtual machines with ok health",
nil,
nil,
)
//
c.physicalPagesAllocated = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vid"), "physical_pages_allocated"),
"The number of physical pages allocated",
[]string{"vm"},
nil,
)
c.preferredNUMANodeIndex = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vid"), "preferred_numa_node_index"),
"The preferred NUMA node index associated with this partition",
[]string{"vm"},
nil,
)
c.remotePhysicalPages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vid"), "remote_physical_pages"),
"The number of physical pages not allocated from the preferred NUMA node",
[]string{"vm"},
nil,
)
//
c.addressSpaces = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "address_spaces"),
"The number of address spaces in the virtual TLB of the partition",
nil,
nil,
)
c.attachedDevices = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "attached_devices"),
"The number of devices attached to the partition",
nil,
nil,
)
c.depositedPages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "deposited_pages"),
"The number of pages deposited into the partition",
nil,
nil,
)
c.deviceDMAErrors = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "device_dma_errors"),
"An indicator of illegal DMA requests generated by all devices assigned to the partition",
nil,
nil,
)
c.deviceInterruptErrors = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "device_interrupt_errors"),
"An indicator of illegal interrupt requests generated by all devices assigned to the partition",
nil,
nil,
)
c.deviceInterruptMappings = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "device_interrupt_mappings"),
"The number of device interrupt mappings used by the partition",
nil,
nil,
)
c.deviceInterruptThrottleEvents = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "device_interrupt_throttle_events"),
"The number of times an interrupt from a device assigned to the partition was temporarily throttled because the device was generating too many interrupts",
nil,
nil,
)
c.gpaPages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "preferred_numa_node_index"),
"The number of pages present in the GPA space of the partition (zero for root partition)",
nil,
nil,
)
c.gpaSpaceModifications = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "gpa_space_modifications"),
"The rate of modifications to the GPA space of the partition",
nil,
nil,
)
c.ioTLBFlushCost = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "io_tlb_flush_cost"),
"The average time (in nanoseconds) spent processing an I/O TLB flush",
nil,
nil,
)
c.ioTLBFlushes = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "io_tlb_flush"),
"The rate of flushes of I/O TLBs of the partition",
nil,
nil,
)
c.recommendedVirtualTLBSize = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "recommended_virtual_tlb_size"),
"The recommended number of pages to be deposited for the virtual TLB",
nil,
nil,
)
c.skippedTimerTicks = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "physical_pages_allocated"),
"The number of timer interrupts skipped for the partition",
nil,
nil,
)
c.value1Gdevicepages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "1G_device_pages"),
"The number of 1G pages present in the device space of the partition",
nil,
nil,
)
c.value1GGPApages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "1G_gpa_pages"),
"The number of 1G pages present in the GPA space of the partition",
nil,
nil,
)
c.value2Mdevicepages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "2M_device_pages"),
"The number of 2M pages present in the device space of the partition",
nil,
nil,
)
c.value2MGPApages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "2M_gpa_pages"),
"The number of 2M pages present in the GPA space of the partition",
nil,
nil,
)
c.value4Kdevicepages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "4K_device_pages"),
"The number of 4K pages present in the device space of the partition",
nil,
nil,
)
c.value4KGPApages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "4K_gpa_pages"),
"The number of 4K pages present in the GPA space of the partition",
nil,
nil,
)
c.virtualTLBFlushEntires = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "virtual_tlb_flush_entires"),
"The rate of flushes of the entire virtual TLB",
nil,
nil,
)
c.virtualTLBPages = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("root_partition"), "virtual_tlb_pages"),
"The number of pages used by the virtual TLB of the partition",
nil,
nil,
)
//
c.virtualProcessors = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("hypervisor"), "virtual_processors"),
"The number of virtual processors present in the system",
nil,
nil,
)
c.logicalProcessors = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("hypervisor"), "logical_processors"),
"The number of logical processors present in the system",
nil,
nil,
)
//
c.hostLPGuestRunTimePercent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("host_lp"), "guest_run_time_percent"),
"The percentage of time spent by the processor in guest code",
[]string{"core"},
nil,
)
c.hostLPHypervisorRunTimePercent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("host_lp"), "hypervisor_run_time_percent"),
"The percentage of time spent by the processor in hypervisor code",
[]string{"core"},
nil,
)
c.hostLPTotalRunTimePercent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("host_lp"), "total_run_time_percent"),
"The percentage of time spent by the processor in guest and hypervisor code",
[]string{"core"},
nil,
)
//
c.hostGuestRunTime = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("host_cpu"), "guest_run_time"),
"The time spent by the virtual processor in guest code",
[]string{"core"},
nil,
)
c.hostHypervisorRunTime = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("host_cpu"), "hypervisor_run_time"),
"The time spent by the virtual processor in hypervisor code",
[]string{"core"},
nil,
)
c.hostRemoteRunTime = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("host_cpu"), "remote_run_time"),
"The time spent by the virtual processor running on a remote node",
[]string{"core"},
nil,
)
c.hostTotalRunTime = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("host_cpu"), "total_run_time"),
"The time spent by the virtual processor in guest and hypervisor code",
[]string{"core"},
nil,
)
c.hostCPUWaitTimePerDispatch = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("host_cpu"), "wait_time_per_dispatch_total"),
"Time in nanoseconds waiting for a virtual processor to be dispatched onto a logical processor",
[]string{"core"},
nil,
)
//
c.vmGuestRunTime = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_cpu"), "guest_run_time"),
"The time spent by the virtual processor in guest code",
[]string{"vm", "core"},
nil,
)
c.vmHypervisorRunTime = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_cpu"), "hypervisor_run_time"),
"The time spent by the virtual processor in hypervisor code",
[]string{"vm", "core"},
nil,
)
c.vmRemoteRunTime = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_cpu"), "remote_run_time"),
"The time spent by the virtual processor running on a remote node",
[]string{"vm", "core"},
nil,
)
c.vmTotalRunTime = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_cpu"), "total_run_time"),
"The time spent by the virtual processor in guest and hypervisor code",
[]string{"vm", "core"},
nil,
)
c.vmCPUWaitTimePerDispatch = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_cpu"), "wait_time_per_dispatch_total"),
"Time in nanoseconds waiting for a virtual processor to be dispatched onto a logical processor",
[]string{"vm", "core"},
nil,
)
//
c.broadcastPacketsReceived = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "broadcast_packets_received_total"),
"This represents the total number of broadcast packets received per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.broadcastPacketsSent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "broadcast_packets_sent_total"),
"This represents the total number of broadcast packets sent per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.bytes = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "bytes_total"),
"This represents the total number of bytes per second traversing the virtual switch",
[]string{"vswitch"},
nil,
)
c.bytesReceived = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "bytes_received_total"),
"This represents the total number of bytes received per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.bytesSent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "bytes_sent_total"),
"This represents the total number of bytes sent per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.directedPacketsReceived = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "directed_packets_received_total"),
"This represents the total number of directed packets received per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.directedPacketsSent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "directed_packets_send_total"),
"This represents the total number of directed packets sent per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.droppedPacketsIncoming = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "dropped_packets_incoming_total"),
"This represents the total number of packet dropped per second by the virtual switch in the incoming direction",
[]string{"vswitch"},
nil,
)
c.droppedPacketsOutgoing = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "dropped_packets_outcoming_total"),
"This represents the total number of packet dropped per second by the virtual switch in the outgoing direction",
[]string{"vswitch"},
nil,
)
c.extensionsDroppedPacketsIncoming = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "extensions_dropped_packets_incoming_total"),
"This represents the total number of packet dropped per second by the virtual switch extensions in the incoming direction",
[]string{"vswitch"},
nil,
)
c.extensionsDroppedPacketsOutgoing = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "extensions_dropped_packets_outcoming_total"),
"This represents the total number of packet dropped per second by the virtual switch extensions in the outgoing direction",
[]string{"vswitch"},
nil,
)
c.learnedMacAddresses = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "learned_mac_addresses_total"),
"This counter represents the total number of learned MAC addresses of the virtual switch",
[]string{"vswitch"},
nil,
)
c.multicastPacketsReceived = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "multicast_packets_received_total"),
"This represents the total number of multicast packets received per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.multicastPacketsSent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "multicast_packets_sent_total"),
"This represents the total number of multicast packets sent per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.numberOfSendChannelMoves = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "number_of_send_channel_moves_total"),
"This represents the total number of send channel moves per second on this virtual switch",
[]string{"vswitch"},
nil,
)
c.numberOfVMQMoves = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "number_of_vmq_moves_total"),
"This represents the total number of VMQ moves per second on this virtual switch",
[]string{"vswitch"},
nil,
)
c.packetsFlooded = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "packets_flooded_total"),
"This counter represents the total number of packets flooded by the virtual switch",
[]string{"vswitch"},
nil,
)
c.packets = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "packets_total"),
"This represents the total number of packets per second traversing the virtual switch",
[]string{"vswitch"},
nil,
)
c.packetsReceived = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "packets_received_total"),
"This represents the total number of packets received per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.packetsSent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "packets_sent_total"),
"This represents the total number of packets send per second by the virtual switch",
[]string{"vswitch"},
nil,
)
c.purgedMacAddresses = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vswitch"), "purged_mac_addresses_total"),
"This counter represents the total number of purged MAC addresses of the virtual switch",
[]string{"vswitch"},
nil,
)
//
c.adapterBytesDropped = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("ethernet"), "bytes_dropped"),
"Bytes Dropped is the number of bytes dropped on the network adapter",
[]string{"adapter"},
nil,
)
c.adapterBytesReceived = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("ethernet"), "bytes_received"),
"Bytes received is the number of bytes received on the network adapter",
[]string{"adapter"},
nil,
)
c.adapterBytesSent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("ethernet"), "bytes_sent"),
"Bytes sent is the number of bytes sent over the network adapter",
[]string{"adapter"},
nil,
)
c.adapterFramesDropped = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("ethernet"), "frames_dropped"),
"Frames Dropped is the number of frames dropped on the network adapter",
[]string{"adapter"},
nil,
)
c.adapterFramesReceived = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("ethernet"), "frames_received"),
"Frames received is the number of frames received on the network adapter",
[]string{"adapter"},
nil,
)
c.adapterFramesSent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("ethernet"), "frames_sent"),
"Frames sent is the number of frames sent over the network adapter",
[]string{"adapter"},
nil,
)
//
c.vmStorageErrorCount = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_device"), "error_count"),
"This counter represents the total number of errors that have occurred on this virtual device",
[]string{"vm_device"},
nil,
)
c.vmStorageQueueLength = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_device"), "queue_length"),
"This counter represents the current queue length on this virtual device",
[]string{"vm_device"},
nil,
)
c.vmStorageReadBytes = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_device"), "bytes_read"),
"This counter represents the total number of bytes that have been read per second on this virtual device",
[]string{"vm_device"},
nil,
)
c.vmStorageReadOperations = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_device"), "operations_read"),
"This counter represents the number of read operations that have occurred per second on this virtual device",
[]string{"vm_device"},
nil,
)
c.vmStorageWriteBytes = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_device"), "bytes_written"),
"This counter represents the total number of bytes that have been written per second on this virtual device",
[]string{"vm_device"},
nil,
)
c.vmStorageWriteOperations = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_device"), "operations_written"),
"This counter represents the number of write operations that have occurred per second on this virtual device",
[]string{"vm_device"},
nil,
)
//
c.vmStorageBytesReceived = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_interface"), "bytes_received"),
"This counter represents the total number of bytes received per second by the network adapter",
[]string{"vm_interface"},
nil,
)
c.vmStorageBytesSent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_interface"), "bytes_sent"),
"This counter represents the total number of bytes sent per second by the network adapter",
[]string{"vm_interface"},
nil,
)
c.vmStorageDroppedPacketsIncoming = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_interface"), "packets_incoming_dropped"),
"This counter represents the total number of dropped packets per second in the incoming direction of the network adapter",
[]string{"vm_interface"},
nil,
)
c.vmStorageDroppedPacketsOutgoing = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_interface"), "packets_outgoing_dropped"),
"This counter represents the total number of dropped packets per second in the outgoing direction of the network adapter",
[]string{"vm_interface"},
nil,
)
c.vmStoragePacketsReceived = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_interface"), "packets_received"),
"This counter represents the total number of packets received per second by the network adapter",
[]string{"vm_interface"},
nil,
)
c.vmStoragePacketsSent = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_interface"), "packets_sent"),
"This counter represents the total number of packets sent per second by the network adapter",
[]string{"vm_interface"},
nil,
)
//
c.vmMemoryAddedMemory = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "added_total"),
"This counter represents memory in MB added to the VM",
[]string{"vm"},
nil,
)
c.vmMemoryAveragePressure = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "pressure_average"),
"This gauge represents the average pressure in the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryCurrentPressure = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "pressure_current"),
"This gauge represents the current pressure in the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryGuestVisiblePhysicalMemory = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "physical_guest_visible"),
"'This gauge represents the amount of memory in MB visible to the VM guest.'",
[]string{"vm"},
nil,
)
c.vmMemoryMaximumPressure = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "pressure_maximum"),
"This gauge represents the maximum pressure band in the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryMemoryAddOperations = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "add_operations_total"),
"This counter represents the number of operations adding memory to the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryMemoryRemoveOperations = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "remove_operations_total"),
"This counter represents the number of operations removing memory from the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryMinimumPressure = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "pressure_minimum"),
"This gauge represents the minimum pressure band in the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryPhysicalMemory = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "physical"),
"This gauge represents the current amount of memory in MB assigned to the VM.",
[]string{"vm"},
nil,
)
c.vmMemoryRemovedMemory = prometheus.NewDesc(
prometheus.BuildFQName("windows", buildSubsystemName("vm_memory"), "removed_total"),
"This counter represents memory in MB removed from the VM",
[]string{"vm"},
nil,
)
return nil
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
if err := c.collectVmHealth(ch); err != nil {
return err
}
if err := c.collectVmVid(ch); err != nil {
return err
}
if err := c.collectVmHv(ch); err != nil {
return err
}
if err := c.collectVmProcessor(ch); err != nil {
return err
}
if err := c.collectHostLPUsage(nil, ch); err != nil {
return err
}
if err := c.collectHostCpuUsage(nil, ch); err != nil {
return err
}
if err := c.collectVmCpuUsage(nil, ch); err != nil {
return err
}
if err := c.collectVmSwitch(ch); err != nil {
return err
}
if err := c.collectVmEthernet(ch); err != nil {
return err
}
if err := c.collectVmStorage(ch); err != nil {
return err
}
if err := c.collectVmNetwork(ch); err != nil {
return err
}
if err := c.collectVmMemory(ch); err != nil {
return err
}
return nil
}
// Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary vm health status.
type Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary struct {
HealthCritical uint32 `mi:"HealthCritical"`
HealthOk uint32 `mi:"HealthOK"`
}
func (c *Collector) collectVmHealth(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, health := range dst {
ch <- prometheus.MustNewConstMetric(
c.healthCritical,
prometheus.GaugeValue,
float64(health.HealthCritical),
)
ch <- prometheus.MustNewConstMetric(
c.healthOk,
prometheus.GaugeValue,
float64(health.HealthOk),
)
}
return nil
}
// Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition ..,.
type Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition struct {
Name string `mi:"Name"`
PhysicalPagesAllocated uint64 `mi:"PhysicalPagesAllocated"`
PreferredNUMANodeIndex uint64 `mi:"PreferredNUMANodeIndex"`
RemotePhysicalPages uint64 `mi:"RemotePhysicalPages"`
}
func (c *Collector) collectVmVid(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, page := range dst {
if strings.Contains(page.Name, "_Total") {
continue
}
ch <- prometheus.MustNewConstMetric(
c.physicalPagesAllocated,
prometheus.GaugeValue,
float64(page.PhysicalPagesAllocated),
page.Name,
)
ch <- prometheus.MustNewConstMetric(
c.preferredNUMANodeIndex,
prometheus.GaugeValue,
float64(page.PreferredNUMANodeIndex),
page.Name,
)
ch <- prometheus.MustNewConstMetric(
c.remotePhysicalPages,
prometheus.GaugeValue,
float64(page.RemotePhysicalPages),
page.Name,
)
}
return nil
}
// Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition ...
type Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition struct {
Name string `mi:"Name"`
AddressSpaces uint64 `mi:"AddressSpaces"`
AttachedDevices uint64 `mi:"AttachedDevices"`
DepositedPages uint64 `mi:"DepositedPages"`
DeviceDMAErrors uint64 `mi:"DeviceDMAErrors"`
DeviceInterruptErrors uint64 `mi:"DeviceInterruptErrors"`
DeviceInterruptMappings uint64 `mi:"DeviceInterruptMappings"`
DeviceInterruptThrottleEvents uint64 `mi:"DeviceInterruptThrottleEvents"`
GPAPages uint64 `mi:"GPAPages"`
GPASpaceModificationsPersec uint64 `mi:"GPASpaceModificationsPersec"`
IOTLBFlushCost uint64 `mi:"IOTLBFlushCost"`
IOTLBFlushesPersec uint64 `mi:"IOTLBFlushesPersec"`
RecommendedVirtualTLBSize uint64 `mi:"RecommendedVirtualTLBSize"`
SkippedTimerTicks uint64 `mi:"SkippedTimerTicks"`
Value1Gdevicepages uint64 `mi:"Value1Gdevicepages"`
Value1GGPApages uint64 `mi:"Value1GGPApages"`
Value2Mdevicepages uint64 `mi:"Value2Mdevicepages"`
Value2MGPApages uint64 `mi:"Value2MGPApages"`
Value4Kdevicepages uint64 `mi:"Value4Kdevicepages"`
Value4KGPApages uint64 `mi:"Value4KGPApages"`
VirtualTLBFlushEntiresPersec uint64 `mi:"VirtualTLBFlushEntiresPersec"`
VirtualTLBPages uint64 `mi:"VirtualTLBPages"`
}
func (c *Collector) collectVmHv(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
ch <- prometheus.MustNewConstMetric(
c.addressSpaces,
prometheus.GaugeValue,
float64(obj.AddressSpaces),
)
ch <- prometheus.MustNewConstMetric(
c.attachedDevices,
prometheus.GaugeValue,
float64(obj.AttachedDevices),
)
ch <- prometheus.MustNewConstMetric(
c.depositedPages,
prometheus.GaugeValue,
float64(obj.DepositedPages),
)
ch <- prometheus.MustNewConstMetric(
c.deviceDMAErrors,
prometheus.GaugeValue,
float64(obj.DeviceDMAErrors),
)
ch <- prometheus.MustNewConstMetric(
c.deviceInterruptErrors,
prometheus.GaugeValue,
float64(obj.DeviceInterruptErrors),
)
ch <- prometheus.MustNewConstMetric(
c.deviceInterruptThrottleEvents,
prometheus.GaugeValue,
float64(obj.DeviceInterruptThrottleEvents),
)
ch <- prometheus.MustNewConstMetric(
c.gpaPages,
prometheus.GaugeValue,
float64(obj.GPAPages),
)
ch <- prometheus.MustNewConstMetric(
c.gpaSpaceModifications,
prometheus.CounterValue,
float64(obj.GPASpaceModificationsPersec),
)
ch <- prometheus.MustNewConstMetric(
c.ioTLBFlushCost,
prometheus.GaugeValue,
float64(obj.IOTLBFlushCost),
)
ch <- prometheus.MustNewConstMetric(
c.ioTLBFlushes,
prometheus.CounterValue,
float64(obj.IOTLBFlushesPersec),
)
ch <- prometheus.MustNewConstMetric(
c.recommendedVirtualTLBSize,
prometheus.GaugeValue,
float64(obj.RecommendedVirtualTLBSize),
)
ch <- prometheus.MustNewConstMetric(
c.skippedTimerTicks,
prometheus.GaugeValue,
float64(obj.SkippedTimerTicks),
)
ch <- prometheus.MustNewConstMetric(
c.value1Gdevicepages,
prometheus.GaugeValue,
float64(obj.Value1Gdevicepages),
)
ch <- prometheus.MustNewConstMetric(
c.value1GGPApages,
prometheus.GaugeValue,
float64(obj.Value1GGPApages),
)
ch <- prometheus.MustNewConstMetric(
c.value2Mdevicepages,
prometheus.GaugeValue,
float64(obj.Value2Mdevicepages),
)
ch <- prometheus.MustNewConstMetric(
c.value2MGPApages,
prometheus.GaugeValue,
float64(obj.Value2MGPApages),
)
ch <- prometheus.MustNewConstMetric(
c.value4Kdevicepages,
prometheus.GaugeValue,
float64(obj.Value4Kdevicepages),
)
ch <- prometheus.MustNewConstMetric(
c.value4KGPApages,
prometheus.GaugeValue,
float64(obj.Value4KGPApages),
)
ch <- prometheus.MustNewConstMetric(
c.virtualTLBFlushEntires,
prometheus.CounterValue,
float64(obj.VirtualTLBFlushEntiresPersec),
)
ch <- prometheus.MustNewConstMetric(
c.virtualTLBPages,
prometheus.GaugeValue,
float64(obj.VirtualTLBPages),
)
}
return nil
}
// Win32_PerfRawData_HvStats_HyperVHypervisor ...
type Win32_PerfRawData_HvStats_HyperVHypervisor struct {
LogicalProcessors uint64 `mi:"LogicalProcessors"`
VirtualProcessors uint64 `mi:"VirtualProcessors"`
}
func (c *Collector) collectVmProcessor(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_HvStats_HyperVHypervisor
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_HvStats_HyperVHypervisor"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
ch <- prometheus.MustNewConstMetric(
c.logicalProcessors,
prometheus.GaugeValue,
float64(obj.LogicalProcessors),
)
ch <- prometheus.MustNewConstMetric(
c.virtualProcessors,
prometheus.GaugeValue,
float64(obj.VirtualProcessors),
)
}
return nil
}
// Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor ...
type Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor struct {
Name string `mi:"Name"`
PercentGuestRunTime uint64 `mi:"PercentGuestRunTime"`
PercentHypervisorRunTime uint64 `mi:"PercentHypervisorRunTime"`
PercentTotalRunTime uint64 `mi:"PercentTotalRunTime"`
}
func (c *Collector) collectHostLPUsage(logger *slog.Logger, ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
// The name format is Hv LP <core id>
parts := strings.Split(obj.Name, " ")
if len(parts) != 3 {
logger.Warn(fmt.Sprintf("Unexpected format of Name in collectHostLPUsage: %q", obj.Name))
continue
}
coreId := parts[2]
ch <- prometheus.MustNewConstMetric(
c.hostLPGuestRunTimePercent,
prometheus.GaugeValue,
float64(obj.PercentGuestRunTime),
coreId,
)
ch <- prometheus.MustNewConstMetric(
c.hostLPHypervisorRunTimePercent,
prometheus.GaugeValue,
float64(obj.PercentHypervisorRunTime),
coreId,
)
ch <- prometheus.MustNewConstMetric(
c.hostLPTotalRunTimePercent,
prometheus.GaugeValue,
float64(obj.PercentTotalRunTime),
coreId,
)
}
return nil
}
// Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor ...
type Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor struct {
Name string `mi:"Name"`
PercentGuestRunTime uint64 `mi:"PercentGuestRunTime"`
PercentHypervisorRunTime uint64 `mi:"PercentHypervisorRunTime"`
PercentRemoteRunTime uint64 `mi:"PercentRemoteRunTime"`
PercentTotalRunTime uint64 `mi:"PercentTotalRunTime"`
CPUWaitTimePerDispatch uint64 `mi:"CPUWaitTimePerDispatch"`
}
func (c *Collector) collectHostCpuUsage(logger *slog.Logger, ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
// The name format is Root VP <core id>
parts := strings.Split(obj.Name, " ")
if len(parts) != 3 {
logger.Warn("Unexpected format of Name in collectHostCpuUsage: " + obj.Name)
continue
}
coreId := parts[2]
ch <- prometheus.MustNewConstMetric(
c.hostGuestRunTime,
prometheus.GaugeValue,
float64(obj.PercentGuestRunTime),
coreId,
)
ch <- prometheus.MustNewConstMetric(
c.hostHypervisorRunTime,
prometheus.GaugeValue,
float64(obj.PercentHypervisorRunTime),
coreId,
)
ch <- prometheus.MustNewConstMetric(
c.hostRemoteRunTime,
prometheus.GaugeValue,
float64(obj.PercentRemoteRunTime),
coreId,
)
ch <- prometheus.MustNewConstMetric(
c.hostTotalRunTime,
prometheus.GaugeValue,
float64(obj.PercentTotalRunTime),
coreId,
)
ch <- prometheus.MustNewConstMetric(
c.hostCPUWaitTimePerDispatch,
prometheus.CounterValue,
float64(obj.CPUWaitTimePerDispatch),
coreId,
)
}
return nil
}
// Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor ...
type Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor struct {
Name string `mi:"Name"`
PercentGuestRunTime uint64 `mi:"PercentGuestRunTime"`
PercentHypervisorRunTime uint64 `mi:"PercentHypervisorRunTime"`
PercentRemoteRunTime uint64 `mi:"PercentRemoteRunTime"`
PercentTotalRunTime uint64 `mi:"PercentTotalRunTime"`
CPUWaitTimePerDispatch uint64 `mi:"CPUWaitTimePerDispatch"`
}
func (c *Collector) collectVmCpuUsage(logger *slog.Logger, ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
// The name format is <VM Name>:Hv VP <vcore id>
parts := strings.Split(obj.Name, ":")
if len(parts) != 2 {
logger.Warn(fmt.Sprintf("Unexpected format of Name in collectVmCpuUsage: %q, expected %q. Skipping.", obj.Name, "<VM Name>:Hv VP <vcore id>"))
continue
}
coreParts := strings.Split(parts[1], " ")
if len(coreParts) != 3 {
logger.Warn(fmt.Sprintf("Unexpected format of core identifier in collectVmCpuUsage: %q, expected %q. Skipping.", parts[1], "Hv VP <vcore id>"))
continue
}
vmName := parts[0]
coreId := coreParts[2]
ch <- prometheus.MustNewConstMetric(
c.vmGuestRunTime,
prometheus.GaugeValue,
float64(obj.PercentGuestRunTime),
vmName, coreId,
)
ch <- prometheus.MustNewConstMetric(
c.vmHypervisorRunTime,
prometheus.GaugeValue,
float64(obj.PercentHypervisorRunTime),
vmName, coreId,
)
ch <- prometheus.MustNewConstMetric(
c.vmRemoteRunTime,
prometheus.GaugeValue,
float64(obj.PercentRemoteRunTime),
vmName, coreId,
)
ch <- prometheus.MustNewConstMetric(
c.vmTotalRunTime,
prometheus.GaugeValue,
float64(obj.PercentTotalRunTime),
vmName, coreId,
)
ch <- prometheus.MustNewConstMetric(
c.vmCPUWaitTimePerDispatch,
prometheus.CounterValue,
float64(obj.CPUWaitTimePerDispatch),
vmName, coreId,
)
}
return nil
}
// Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch ...
type Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch struct {
Name string `mi:"Name"`
BroadcastPacketsReceivedPersec uint64 `mi:"BroadcastPacketsReceivedPersec"`
BroadcastPacketsSentPersec uint64 `mi:"BroadcastPacketsSentPersec"`
BytesPersec uint64 `mi:"BytesPersec"`
BytesReceivedPersec uint64 `mi:"BytesReceivedPersec"`
BytesSentPersec uint64 `mi:"BytesSentPersec"`
DirectedPacketsReceivedPersec uint64 `mi:"DirectedPacketsReceivedPersec"`
DirectedPacketsSentPersec uint64 `mi:"DirectedPacketsSentPersec"`
DroppedPacketsIncomingPersec uint64 `mi:"DroppedPacketsIncomingPersec"`
DroppedPacketsOutgoingPersec uint64 `mi:"DroppedPacketsOutgoingPersec"`
ExtensionsDroppedPacketsIncomingPersec uint64 `mi:"ExtensionsDroppedPacketsIncomingPersec"`
ExtensionsDroppedPacketsOutgoingPersec uint64 `mi:"ExtensionsDroppedPacketsOutgoingPersec"`
LearnedMacAddresses uint64 `mi:"LearnedMacAddresses"`
LearnedMacAddressesPersec uint64 `mi:"LearnedMacAddressesPersec"`
MulticastPacketsReceivedPersec uint64 `mi:"MulticastPacketsReceivedPersec"`
MulticastPacketsSentPersec uint64 `mi:"MulticastPacketsSentPersec"`
NumberofSendChannelMovesPersec uint64 `mi:"NumberofSendChannelMovesPersec"`
NumberofVMQMovesPersec uint64 `mi:"NumberofVMQMovesPersec"`
PacketsFlooded uint64 `mi:"PacketsFlooded"`
PacketsFloodedPersec uint64 `mi:"PacketsFloodedPersec"`
PacketsPersec uint64 `mi:"PacketsPersec"`
PacketsReceivedPersec uint64 `mi:"PacketsReceivedPersec"`
PacketsSentPersec uint64 `mi:"PacketsSentPersec"`
PurgedMacAddresses uint64 `mi:"PurgedMacAddresses"`
PurgedMacAddressesPersec uint64 `mi:"PurgedMacAddressesPersec"`
}
func (c *Collector) collectVmSwitch(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
ch <- prometheus.MustNewConstMetric(
c.broadcastPacketsReceived,
prometheus.CounterValue,
float64(obj.BroadcastPacketsReceivedPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.broadcastPacketsSent,
prometheus.CounterValue,
float64(obj.BroadcastPacketsSentPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.bytes,
prometheus.CounterValue,
float64(obj.BytesPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.bytesReceived,
prometheus.CounterValue,
float64(obj.BytesReceivedPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.bytesSent,
prometheus.CounterValue,
float64(obj.BytesSentPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.directedPacketsReceived,
prometheus.CounterValue,
float64(obj.DirectedPacketsReceivedPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.directedPacketsSent,
prometheus.CounterValue,
float64(obj.DirectedPacketsSentPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.droppedPacketsIncoming,
prometheus.CounterValue,
float64(obj.DroppedPacketsIncomingPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.droppedPacketsOutgoing,
prometheus.CounterValue,
float64(obj.DroppedPacketsOutgoingPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.extensionsDroppedPacketsIncoming,
prometheus.CounterValue,
float64(obj.ExtensionsDroppedPacketsIncomingPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.extensionsDroppedPacketsOutgoing,
prometheus.CounterValue,
float64(obj.ExtensionsDroppedPacketsOutgoingPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.learnedMacAddresses,
prometheus.CounterValue,
float64(obj.LearnedMacAddresses),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.multicastPacketsReceived,
prometheus.CounterValue,
float64(obj.MulticastPacketsReceivedPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.multicastPacketsSent,
prometheus.CounterValue,
float64(obj.MulticastPacketsSentPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.numberOfSendChannelMoves,
prometheus.CounterValue,
float64(obj.NumberofSendChannelMovesPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.numberOfVMQMoves,
prometheus.CounterValue,
float64(obj.NumberofVMQMovesPersec),
obj.Name,
)
// ...
ch <- prometheus.MustNewConstMetric(
c.packetsFlooded,
prometheus.CounterValue,
float64(obj.PacketsFlooded),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.packets,
prometheus.CounterValue,
float64(obj.PacketsPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.packetsReceived,
prometheus.CounterValue,
float64(obj.PacketsReceivedPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.packetsSent,
prometheus.CounterValue,
float64(obj.PacketsSentPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.purgedMacAddresses,
prometheus.CounterValue,
float64(obj.PurgedMacAddresses),
obj.Name,
)
}
return nil
}
// Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter ...
type Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter struct {
Name string `mi:"Name"`
BytesDropped uint64 `mi:"BytesDropped"`
BytesReceivedPersec uint64 `mi:"BytesReceivedPersec"`
BytesSentPersec uint64 `mi:"BytesSentPersec"`
FramesDropped uint64 `mi:"FramesDropped"`
FramesReceivedPersec uint64 `mi:"FramesReceivedPersec"`
FramesSentPersec uint64 `mi:"FramesSentPersec"`
}
func (c *Collector) collectVmEthernet(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
ch <- prometheus.MustNewConstMetric(
c.adapterBytesDropped,
prometheus.GaugeValue,
float64(obj.BytesDropped),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.adapterBytesReceived,
prometheus.CounterValue,
float64(obj.BytesReceivedPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.adapterBytesSent,
prometheus.CounterValue,
float64(obj.BytesSentPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.adapterFramesReceived,
prometheus.CounterValue,
float64(obj.FramesReceivedPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.adapterFramesDropped,
prometheus.CounterValue,
float64(obj.FramesDropped),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.adapterFramesSent,
prometheus.CounterValue,
float64(obj.FramesSentPersec),
obj.Name,
)
}
return nil
}
// Win32_PerfRawData_Counters_HyperVVirtualStorageDevice ...
type Win32_PerfRawData_Counters_HyperVVirtualStorageDevice struct {
Name string `mi:"Name"`
ErrorCount uint64 `mi:"ErrorCount"`
QueueLength uint32 `mi:"QueueLength"`
ReadBytesPersec uint64 `mi:"ReadBytesPersec"`
ReadOperationsPerSec uint64 `mi:"ReadOperationsPerSec"`
WriteBytesPersec uint64 `mi:"WriteBytesPersec"`
WriteOperationsPerSec uint64 `mi:"WriteOperationsPerSec"`
}
func (c *Collector) collectVmStorage(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_Counters_HyperVVirtualStorageDevice
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_Counters_HyperVVirtualStorageDevice"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
ch <- prometheus.MustNewConstMetric(
c.vmStorageErrorCount,
prometheus.CounterValue,
float64(obj.ErrorCount),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStorageQueueLength,
prometheus.CounterValue,
float64(obj.QueueLength),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStorageReadBytes,
prometheus.CounterValue,
float64(obj.ReadBytesPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStorageReadOperations,
prometheus.CounterValue,
float64(obj.ReadOperationsPerSec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStorageWriteBytes,
prometheus.CounterValue,
float64(obj.WriteBytesPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStorageWriteOperations,
prometheus.CounterValue,
float64(obj.WriteOperationsPerSec),
obj.Name,
)
}
return nil
}
// Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter ...
type Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter struct {
Name string `mi:"Name"`
BytesReceivedPersec uint64 `mi:"BytesReceivedPersec"`
BytesSentPersec uint64 `mi:"BytesSentPersec"`
DroppedPacketsIncomingPersec uint64 `mi:"DroppedPacketsIncomingPersec"`
DroppedPacketsOutgoingPersec uint64 `mi:"DroppedPacketsOutgoingPersec"`
PacketsReceivedPersec uint64 `mi:"PacketsReceivedPersec"`
PacketsSentPersec uint64 `mi:"PacketsSentPersec"`
}
func (c *Collector) collectVmNetwork(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
ch <- prometheus.MustNewConstMetric(
c.vmStorageBytesReceived,
prometheus.CounterValue,
float64(obj.BytesReceivedPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStorageBytesSent,
prometheus.CounterValue,
float64(obj.BytesSentPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStorageDroppedPacketsIncoming,
prometheus.CounterValue,
float64(obj.DroppedPacketsIncomingPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStorageDroppedPacketsOutgoing,
prometheus.CounterValue,
float64(obj.DroppedPacketsOutgoingPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStoragePacketsReceived,
prometheus.CounterValue,
float64(obj.PacketsReceivedPersec),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmStoragePacketsSent,
prometheus.CounterValue,
float64(obj.PacketsSentPersec),
obj.Name,
)
}
return nil
}
// Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM ...
type Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM struct {
Name string `mi:"Name"`
AddedMemory uint64 `mi:"AddedMemory"`
AveragePressure uint64 `mi:"AveragePressure"`
CurrentPressure uint64 `mi:"CurrentPressure"`
GuestVisiblePhysicalMemory uint64 `mi:"GuestVisiblePhysicalMemory"`
MaximumPressure uint64 `mi:"MaximumPressure"`
MemoryAddOperations uint64 `mi:"MemoryAddOperations"`
MemoryRemoveOperations uint64 `mi:"MemoryRemoveOperations"`
MinimumPressure uint64 `mi:"MinimumPressure"`
PhysicalMemory uint64 `mi:"PhysicalMemory"`
RemovedMemory uint64 `mi:"RemovedMemory"`
}
func (c *Collector) collectVmMemory(ch chan<- prometheus.Metric) error {
var dst []Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM"))); err != nil {
return fmt.Errorf("WMI query failed: %w", err)
}
for _, obj := range dst {
if strings.Contains(obj.Name, "_Total") {
continue
}
ch <- prometheus.MustNewConstMetric(
c.vmMemoryAddedMemory,
prometheus.CounterValue,
float64(obj.AddedMemory),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryAveragePressure,
prometheus.GaugeValue,
float64(obj.AveragePressure),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryCurrentPressure,
prometheus.GaugeValue,
float64(obj.CurrentPressure),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryGuestVisiblePhysicalMemory,
prometheus.GaugeValue,
float64(obj.GuestVisiblePhysicalMemory),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryMaximumPressure,
prometheus.GaugeValue,
float64(obj.MaximumPressure),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryMemoryAddOperations,
prometheus.CounterValue,
float64(obj.MemoryAddOperations),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryMemoryRemoveOperations,
prometheus.CounterValue,
float64(obj.MemoryRemoveOperations),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryMinimumPressure,
prometheus.GaugeValue,
float64(obj.MinimumPressure),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryPhysicalMemory,
prometheus.GaugeValue,
float64(obj.PhysicalMemory),
obj.Name,
)
ch <- prometheus.MustNewConstMetric(
c.vmMemoryRemovedMemory,
prometheus.CounterValue,
float64(obj.RemovedMemory),
obj.Name,
)
}
return nil
}