github.com/netdata/go.d.plugin@v0.58.1/modules/windows/collect_hyperv.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package windows
     4  
     5  import (
     6  	"strings"
     7  
     8  	"github.com/netdata/go.d.plugin/pkg/prometheus"
     9  )
    10  
    11  const (
    12  	metricHypervHealthCritical = "windows_hyperv_health_critical"
    13  	metricHypervHealthOK       = "windows_hyperv_health_ok"
    14  
    15  	metricHypervHypervisorLogicalProcessors = "windows_hyperv_hypervisor_logical_processors"
    16  	metricHypervHypervisorVirtualProcessors = "windows_hyperv_hypervisor_virtual_processors"
    17  
    18  	metricHypervHostCPUGuestRunTime            = "windows_hyperv_host_cpu_guest_run_time"
    19  	metricHypervHostCPUHypervisorRunTime       = "windows_hyperv_host_cpu_hypervisor_run_time"
    20  	metricHypervHostCPURemoteRunTime           = "windows_hyperv_host_cpu_remote_run_time"
    21  	metricHypervHostCPUTotalRunTime            = "windows_hyperv_host_cpu_total_run_time"
    22  	metricHypervHostLPGuestRunTimePercent      = "windows_hyperv_host_lp_guest_run_time_percent"
    23  	metricHypervHostLPHypervisorRunTimePercent = "windows_hyperv_host_lp_hypervisor_run_time_percent"
    24  	metricHypervHostLPTotalRunTimePercent      = "windows_hyperv_host_lp_total_run_time_percent"
    25  
    26  	metricHypervRootPartition4KGPAPages                    = "windows_hyperv_root_partition_4K_gpa_pages"
    27  	metricHypervRootPartition2MGPAPages                    = "windows_hyperv_root_partition_2M_gpa_pages"
    28  	metricHypervRootPartition1GGPAPages                    = "windows_hyperv_root_partition_1G_gpa_pages"
    29  	metricHypervRootPartition4KDevicePages                 = "windows_hyperv_root_partition_4K_device_pages"
    30  	metricHypervRootPartition2MDevicePages                 = "windows_hyperv_root_partition_2M_device_pages"
    31  	metricHypervRootPartition1GDevicePages                 = "windows_hyperv_root_partition_1G_device_pages"
    32  	metricHypervRootPartitionGPASpaceModifications         = "windows_hyperv_root_partition_gpa_space_modifications"
    33  	metricHypervRootPartitionAttachedDevices               = "windows_hyperv_root_partition_attached_devices"
    34  	metricHypervRootPartitionDepositedPages                = "windows_hyperv_root_partition_deposited_pages"
    35  	metricHypervRootPartitionPhysicalPagesAllocated        = "windows_hyperv_root_partition_physical_pages_allocated" // SkippedTimerTicks
    36  	metricHypervRootPartitionDeviceDMAErrors               = "windows_hyperv_root_partition_device_dma_errors"
    37  	metricHypervRootPartitionDeviceInterruptErrors         = "windows_hyperv_root_partition_device_interrupt_errors"
    38  	metricHypervRootPartitionDeviceInterruptThrottleEvents = "windows_hyperv_root_partition_device_interrupt_throttle_events"
    39  	metricHypervRootPartitionIOTLBFlush                    = "windows_hyperv_root_partition_io_tlb_flush"
    40  	metricHypervRootPartitionAddressSpace                  = "windows_hyperv_root_partition_address_spaces"
    41  	metricHypervRootPartitionVirtualTLBPages               = "windows_hyperv_root_partition_virtual_tlb_pages"
    42  	metricHypervRootPartitionVirtualTLBFlushEntries        = "windows_hyperv_root_partition_virtual_tlb_flush_entires"
    43  
    44  	metricsHypervVMCPUGuestRunTime      = "windows_hyperv_vm_cpu_guest_run_time"
    45  	metricsHypervVMCPUHypervisorRunTime = "windows_hyperv_vm_cpu_hypervisor_run_time"
    46  	metricsHypervVMCPURemoteRunTime     = "windows_hyperv_vm_cpu_remote_run_time"
    47  	metricsHypervVMCPUTotalRunTime      = "windows_hyperv_vm_cpu_total_run_time"
    48  
    49  	metricHypervVMMemoryPhysical             = "windows_hyperv_vm_memory_physical"
    50  	metricHypervVMMemoryPhysicalGuestVisible = "windows_hyperv_vm_memory_physical_guest_visible"
    51  	metricHypervVMMemoryPressureCurrent      = "windows_hyperv_vm_memory_pressure_current"
    52  	metricHyperVVIDPhysicalPagesAllocated    = "windows_hyperv_vid_physical_pages_allocated"
    53  	metricHyperVVIDRemotePhysicalPages       = "windows_hyperv_vid_remote_physical_pages"
    54  
    55  	metricHypervVMDeviceBytesRead         = "windows_hyperv_vm_device_bytes_read"
    56  	metricHypervVMDeviceBytesWritten      = "windows_hyperv_vm_device_bytes_written"
    57  	metricHypervVMDeviceOperationsRead    = "windows_hyperv_vm_device_operations_read"
    58  	metricHypervVMDeviceOperationsWritten = "windows_hyperv_vm_device_operations_written"
    59  	metricHypervVMDeviceErrorCount        = "windows_hyperv_vm_device_error_count"
    60  
    61  	metricHypervVMInterfaceBytesReceived          = "windows_hyperv_vm_interface_bytes_received"
    62  	metricHypervVMInterfaceBytesSent              = "windows_hyperv_vm_interface_bytes_sent"
    63  	metricHypervVMInterfacePacketsIncomingDropped = "windows_hyperv_vm_interface_packets_incoming_dropped"
    64  	metricHypervVMInterfacePacketsOutgoingDropped = "windows_hyperv_vm_interface_packets_outgoing_dropped"
    65  	metricHypervVMInterfacePacketsReceived        = "windows_hyperv_vm_interface_packets_received"
    66  	metricHypervVMInterfacePacketsSent            = "windows_hyperv_vm_interface_packets_sent"
    67  
    68  	metricHypervVSwitchBroadcastPacketsReceivedTotal         = "windows_hyperv_vswitch_broadcast_packets_received_total"
    69  	metricHypervVSwitchBroadcastPacketsSentTotal             = "windows_hyperv_vswitch_broadcast_packets_sent_total"
    70  	metricHypervVSwitchBytesReceivedTotal                    = "windows_hyperv_vswitch_bytes_received_total"
    71  	metricHypervVSwitchBytesSentTotal                        = "windows_hyperv_vswitch_bytes_sent_total"
    72  	metricHypervVSwitchPacketsReceivedTotal                  = "windows_hyperv_vswitch_packets_received_total"
    73  	metricHypervVSwitchPacketsSentTotal                      = "windows_hyperv_vswitch_packets_sent_total"
    74  	metricHypervVSwitchDirectedPacketsReceivedTotal          = "windows_hyperv_vswitch_directed_packets_received_total"
    75  	metricHypervVSwitchDirectedPacketsSendTotal              = "windows_hyperv_vswitch_directed_packets_send_total"
    76  	metricHypervVSwitchDroppedPacketsIncomingTotal           = "windows_hyperv_vswitch_dropped_packets_incoming_total"
    77  	metricHypervVSwitchDroppedPacketsOutcomingTotal          = "windows_hyperv_vswitch_dropped_packets_outcoming_total"
    78  	metricHypervVSwitchExtensionDroppedAttacksIncomingTotal  = "windows_hyperv_vswitch_extensions_dropped_packets_incoming_total"
    79  	metricHypervVSwitchExtensionDroppedPacketsOutcomingTotal = "windows_hyperv_vswitch_extensions_dropped_packets_outcoming_total"
    80  	metricHypervVSwitchLearnedMACAddressTotal                = "windows_hyperv_vswitch_learned_mac_addresses_total"
    81  	metricHypervVSwitchMulticastPacketsReceivedTotal         = "windows_hyperv_vswitch_multicast_packets_received_total"
    82  	metricHypervVSwitchMulticastPacketsSentTotal             = "windows_hyperv_vswitch_multicast_packets_sent_total"
    83  	metricHypervVSwitchNumberOfSendChannelMovesTotal         = "windows_hyperv_vswitch_number_of_send_channel_moves_total"
    84  	metricHypervVSwitchNumberOfVMQMovesTotal                 = "windows_hyperv_vswitch_number_of_vmq_moves_total"
    85  	metricHypervVSwitchPacketsFloodedTotal                   = "windows_hyperv_vswitch_packets_flooded_total"
    86  	metricHypervVSwitchPurgedMACAddresses                    = "windows_hyperv_vswitch_purged_mac_addresses_total"
    87  )
    88  
    89  func (w *Windows) collectHyperv(mx map[string]int64, pms prometheus.Series) {
    90  	if !w.cache.collection[collectorHyperv] {
    91  		w.cache.collection[collectorHyperv] = true
    92  		w.addHypervCharts()
    93  	}
    94  
    95  	for _, v := range []string{
    96  		metricHypervHealthOK,
    97  		metricHypervHealthCritical,
    98  		metricHypervRootPartition4KGPAPages,
    99  		metricHypervRootPartition2MGPAPages,
   100  		metricHypervRootPartition1GGPAPages,
   101  		metricHypervRootPartition4KDevicePages,
   102  		metricHypervRootPartition2MDevicePages,
   103  		metricHypervRootPartition1GDevicePages,
   104  		metricHypervRootPartitionGPASpaceModifications,
   105  		metricHypervRootPartitionAddressSpace,
   106  		metricHypervRootPartitionAttachedDevices,
   107  		metricHypervRootPartitionDepositedPages,
   108  		metricHypervRootPartitionPhysicalPagesAllocated,
   109  		metricHypervRootPartitionDeviceDMAErrors,
   110  		metricHypervRootPartitionDeviceInterruptErrors,
   111  		metricHypervRootPartitionDeviceInterruptThrottleEvents,
   112  		metricHypervRootPartitionIOTLBFlush,
   113  		metricHypervRootPartitionVirtualTLBPages,
   114  		metricHypervRootPartitionVirtualTLBFlushEntries,
   115  	} {
   116  		for _, pm := range pms.FindByName(v) {
   117  			name := strings.TrimPrefix(pm.Name(), "windows_")
   118  			mx[name] = int64(pm.Value)
   119  		}
   120  	}
   121  
   122  	w.collectHypervVM(mx, pms)
   123  	w.collectHypervVMDevices(mx, pms)
   124  	w.collectHypervVMInterface(mx, pms)
   125  	w.collectHypervVSwitch(mx, pms)
   126  }
   127  
   128  func (w *Windows) collectHypervVM(mx map[string]int64, pms prometheus.Series) {
   129  	seen := make(map[string]bool)
   130  	px := "hyperv_vm_"
   131  
   132  	for _, v := range []string{
   133  		metricHypervVMMemoryPhysical,
   134  		metricHypervVMMemoryPhysicalGuestVisible,
   135  		metricHypervVMMemoryPressureCurrent,
   136  		metricsHypervVMCPUGuestRunTime,
   137  		metricsHypervVMCPUHypervisorRunTime,
   138  		metricsHypervVMCPURemoteRunTime,
   139  	} {
   140  		for _, pm := range pms.FindByName(v) {
   141  			if vm := pm.Labels.Get("vm"); vm != "" {
   142  				name := strings.TrimPrefix(pm.Name(), "windows_hyperv_vm")
   143  				seen[vm] = true
   144  				mx[px+hypervCleanName(vm)+name] += int64(pm.Value)
   145  			}
   146  		}
   147  	}
   148  
   149  	px = "hyperv_vid_"
   150  	for _, v := range []string{
   151  		metricHyperVVIDPhysicalPagesAllocated,
   152  		metricHyperVVIDRemotePhysicalPages,
   153  	} {
   154  		for _, pm := range pms.FindByName(v) {
   155  			if vm := pm.Labels.Get("vm"); vm != "" {
   156  				name := strings.TrimPrefix(pm.Name(), "windows_hyperv_vid")
   157  				seen[vm] = true
   158  				mx[px+hypervCleanName(vm)+name] = int64(pm.Value)
   159  			}
   160  		}
   161  	}
   162  
   163  	for v := range seen {
   164  		if !w.cache.hypervVMMem[v] {
   165  			w.cache.hypervVMMem[v] = true
   166  			w.addHypervVMCharts(v)
   167  		}
   168  	}
   169  	for v := range w.cache.hypervVMMem {
   170  		if !seen[v] {
   171  			delete(w.cache.hypervVMMem, v)
   172  			w.removeHypervVMCharts(v)
   173  		}
   174  	}
   175  }
   176  
   177  func (w *Windows) collectHypervVMDevices(mx map[string]int64, pms prometheus.Series) {
   178  	seen := make(map[string]bool)
   179  	px := "hyperv_vm_device_"
   180  
   181  	for _, v := range []string{
   182  		metricHypervVMDeviceBytesRead,
   183  		metricHypervVMDeviceBytesWritten,
   184  		metricHypervVMDeviceOperationsRead,
   185  		metricHypervVMDeviceOperationsWritten,
   186  		metricHypervVMDeviceErrorCount,
   187  	} {
   188  		for _, pm := range pms.FindByName(v) {
   189  			if device := pm.Labels.Get("vm_device"); device != "" {
   190  				name := strings.TrimPrefix(pm.Name(), "windows_hyperv_vm_device")
   191  				seen[device] = true
   192  				mx[px+hypervCleanName(device)+name] = int64(pm.Value)
   193  			}
   194  		}
   195  	}
   196  
   197  	for v := range seen {
   198  		if !w.cache.hypervVMDevices[v] {
   199  			w.cache.hypervVMDevices[v] = true
   200  			w.addHypervVMDeviceCharts(v)
   201  		}
   202  	}
   203  	for v := range w.cache.hypervVMDevices {
   204  		if !seen[v] {
   205  			delete(w.cache.hypervVMDevices, v)
   206  			w.removeHypervVMDeviceCharts(v)
   207  		}
   208  	}
   209  }
   210  
   211  func (w *Windows) collectHypervVMInterface(mx map[string]int64, pms prometheus.Series) {
   212  	seen := make(map[string]bool)
   213  	px := "hyperv_vm_interface_"
   214  
   215  	for _, v := range []string{
   216  		metricHypervVMInterfaceBytesReceived,
   217  		metricHypervVMInterfaceBytesSent,
   218  		metricHypervVMInterfacePacketsIncomingDropped,
   219  		metricHypervVMInterfacePacketsOutgoingDropped,
   220  		metricHypervVMInterfacePacketsReceived,
   221  		metricHypervVMInterfacePacketsSent,
   222  	} {
   223  		for _, pm := range pms.FindByName(v) {
   224  			if iface := pm.Labels.Get("vm_interface"); iface != "" {
   225  				name := strings.TrimPrefix(pm.Name(), "windows_hyperv_vm_interface")
   226  				seen[iface] = true
   227  				mx[px+hypervCleanName(iface)+name] = int64(pm.Value)
   228  			}
   229  		}
   230  	}
   231  
   232  	for v := range seen {
   233  		if !w.cache.hypervVMInterfaces[v] {
   234  			w.cache.hypervVMInterfaces[v] = true
   235  			w.addHypervVMInterfaceCharts(v)
   236  		}
   237  	}
   238  	for v := range w.cache.hypervVMInterfaces {
   239  		if !seen[v] {
   240  			delete(w.cache.hypervVMInterfaces, v)
   241  			w.removeHypervVMInterfaceCharts(v)
   242  		}
   243  	}
   244  }
   245  
   246  func (w *Windows) collectHypervVSwitch(mx map[string]int64, pms prometheus.Series) {
   247  	seen := make(map[string]bool)
   248  	px := "hyperv_vswitch_"
   249  
   250  	for _, v := range []string{
   251  		metricHypervVSwitchBytesReceivedTotal,
   252  		metricHypervVSwitchBytesSentTotal,
   253  		metricHypervVSwitchPacketsReceivedTotal,
   254  		metricHypervVSwitchPacketsSentTotal,
   255  		metricHypervVSwitchDirectedPacketsReceivedTotal,
   256  		metricHypervVSwitchDirectedPacketsSendTotal,
   257  		metricHypervVSwitchBroadcastPacketsReceivedTotal,
   258  		metricHypervVSwitchBroadcastPacketsSentTotal,
   259  		metricHypervVSwitchMulticastPacketsReceivedTotal,
   260  		metricHypervVSwitchMulticastPacketsSentTotal,
   261  		metricHypervVSwitchDroppedPacketsIncomingTotal,
   262  		metricHypervVSwitchDroppedPacketsOutcomingTotal,
   263  		metricHypervVSwitchExtensionDroppedAttacksIncomingTotal,
   264  		metricHypervVSwitchExtensionDroppedPacketsOutcomingTotal,
   265  		metricHypervVSwitchPacketsFloodedTotal,
   266  		metricHypervVSwitchLearnedMACAddressTotal,
   267  		metricHypervVSwitchPurgedMACAddresses,
   268  		metricHypervVSwitchNumberOfSendChannelMovesTotal,
   269  		metricHypervVSwitchNumberOfVMQMovesTotal,
   270  	} {
   271  		for _, pm := range pms.FindByName(v) {
   272  			if vswitch := pm.Labels.Get("vswitch"); vswitch != "" {
   273  				name := strings.TrimPrefix(pm.Name(), "windows_hyperv_vswitch")
   274  				seen[vswitch] = true
   275  				mx[px+hypervCleanName(vswitch)+name] = int64(pm.Value)
   276  			}
   277  		}
   278  	}
   279  
   280  	for v := range seen {
   281  		if !w.cache.hypervVswitch[v] {
   282  			w.cache.hypervVswitch[v] = true
   283  			w.addHypervVSwitchCharts(v)
   284  		}
   285  	}
   286  	for v := range w.cache.hypervVswitch {
   287  		if !seen[v] {
   288  			delete(w.cache.hypervVswitch, v)
   289  			w.removeHypervVSwitchCharts(v)
   290  		}
   291  	}
   292  }
   293  
   294  var hypervNameReplacer = strings.NewReplacer(" ", "_", "?", "_", ":", "_", ".", "_")
   295  
   296  func hypervCleanName(name string) string {
   297  	name = hypervNameReplacer.Replace(name)
   298  	return strings.ToLower(name)
   299  }