diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml
index 2f0e1086..db115a87 100644
--- a/.github/workflows/spelling.yml
+++ b/.github/workflows/spelling.yml
@@ -23,4 +23,4 @@ jobs:
check_filenames: true
# When using this Action in other repos, the --skip option below can be removed
skip: ./.git,go.mod,go.sum
- ignore_words_list: calle
+ ignore_words_list: calle,Entires
diff --git a/docs/collector.hyperv.md b/docs/collector.hyperv.md
index 0b799e6b..23c8e204 100644
--- a/docs/collector.hyperv.md
+++ b/docs/collector.hyperv.md
@@ -2,110 +2,262 @@
The hyperv collector exposes metrics about the Hyper-V hypervisor
-|||
--|-
-Metric name prefix | `hyperv`
-Classes | `Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary`
`Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition`
`Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition`
`Win32_PerfRawData_HvStats_HyperVHypervisor`
`Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor`
`Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor`
`Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor`
`Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch`
`Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter`
`Win32_PerfRawData_Counters_HyperVVirtualStorageDevice`
`Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter`
-Enabled by default? | No
+| | |
+|---------------------|----------------------|
+| Metric name prefix | `hyperv` |
+| Source | Performance counters |
+| Enabled by default? | No |
## Flags
-None
+### `--collectors.hyperv.enabled`
+Comma-separated list of collectors to use, for example:
+`--collectors.hyperv.enabled=dynamic_memory_balancer,dynamic_memory_vm,hypervisor_logical_processor,hypervisor_root_partition,hypervisor_root_virtual_processor,hypervisor_virtual_processor,legacy_network_adapter,virtual_machine_health_summary,virtual_machine_vid_partition,virtual_network_adapter,virtual_storage_device,virtual_switch`.
+Matching is case-sensitive.
## Metrics
-Name | Description | Type | Labels
------|-------------|------|-------
-`windows_hyperv_health_critical` | _Not yet documented_ | counter | None
-`windows_hyperv_health_ok` | _Not yet documented_ | counter | None
-`windows_hyperv_vid_physical_pages_allocated` | _Not yet documented_ | counter | `vm`
-`windows_hyperv_vid_preferred_numa_node_index` | _Not yet documented_ | counter | `vm`
-`windows_hyperv_vid_remote_physical_pages` | _Not yet documented_ | counter | `vm`
-`windows_hyperv_root_partition_address_spaces` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_attached_devices` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_deposited_pages` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_device_dma_errors` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_device_interrupt_errors` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_device_interrupt_mappings` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_device_interrupt_throttle_events` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_preferred_numa_node_index` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_gpa_space_modifications` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_io_tlb_flush_cost` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_io_tlb_flush` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_recommended_virtual_tlb_size` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_physical_pages_allocated` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_1G_device_pages` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_1G_gpa_pages` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_2M_device_pages` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_2M_gpa_pages` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_4K_device_pages` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_4K_gpa_pages` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_virtual_tlb_flush_entires` | _Not yet documented_ | counter | None
-`windows_hyperv_root_partition_virtual_tlb_pages` | _Not yet documented_ | counter | None
-`windows_hyperv_hypervisor_virtual_processors` | _Not yet documented_ | counter | None
-`windows_hyperv_hypervisor_logical_processors` | _Not yet documented_ | counter | None
-`windows_hyperv_host_lp_guest_run_time_percent` | _Not yet documented_ | counter | `core`
-`windows_hyperv_host_lp_hypervisor_run_time_percent` | _Not yet documented_ | counter | `core`
-`windows_hyperv_host_lp_total_run_time_percent` | _Not yet documented_ | counter | `core`
-`windows_hyperv_host_cpu_guest_run_time` | _Not yet documented_ | counter | `core`
-`windows_hyperv_host_cpu_hypervisor_run_time` | _Not yet documented_ | counter | `core`
-`windows_hyperv_host_cpu_remote_run_time` | _Not yet documented_ | counter | `core`
-`windows_hyperv_host_cpu_total_run_time` | _Not yet documented_ | counter | `core`
-`windows_hyperv_host_cpu_wait_time_per_dispatch_total` | _Not yet documented_ | counter | `core`
-`windows_hyperv_vm_cpu_guest_run_time` | _Not yet documented_ | counter | `vm`, `core`
-`windows_hyperv_vm_cpu_hypervisor_run_time` | _Not yet documented_ | counter | `vm`, `core`
-`windows_hyperv_vm_cpu_remote_run_time` | _Not yet documented_ | counter | `vm`, `core`
-`windows_hyperv_vm_cpu_wait_time_per_dispatch_total` | _Not yet documented_ | counter | `vm`, `core`
-`windows_hyperv_vm_memory_added_total` | _Not yet documented_ | counter | `vm`
-`windows_hyperv_vm_memory_pressure_average` | _Not yet documented_ | gauge | `vm`
-`windows_hyperv_vm_memory_pressure_current` | _Not yet documented_ | counter | `vm`
-`windows_hyperv_vm_memory_physical_guest_visible` | _Not yet documented_ | gauge | `vm`
-`windows_hyperv_vm_memory_pressure_maximum` | _Not yet documented_ | gauge | `vm`
-`windows_hyperv_vm_memory_add_operations_total` | _Not yet documented_ | counter | `vm`
-`windows_hyperv_vm_memory_remove_operations_total` | _Not yet documented_ | counter | `vm`
-`windows_hyperv_vm_memory_pressure_minumim` | _Not yet documented_ | gauge | `vm`
-`windows_hyperv_vm_memory_physical` | _Not yet documented_ | gauge | `vm`
-`windows_hyperv_vm_memory_removed_total` | _Not yet documented_ | counter | `vm`
-`windows_hyperv_vm_cpu_total_run_time` | _Not yet documented_ | counter | `vm`, `core`
-`windows_hyperv_vswitch_broadcast_packets_received_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_broadcast_packets_sent_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_bytes_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_bytes_received_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_bytes_sent_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_directed_packets_received_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_directed_packets_send_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_dropped_packets_incoming_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_dropped_packets_outcoming_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_extensions_dropped_packets_incoming_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_extensions_dropped_packets_outcoming_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_learned_mac_addresses_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_multicast_packets_received_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_multicast_packets_sent_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_number_of_send_channel_moves_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_number_of_vmq_moves_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_packets_flooded_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_packets_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_packets_received_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_packets_sent_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_vswitch_purged_mac_addresses_total` | _Not yet documented_ | counter | `vswitch`
-`windows_hyperv_ethernet_bytes_dropped` | _Not yet documented_ | counter | `adapter`
-`windows_hyperv_ethernet_bytes_received` | _Not yet documented_ | counter | `adapter`
-`windows_hyperv_ethernet_bytes_sent` | _Not yet documented_ | counter | `adapter`
-`windows_hyperv_ethernet_frames_dropped` | _Not yet documented_ | counter | `adapter`
-`windows_hyperv_ethernet_frames_received` | _Not yet documented_ | counter | `adapter`
-`windows_hyperv_ethernet_frames_sent` | _Not yet documented_ | counter | `adapter`
-`windows_hyperv_vm_device_error_count` | _Not yet documented_ | counter | `vm_device`
-`windows_hyperv_vm_device_queue_length` | _Not yet documented_ | counter | `vm_device`
-`windows_hyperv_vm_device_bytes_read` | _Not yet documented_ | counter | `vm_device`
-`windows_hyperv_vm_device_operations_read` | _Not yet documented_ | counter | `vm_device`
-`windows_hyperv_vm_device_bytes_written` | _Not yet documented_ | counter | `vm_device`
-`windows_hyperv_vm_device_operations_written` | _Not yet documented_ | counter | `vm_device`
-`windows_hyperv_vm_interface_bytes_received` | _Not yet documented_ | counter | `vm_interface`
-`windows_hyperv_vm_interface_bytes_sent` | _Not yet documented_ | counter | `vm_interface`
-`windows_hyperv_vm_interface_packets_incoming_dropped` | _Not yet documented_ | counter | `vm_interface`
-`windows_hyperv_vm_interface_packets_outgoing_dropped` | _Not yet documented_ | counter | `vm_interface`
-`windows_hyperv_vm_interface_packets_received` | _Not yet documented_ | counter | `vm_interface`
-`windows_hyperv_vm_interface_packets_sent` | _Not yet documented_ | counter | `vm_interface`
+### Hyper-V Datastore
+### Hyper-V Datastore Metrics Documentation
+
+This documentation outlines the available metrics for monitoring Hyper-V Datastore performance and resource usage using Prometheus. All metrics are prefixed with `windows_hyperv_datastore`.
+
+| Metric Name | Description | Type | Labels |
+|------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------|-----------|
+| `windows_hyperv_datastore_fragmentation_ratio` | Represents the fragmentation ratio of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_sector_size_bytes` | Represents the sector size of the DataStore in bytes. | gauge | datastore |
+| `windows_hyperv_datastore_data_alignment_bytes` | Represents the data alignment of the DataStore in bytes. | gauge | datastore |
+| `windows_hyperv_datastore_current_replay_log_size_bytes` | Represents the current replay log size of the DataStore in bytes. | gauge | datastore |
+| `windows_hyperv_datastore_available_entries` | Represents the number of available entries inside object tables. | gauge | datastore |
+| `windows_hyperv_datastore_empty_entries` | Represents the number of empty entries inside object tables. | gauge | datastore |
+| `windows_hyperv_datastore_free_bytes` | Represents the number of free bytes inside key tables. | gauge | datastore |
+| `windows_hyperv_datastore_data_end_bytes` | Represents the data end of the DataStore in bytes. | gauge | datastore |
+| `windows_hyperv_datastore_file_objects` | Represents the number of file objects in the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_object_tables` | Represents the number of object tables in the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_key_tables` | Represents the number of key tables in the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_file_data_size_bytes` | Represents the file data size in bytes of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_table_data_size_bytes` | Represents the table data size in bytes of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_names_size_bytes` | Represents the names size in bytes of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_number_of_keys` | Represents the number of keys in the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_reconnect_latency_microseconds` | Represents the reconnect latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_disconnect_count` | Represents the disconnect count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_write_to_file_byte_latency_microseconds` | Represents the write-to-file byte latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_write_to_file_byte_count` | Represents the write-to-file byte count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_write_to_file_count` | Represents the write-to-file count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_read_from_file_byte_latency_microseconds` | Represents the read-from-file byte latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_read_from_file_byte_count` | Represents the read-from-file byte count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_read_from_file_count` | Represents the read-from-file count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_write_to_storage_byte_latency_microseconds` | Represents the write-to-storage byte latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_write_to_storage_byte_count` | Represents the write-to-storage byte count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_write_to_storage_count` | Represents the write-to-storage count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_read_from_storage_byte_latency_microseconds` | Represents the read-from-storage byte latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_read_from_storage_byte_count` | Represents the read-from-storage byte count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_read_from_storage_count` | Represents the read-from-storage count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_commit_byte_latency_microseconds` | Represents the commit byte latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_commit_byte_count` | Represents the commit byte count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_commit_count` | Represents the commit count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_cache_update_operation_latency_microseconds` | Represents the cache update operation latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_cache_update_operation_count` | Represents the cache update operation count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_commit_operation_latency_microseconds` | Represents the commit operation latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_commit_operation_count` | Represents the commit operation count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_compact_operation_latency_microseconds` | Represents the compact operation latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_compact_operation_count` | Represents the compact operation count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_load_file_operation_latency_microseconds` | Represents the load file operation latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_load_file_operation_count` | Represents the load file operation count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_remove_operation_latency_microseconds` | Represents the remove operation latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_remove_operation_count` | Represents the remove operation count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_query_size_operation_latency_microseconds` | Represents the query size operation latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_query_size_operation_count` | Represents the query size operation count of the DataStore. | counter | datastore |
+| `windows_hyperv_datastore_set_operation_latency_microseconds` | Represents the set operation latency in microseconds of the DataStore. | gauge | datastore |
+| `windows_hyperv_datastore_set_operation_count` | Represents the set operation count of the DataStore. | counter | datastore |
+
+### Hyper-V Dynamic Memory Balancer
+
+Some metrics explained: https://learn.microsoft.com/en-us/archive/blogs/chrisavis/monitoring-dynamic-memory-in-windows-server-hyper-v-2012
+
+| Name | Description | Type | Labels |
+|-------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|-------|------------|
+| `windows_hyperv_dynamic_memory_balancer_available_memory_bytes` | Represents the amount of memory left on the node. | gauge | `balancer` |
+| `windows_hyperv_dynamic_memory_balancer_available_memory_for_balancing_bytes` | Represents the available memory for balancing purposes. | gauge | `balancer` |
+| `windows_hyperv_dynamic_memory_balancer_average_pressure_ratio` | Represents the average system pressure on the balancer node among all balanced objects. | gauge | `balancer` |
+| `windows_hyperv_dynamic_memory_balancer_system_current_pressure_ratio` | Represents the current pressure in the system. | gauge | `balancer` |
+
+
+### Hyper-V Dynamic Memory VM
+
+| Name | Description | Type | Labels |
+|------------------------------------------------------------------------|-----------------------------------------------------------------------------------|---------|--------|
+| `windows_hyperv_dynamic_memory_vm_added_bytes_total` | Represents the cumulative amount of memory added to the VM. | counter | `vm` |
+| `windows_hyperv_dynamic_memory_vm_pressure_current_ratio` | Represents the current pressure in the VM. | gauge | `vm` |
+| `windows_hyperv_dynamic_memory_vm_guest_available_bytes` | Represents the current amount of available memory in the VM (reported by the VM). | gauge | `vm` |
+| `windows_hyperv_dynamic_memory_vm_guest_visible_physical_memory_bytes` | Represents the amount of memory visible in the VM | gauge | `vm` |
+| `windows_hyperv_dynamic_memory_vm_pressure_maximum_ratio` | Represents the maximum pressure band in the VM. | gauge | `vm` |
+| `windows_hyperv_dynamic_memory_vm_add_operations_total` | Represents the total number of add operations for the VM. | counter | `vm` |
+| `windows_hyperv_dynamic_memory_vm_remove_operations_total` | Represents the total number of remove operations for the VM. | counter | `vm` |
+| `windows_hyperv_dynamic_memory_vm_pressure_minimum_ratio` | Represents the minimum pressure band in the VM. | gauge | `vm` |
+| `windows_hyperv_dynamic_memory_vm_physical` | Represents the current amount of memory in the VM. | gauge | `vm` |
+| `windows_hyperv_dynamic_memory_vm_removed_bytes_total` | Represents the cumulative amount of memory removed from the VM. | counter | `vm` |
+
+### Hyper-V Hypervisor Logical Processor
+
+| Name | Description | Type | Labels |
+|----------------------------------------------------------------------|------------------------------------------------------------------------|---------|----------------|
+| `windows_hyperv_hypervisor_logical_processor_time_total` | Time that processor spent in different modes (hypervisor, guest, idle) | counter | `core`.`state` |
+| `windows_hyperv_hypervisor_logical_processor_context_switches_total` | The rate of virtual processor context switches on the processor. | counter | `core` |
+
+### Hyper-V Hypervisor Root Partition
+
+| Name | Description | Type | Labels |
+|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
+| `windows_hyperv_root_partition_address_spaces` | The number of address spaces in the virtual TLB of the partition | gauge | None |
+| `windows_hyperv_root_partition_attached_devices` | The number of devices attached to the partition | gauge | None |
+| `windows_hyperv_root_partition_deposited_pages` | The number of pages deposited into the partition | gauge | None |
+| `windows_hyperv_root_partition_device_dma_errors` | An indicator of illegal DMA requests generated by all devices assigned to the partition | gauge | None |
+| `windows_hyperv_root_partition_device_interrupt_errors` | An indicator of illegal interrupt requests generated by all devices assigned to the partition | gauge | None |
+| `windows_hyperv_root_partition_device_interrupt_mappings` | The number of device interrupt mappings used by the partition | gauge | None |
+| `windows_hyperv_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 | gauge | None |
+| `windows_hyperv_root_partition_preferred_numa_node_index` | The number of pages present in the GPA space of the partition (zero for root partition) | gauge | None |
+| `windows_hyperv_root_partition_gpa_space_modifications` | The rate of modifications to the GPA space of the partition | counter | None |
+| `windows_hyperv_root_partition_io_tlb_flush_cost` | The average time (in nanoseconds) spent processing an I/O TLB flush | gauge | None |
+| `windows_hyperv_root_partition_io_tlb_flush` | The rate of flushes of I/O TLBs of the partition | counter | None |
+| `windows_hyperv_root_partition_recommended_virtual_tlb_size` | The recommended number of pages to be deposited for the virtual TLB | gauge | None |
+| `windows_hyperv_root_partition_physical_pages_allocated` | The number of timer interrupts skipped for the partition | gauge | None |
+| `windows_hyperv_root_partition_1G_device_pages` | The number of 1G pages present in the device space of the partition | gauge | None |
+| `windows_hyperv_root_partition_1G_gpa_pages` | The number of 1G pages present in the GPA space of the partition | gauge | None |
+| `windows_hyperv_root_partition_2M_device_pages` | The number of 2M pages present in the device space of the partition | gauge | None |
+| `windows_hyperv_root_partition_2M_gpa_pages` | The number of 2M pages present in the GPA space of the partition | gauge | None |
+| `windows_hyperv_root_partition_4K_device_pages` | The number of 4K pages present in the device space of the partition | gauge | None |
+| `windows_hyperv_root_partition_4K_gpa_pages` | The number of 4K pages present in the GPA space of the partition | gauge | None |
+| `windows_hyperv_root_partition_virtual_tlb_flush_entries` | The rate of flushes of the entire virtual TLB | counter | None |
+| `windows_hyperv_root_partition_virtual_tlb_pages` | The number of pages used by the virtual TLB of the partition | gauge | None |
+
+
+### Hyper-V Hypervisor Root Virtual Processor
+
+| Name | Description | Type | Labels |
+|---------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|---------|----------------|
+| `windows_hyperv_hypervisor_root_virtual_processor_time_total` | Time that processor spent in different modes (hypervisor, guest_run, guest_idle, remote, total) | counter | `core`.`state` |
+| `windows_hyperv_hypervisor_root_virtual_cpu_wait_time_per_dispatch_total` | The average time (in nanoseconds) spent waiting for a virtual processor to be dispatched onto a logical processor | counter | `core` |
+
+
+### Hyper-V Legacy Network Adapter
+
+| Name | Description | Type | Labels |
+|---------------------------------------------------------------|-------------------------------------------------------------------------|---------|-----------|
+| `windows_hyperv_legacy_network_adapter_bytes_dropped_total` | Bytes Dropped is the number of bytes dropped on the network adapter | counter | `adapter` |
+| `windows_hyperv_legacy_network_adapter_bytes_received_total` | Bytes received is the number of bytes received on the network adapter | counter | `adapter` |
+| `windows_hyperv_legacy_network_adapter_bytes_sent_total` | Bytes sent is the number of bytes sent over the network adapter | counter | `adapter` |
+| `windows_hyperv_legacy_network_adapter_frames_dropped_total` | Frames Dropped is the number of frames dropped on the network adapter | counter | `adapter` |
+| `windows_hyperv_legacy_network_adapter_frames_received_total` | Frames received is the number of frames received on the network adapter | counter | `adapter` |
+| `windows_hyperv_legacy_network_adapter_frames_sent_total` | Frames sent is the number of frames sent over the network adapter | counter | `adapter` |
+
+
+### Hyper-V Hypervisor Virtual Processor
+
+| Name | Description | Type | Labels |
+|--------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|---------|--------------|
+| `windows_hyperv_hypervisor_virtual_processor_time_total` | Time that processor spent in different modes (hypervisor, guest_run, guest_idle, remote) | counter | `vm`, `core` |
+| `windows_hyperv_hypervisor_virtual_processor_total_run_time_total` | Time that processor spent | counter | `vm`, `core` |
+| `windows_hyperv_hypervisor_virtual_processor_cpu_wait_time_per_dispatch_total` | The average time (in nanoseconds) spent waiting for a virtual processor to be dispatched onto a logical processor. | counter | `vm`, `core` |
+
+### Hyper-V Virtual Network Adapter
+
+| Name | Description | Type | Labels |
+|-------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|---------|-----------|
+| `windows_hyperv_virtual_network_adapter_received_bytes_total` | Represents the total number of bytes received per second by the network adapter | counter | `adapter` |
+| `windows_hyperv_virtual_network_adapter_sent_bytes_total` | Represents the total number of bytes sent per second by the network adapter | counter | `adapter` |
+| `windows_hyperv_virtual_network_adapter_incoming_dropped_packets_total` | Represents the total number of dropped packets per second in the incoming direction of the network adapter | counter | `adapter` |
+| `windows_hyperv_virtual_network_adapter_outgoing_dropped_packets_total` | Represents the total number of dropped packets per second in the outgoing direction of the network adapter | counter | `adapter` |
+| `windows_hyperv_virtual_network_adapter_received_packets_total` | Represents the total number of packets received per second by the network adapter | counter | `adapter` |
+| `windows_hyperv_virtual_network_adapter_sent_packets_total` | Represents the total number of packets sent per second by the network adapter | counter | `adapter` |
+
+### Hyper-V Virtual Network Adapter Drop Reasons
+
+| Name | Description | Type | Labels |
+|-------------------------------------------------------|----------------------------------------------|---------|--------------------------------|
+| `windows_hyperv_virtual_network_adapter_drop_reasons` | Hyper-V Virtual Network Adapter Drop Reasons | counter | `adapter`,`direction`,`reason` |
+
+### Hyper-V Virtual SMB
+
+| Name | Description | Type | Labels |
+|-------------------------------------------------------|-----------------------------------------------------------------------------------|---------|------------|
+| `windows_hyperv_virtual_smb_direct_mapped_sections` | Represents the number of direct-mapped sections in the virtual SMB` | gauge | `instance` |
+| `windows_hyperv_virtual_smb_direct_mapped_pages` | Represents the number of direct-mapped pages in the virtual SMB` | gauge | `instance` |
+| `windows_hyperv_virtual_smb_write_bytes_rdma` | Represents the number of bytes written per second using RDMA in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_write_bytes` | Represents the number of bytes written per second in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_read_bytes_rdma` | Represents the number of bytes read per second using RDMA in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_read_bytes` | Represents the number of bytes read per second in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_flush_requests` | Represents the number of flush requests per second in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_write_requests_rdma` | Represents the number of write requests per second using RDMA in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_write_requests` | Represents the number of write requests per second in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_read_requests_rdma` | Represents the number of read requests per second using RDMA in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_read_requests` | Represents the number of read requests per second in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_current_pending_requests` | Represents the current number of pending requests in the virtual SMB` | gauge | `instance` |
+| `windows_hyperv_virtual_smb_current_open_file_count` | Represents the current number of open files in the virtual SMB` | gauge | `instance` |
+| `windows_hyperv_virtual_smb_tree_connect_count` | Represents the number of tree connects in the virtual SMB` | gauge | `instance` |
+| `windows_hyperv_virtual_smb_requests` | Represents the number of requests per second in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_sent_bytes` | Represents the number of bytes sent per second in the virtual SMB` | counter | `instance` |
+| `windows_hyperv_virtual_smb_received_bytes` | Represents the number of bytes received per second in the virtual SMB` | counter | `instance` |
+
+
+### Hyper-V Virtual Switch
+
+| Name | Description | Type | Labels |
+|---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|---------|-----------|
+| `windows_hyperv_vswitch_broadcast_packets_received_total` | Represents the total number of broadcast packets received per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_broadcast_packets_sent_total` | Represents the total number of broadcast packets sent per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_bytes_total` | Represents the total number of bytes per second traversing the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_bytes_received_total` | Represents the total number of bytes received per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_bytes_sent_total` | Represents the total number of bytes sent per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_directed_packets_received_total` | Represents the total number of directed packets received per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_directed_packets_send_total` | Represents the total number of directed packets sent per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_dropped_packets_incoming_total` | Represents the total number of packet dropped per second by the virtual switch in the incoming direction | counter | `vswitch` |
+| `windows_hyperv_vswitch_dropped_packets_outcoming_total` | Represents the total number of packet dropped per second by the virtual switch in the outgoing direction | counter | `vswitch` |
+| `windows_hyperv_vswitch_extensions_dropped_packets_incoming_total` | Represents the total number of packet dropped per second by the virtual switch extensions in the incoming direction | counter | `vswitch` |
+| `windows_hyperv_vswitch_extensions_dropped_packets_outcoming_total` | Represents the total number of packet dropped per second by the virtual switch extensions in the outgoing direction | counter | `vswitch` |
+| `windows_hyperv_vswitch_learned_mac_addresses_total` | Represents the total number of learned MAC addresses of the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_multicast_packets_received_total` | Represents the total number of multicast packets received per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_multicast_packets_sent_total` | Represents the total number of multicast packets sent per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_number_of_send_channel_moves_total` | Represents the total number of send channel moves per second on this virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_number_of_vmq_moves_total` | Represents the total number of VMQ moves per second on this virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_packets_flooded_total` | Represents the total number of packets flooded by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_packets_total` | Represents the total number of packets per second traversing the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_packets_received_total` | Represents the total number of packets received per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_packets_sent_total` | Represents the total number of packets send per second by the virtual switch | counter | `vswitch` |
+| `windows_hyperv_vswitch_purged_mac_addresses_total` | Represents the total number of purged MAC addresses of the virtual switch | counter | `vswitch` |
+
+### Hyper-V Virtual Storage Device
+
+| Name | Description | Type | Labels |
+|---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|---------|----------|
+| `windows_hyperv_virtual_storage_device_error_count_total` | Represents the total number of errors that have occurred on this virtual device. | counter | `device` |
+| `windows_hyperv_virtual_storage_device_queue_length` | Represents the average queue length on this virtual device. | gauge | `device` |
+| `windows_hyperv_virtual_storage_device_bytes_read` | Represents the total number of bytes that have been read on this virtual device. | counter | `device` |
+| `windows_hyperv_virtual_storage_device_operations_read_total` | Represents the total number of read operations that have occurred on this virtual device. | counter | `device` |
+| `windows_hyperv_virtual_storage_device_bytes_written` | Represents the total number of bytes that have been written on this virtual device. | counter | `device` |
+| `windows_hyperv_virtual_storage_device_operations_written_total` | Represents the total number of write operations that have occurred on this virtual device. | counter | `device` |
+| `windows_hyperv_virtual_storage_device_latency_seconds` | Represents the average IO transfer latency for this virtual device. | gauge | `device` |
+| `windows_hyperv_virtual_storage_device_throughput` | Represents the average number of 8KB IO transfers completed by this virtual device. | gauge | `device` |
+| `windows_hyperv_virtual_storage_device_normalized_throughput` | Represents the average number of IO transfers completed by this virtual device. | gauge | `device` |
+| `windows_hyperv_virtual_storage_device_lower_queue_length` | Represents the average queue length on the underlying storage subsystem for this device. | gauge | `device` |
+| `windows_hyperv_virtual_storage_device_lower_latency_seconds` | Represents the average IO transfer latency on the underlying storage subsystem for this virtual device. | gauge | `device` |
+| `windows_hyperv_virtual_storage_device_io_quota_replenishment_rate` | Represents the IO quota replenishment rate for this virtual device. | gauge | `device` |
+
+### Hyper-V VM Vid Partition
+
+| Name | Description | Type | Labels |
+|------------------------------------------------|-------------------------------------------------------------------------|-------|--------|
+| `windows_hyperv_vid_physical_pages_allocated` | The number of physical pages allocated | gauge | `vm` |
+| `windows_hyperv_vid_preferred_numa_node_index` | The preferred NUMA node index associated with this partition | gauge | `vm` |
+| `windows_hyperv_vid_remote_physical_pages` | The number of physical pages not allocated from the preferred NUMA node | gauge | `vm` |
+
+
+### Hyper-V Virtual Machine Health Summary
+
+| Name | Description | Type | Labels |
+|------------------------------------------------------|-------------------------------------------------------|-------|--------|
+| `windows_hyperv_virtual_machine_health_total_count` | Represents the number of virtual machines with health | gauge | None |
+
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_
@@ -113,19 +265,19 @@ _This collector does not yet have explained examples, we would appreciate your h
## Useful queries
Percent of physical CPU resources used per VM (on instance "localhost")
```
-(sum (rate(windows_hyperv_vm_cpu_hypervisor_run_time{instance="localhost"}[1m]))) / ignoring(vm) group_left max (windows_cs_logical_processors{instance="localhost"}) / 100000
+(sum (rate(windows_hyperv_hypervisor_virtual_processor_time_total{state="hypervisor",instance="localhost"}[1m]))) / ignoring(state,vm) group_left max (windows_cpu_logical_processor{instance="localhost"}) / 100000
```
Percent of physical CPU resources used by all VMs (on all monitored hosts)
```
-(sum by (instance)(rate(windows_hyperv_vm_cpu_total_run_time{}[1m]))) / max by (instance)(windows_cs_logical_processors{}) / 100000
+(sum by (instance)(rate(windows_hyperv_hypervisor_virtual_processor_total_run_time_total{}[1m]))) / max by (instance)(windows_cpu_logical_processor{}) / 100000
```
Percent of physical CPU resources by the hosts themselves (on all monitored hosts)
```
-(sum by (instance)(rate(windows_hyperv_host_cpu_total_run_time{}[1m]))) / sum by (instance)(windows_cs_logical_processors{}) / 100000
+(sum by (instance)(rate(windows_hyperv_hypervisor_root_virtual_processor_total_run_time_total{state="total"}[1m]))) / sum by (instance)(windows_cpu_logical_processor{}) / 100000
```
Percent of physical CPU resources by the hypervisor (on all monitored hosts)
```
-(sum by (instance)(rate(windows_hyperv_host_lp_total_run_time_percent{}[1m]))) / sum by (instance)(windows_hyperv_hypervisor_logical_processors{}) / 100000
+(sum by (instance)(rate(windows_hyperv_hypervisor_logical_processor_total_run_time_total{}[1m]))) / sum by (instance)(windows_cpu_logical_processor{}) / 100000
```
## Alerting examples
diff --git a/internal/collector/cpu/cpu.go b/internal/collector/cpu/cpu.go
index 1aa0ab4f..30e43bee 100644
--- a/internal/collector/cpu/cpu.go
+++ b/internal/collector/cpu/cpu.go
@@ -113,31 +113,6 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
nil,
nil,
)
-
- c.cStateSecondsTotal = prometheus.NewDesc(
- prometheus.BuildFQName(types.Namespace, Name, "cstate_seconds_total"),
- "Time spent in low-power idle state",
- []string{"core", "state"},
- nil,
- )
- c.timeTotal = prometheus.NewDesc(
- prometheus.BuildFQName(types.Namespace, Name, "time_total"),
- "Time that processor spent in different modes (dpc, idle, interrupt, privileged, user)",
- []string{"core", "mode"},
- nil,
- )
- c.interruptsTotal = prometheus.NewDesc(
- prometheus.BuildFQName(types.Namespace, Name, "interrupts_total"),
- "Total number of received and serviced hardware interrupts",
- []string{"core"},
- nil,
- )
- c.dpcsTotal = prometheus.NewDesc(
- prometheus.BuildFQName(types.Namespace, Name, "dpcs_total"),
- "Total number of received and serviced deferred procedure calls (DPCs)",
- []string{"core"},
- nil,
- )
c.cStateSecondsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "cstate_seconds_total"),
"Time spent in low-power idle state",
diff --git a/internal/collector/cs/cs.go b/internal/collector/cs/cs.go
index c4e98350..a77c814f 100644
--- a/internal/collector/cs/cs.go
+++ b/internal/collector/cs/cs.go
@@ -23,10 +23,10 @@ type Collector struct {
config Config
// physicalMemoryBytes
- // Deprecated: Use windows_cpu_logical_processor instead
+ // Deprecated: Use windows_physical_memory_total_bytes instead
physicalMemoryBytes *prometheus.Desc
// logicalProcessors
- // Deprecated: Use windows_physical_memory_total_bytes instead
+ // Deprecated: Use windows_cpu_logical_processor instead
logicalProcessors *prometheus.Desc
// hostname
// Deprecated: Use windows_os_hostname instead
diff --git a/internal/collector/hyperv/hyperv.go b/internal/collector/hyperv/hyperv.go
index a2e6b7da..11ebadbc 100644
--- a/internal/collector/hyperv/hyperv.go
+++ b/internal/collector/hyperv/hyperv.go
@@ -6,138 +6,81 @@ import (
"errors"
"fmt"
"log/slog"
+ "sort"
"strings"
+ "sync"
"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"
+const (
+ Name = "hyperv"
-type Config struct{}
+ subCollectorDataStore = "datastore"
+ subCollectorDynamicMemoryBalancer = "dynamic_memory_balancer"
+ subCollectorDynamicMemoryVM = "dynamic_memory_vm"
+ subCollectorHypervisorLogicalProcessor = "hypervisor_logical_processor"
+ subCollectorHypervisorRootPartition = "hypervisor_root_partition"
+ subCollectorHypervisorRootVirtualProcessor = "hypervisor_root_virtual_processor"
+ subCollectorHypervisorVirtualProcessor = "hypervisor_virtual_processor"
+ subCollectorLegacyNetworkAdapter = "legacy_network_adapter"
+ subCollectorVirtualMachineHealthSummary = "virtual_machine_health_summary"
+ subCollectorVirtualMachineVidPartition = "virtual_machine_vid_partition"
+ subCollectorVirtualNetworkAdapter = "virtual_network_adapter"
+ subCollectorVirtualNetworkAdapterDropReasons = "virtual_network_adapter_drop_reasons"
+ subCollectorVirtualSMB = "virtual_smb"
+ subCollectorVirtualStorageDevice = "virtual_storage_device"
+ subCollectorVirtualSwitch = "virtual_switch"
+)
-var ConfigDefaults = Config{}
+type Config struct {
+ CollectorsEnabled []string `yaml:"collectors_enabled"`
+}
+
+var ConfigDefaults = Config{
+ CollectorsEnabled: []string{
+ subCollectorDataStore,
+ subCollectorDynamicMemoryBalancer,
+ subCollectorDynamicMemoryVM,
+ subCollectorHypervisorLogicalProcessor,
+ subCollectorHypervisorRootPartition,
+ subCollectorHypervisorRootVirtualProcessor,
+ subCollectorHypervisorVirtualProcessor,
+ subCollectorLegacyNetworkAdapter,
+ subCollectorVirtualMachineHealthSummary,
+ subCollectorVirtualMachineVidPartition,
+ subCollectorVirtualNetworkAdapter,
+ subCollectorVirtualNetworkAdapterDropReasons,
+ subCollectorVirtualSMB,
+ subCollectorVirtualStorageDevice,
+ subCollectorVirtualSwitch,
+ },
+}
// Collector is a Prometheus Collector for hyper-v.
type Collector struct {
- config Config
- miSession *mi.Session
+ config Config
- // Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
- healthCritical *prometheus.Desc
- healthOk *prometheus.Desc
+ collectorFns []func(ch chan<- prometheus.Metric) error
+ closeFns []func()
- // 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
+ collectorDataStore
+ collectorDynamicMemoryBalancer
+ collectorDynamicMemoryVM
+ collectorHypervisorLogicalProcessor
+ collectorHypervisorRootPartition
+ collectorHypervisorRootVirtualProcessor
+ collectorHypervisorVirtualProcessor
+ collectorLegacyNetworkAdapter
+ collectorVirtualMachineHealthSummary
+ collectorVirtualMachineVidPartition
+ collectorVirtualNetworkAdapter
+ collectorVirtualNetworkAdapterDropReasons
+ collectorVirtualSMB
+ collectorVirtualStorageDevice
+ collectorVirtualSwitch
}
func New(config *Config) *Collector {
@@ -145,6 +88,10 @@ func New(config *Config) *Collector {
config = &ConfigDefaults
}
+ if config.CollectorsEnabled == nil {
+ config.CollectorsEnabled = ConfigDefaults.CollectorsEnabled
+ }
+
c := &Collector{
config: *config,
}
@@ -152,8 +99,26 @@ func New(config *Config) *Collector {
return c
}
-func NewWithFlags(_ *kingpin.Application) *Collector {
- return &Collector{}
+func NewWithFlags(app *kingpin.Application) *Collector {
+ c := &Collector{
+ config: ConfigDefaults,
+ }
+ c.config.CollectorsEnabled = make([]string, 0)
+
+ var collectorsEnabled string
+
+ app.Flag(
+ "collector.hyperv.enabled",
+ "Comma-separated list of collectors to use.",
+ ).Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
+
+ app.Action(func(*kingpin.ParseContext) error {
+ c.config.CollectorsEnabled = strings.Split(collectorsEnabled, ",")
+
+ return nil
+ })
+
+ return c
}
func (c *Collector) GetName() string {
@@ -161,590 +126,118 @@ func (c *Collector) GetName() string {
}
func (c *Collector) Close() error {
+ for _, fn := range c.closeFns {
+ fn()
+ }
+
return nil
}
-func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
- if miSession == nil {
- return errors.New("miSession is nil")
+func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
+ c.collectorFns = make([]func(ch chan<- prometheus.Metric) error, 0, len(c.config.CollectorsEnabled))
+ c.closeFns = make([]func(), 0, len(c.config.CollectorsEnabled))
+
+ if len(c.config.CollectorsEnabled) == 0 {
+ return nil
}
- c.miSession = miSession
+ subCollectors := map[string]struct {
+ build func() error
+ collect func(ch chan<- prometheus.Metric) error
+ close func()
+ }{
+ subCollectorDataStore: {
+ build: c.buildDataStore,
+ collect: c.collectDataStore,
+ close: c.perfDataCollectorDataStore.Close,
+ },
+ subCollectorDynamicMemoryBalancer: {
+ build: c.buildDynamicMemoryBalancer,
+ collect: c.collectDynamicMemoryBalancer,
+ close: c.perfDataCollectorDynamicMemoryBalancer.Close,
+ },
+ subCollectorDynamicMemoryVM: {
+ build: c.buildDynamicMemoryVM,
+ collect: c.collectDynamicMemoryVM,
+ close: c.perfDataCollectorDynamicMemoryVM.Close,
+ },
+ subCollectorHypervisorLogicalProcessor: {
+ build: c.buildHypervisorLogicalProcessor,
+ collect: c.collectHypervisorLogicalProcessor,
+ close: c.perfDataCollectorHypervisorLogicalProcessor.Close,
+ },
+ subCollectorHypervisorRootPartition: {
+ build: c.buildHypervisorRootPartition,
+ collect: c.collectHypervisorRootPartition,
+ close: c.perfDataCollectorHypervisorRootPartition.Close,
+ },
+ subCollectorHypervisorRootVirtualProcessor: {
+ build: c.buildHypervisorRootVirtualProcessor,
+ collect: c.collectHypervisorRootVirtualProcessor,
+ close: c.perfDataCollectorHypervisorRootVirtualProcessor.Close,
+ },
+ subCollectorHypervisorVirtualProcessor: {
+ build: c.buildHypervisorVirtualProcessor,
+ collect: c.collectHypervisorVirtualProcessor,
+ close: c.perfDataCollectorHypervisorVirtualProcessor.Close,
+ },
+ subCollectorLegacyNetworkAdapter: {
+ build: c.buildLegacyNetworkAdapter,
+ collect: c.collectLegacyNetworkAdapter,
+ close: c.perfDataCollectorLegacyNetworkAdapter.Close,
+ },
+ subCollectorVirtualMachineHealthSummary: {
+ build: c.buildVirtualMachineHealthSummary,
+ collect: c.collectVirtualMachineHealthSummary,
+ close: c.perfDataCollectorVirtualMachineHealthSummary.Close,
+ },
+ subCollectorVirtualMachineVidPartition: {
+ build: c.buildVirtualMachineVidPartition,
+ collect: c.collectVirtualMachineVidPartition,
+ close: c.perfDataCollectorVirtualMachineVidPartition.Close,
+ },
+ subCollectorVirtualNetworkAdapter: {
+ build: c.buildVirtualNetworkAdapter,
+ collect: c.collectVirtualNetworkAdapter,
+ close: c.perfDataCollectorVirtualNetworkAdapter.Close,
+ },
+ subCollectorVirtualNetworkAdapterDropReasons: {
+ build: c.buildVirtualNetworkAdapterDropReasons,
+ collect: c.collectVirtualNetworkAdapterDropReasons,
+ close: c.perfDataCollectorVirtualNetworkAdapterDropReasons.Close,
+ },
+ subCollectorVirtualSMB: {
+ build: c.buildVirtualSMB,
+ collect: c.collectVirtualSMB,
+ close: c.perfDataCollectorVirtualSMB.Close,
+ },
+ subCollectorVirtualStorageDevice: {
+ build: c.buildVirtualStorageDevice,
+ collect: c.collectVirtualStorageDevice,
+ close: c.perfDataCollectorVirtualStorageDevice.Close,
+ },
+ subCollectorVirtualSwitch: {
+ build: c.buildVirtualSwitch,
+ collect: c.collectVirtualSwitch,
+ close: c.perfDataCollectorVirtualSwitch.Close,
+ },
+ }
- buildSubsystemName := func(component string) string { return "hyperv_" + component }
+ // Result must order, to prevent test failures.
+ sort.Strings(c.config.CollectorsEnabled)
- 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,
- )
+ for _, name := range c.config.CollectorsEnabled {
+ if _, ok := subCollectors[name]; !ok {
+ return fmt.Errorf("unknown collector: %s", name)
+ }
- //
+ if err := subCollectors[name].build(); err != nil {
+ return fmt.Errorf("failed to build %s collector: %w", name, err)
+ }
- 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,
- )
+ c.collectorFns = append(c.collectorFns, subCollectors[name].collect)
+ c.closeFns = append(c.closeFns, subCollectors[name].close)
+ }
return nil
}
@@ -752,999 +245,30 @@ func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
// 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
+ errCh := make(chan error, len(c.collectorFns))
+ errs := make([]error, 0, len(c.collectorFns))
+
+ wg := sync.WaitGroup{}
+
+ for _, fn := range c.collectorFns {
+ wg.Add(1)
+
+ go func(fn func(ch chan<- prometheus.Metric) error) {
+ defer wg.Done()
+
+ if err := fn(ch); err != nil {
+ errCh <- err
+ }
+ }(fn)
}
- if err := c.collectVmVid(ch); err != nil {
- return err
+ wg.Wait()
+
+ close(errCh)
+
+ for err := range errCh {
+ errs = append(errs, 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
- 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
- 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 :Hv VP
- 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, ":Hv VP "))
-
- 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 "))
-
- 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
+ return errors.Join(errs...)
}
diff --git a/internal/collector/hyperv/hyperv_datastore.go b/internal/collector/hyperv/hyperv_datastore.go
new file mode 100644
index 00000000..4349e6d3
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_datastore.go
@@ -0,0 +1,780 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorDataStore Hyper-V DataStore metrics
+type collectorDataStore struct {
+ perfDataCollectorDataStore *perfdata.Collector
+
+ dataStoreFragmentationRatio *prometheus.Desc // \Hyper-V DataStore(*)\Fragmentation ratio
+ dataStoreSectorSize *prometheus.Desc // \Hyper-V DataStore(*)\Sector size
+ dataStoreDataAlignment *prometheus.Desc // \Hyper-V DataStore(*)\Data alignment
+ dataStoreCurrentReplayLogSize *prometheus.Desc // \Hyper-V DataStore(*)\Current replay logSize
+ dataStoreAvailableEntries *prometheus.Desc // \Hyper-V DataStore(*)\Number of available entries inside object tables
+ dataStoreEmptyEntries *prometheus.Desc // \Hyper-V DataStore(*)\Number of empty entries inside object tables
+ dataStoreFreeBytes *prometheus.Desc // \Hyper-V DataStore(*)\Number of free bytes inside key tables
+ dataStoreDataEnd *prometheus.Desc // \Hyper-V DataStore(*)\Data end
+ dataStoreFileObjects *prometheus.Desc // \Hyper-V DataStore(*)\Number of file objects
+ dataStoreObjectTables *prometheus.Desc // \Hyper-V DataStore(*)\Number of object tables
+ dataStoreKeyTables *prometheus.Desc // \Hyper-V DataStore(*)\Number of key tables
+ dataStoreFileDataSize *prometheus.Desc // \Hyper-V DataStore(*)\File data size in bytes
+ dataStoreTableDataSize *prometheus.Desc // \Hyper-V DataStore(*)\Table data size in bytes
+ dataStoreNamesSize *prometheus.Desc // \Hyper-V DataStore(*)\Names size in bytes
+ dataStoreNumberOfKeys *prometheus.Desc // \Hyper-V DataStore(*)\Number of keys
+ dataStoreReconnectLatencyMicro *prometheus.Desc // \Hyper-V DataStore(*)\Reconnect latency microseconds
+ dataStoreDisconnectCount *prometheus.Desc // \Hyper-V DataStore(*)\Disconnect count
+ dataStoreWriteToFileByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Write to file byte latency microseconds
+ dataStoreWriteToFileByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Write to file byte count
+ dataStoreWriteToFileCount *prometheus.Desc // \Hyper-V DataStore(*)\Write to file count
+ dataStoreReadFromFileByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Read from file byte latency microseconds
+ dataStoreReadFromFileByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Read from file byte count
+ dataStoreReadFromFileCount *prometheus.Desc // \Hyper-V DataStore(*)\Read from file count
+ dataStoreWriteToStorageByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Write to storage byte latency microseconds
+ dataStoreWriteToStorageByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Write to storage byte count
+ dataStoreWriteToStorageCount *prometheus.Desc // \Hyper-V DataStore(*)\Write to storage count
+ dataStoreReadFromStorageByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Read from storage byte latency microseconds
+ dataStoreReadFromStorageByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Read from storage byte count
+ dataStoreReadFromStorageCount *prometheus.Desc // \Hyper-V DataStore(*)\Read from storage count
+ dataStoreCommitByteLatency *prometheus.Desc // \Hyper-V DataStore(*)\Commit byte latency microseconds
+ dataStoreCommitByteCount *prometheus.Desc // \Hyper-V DataStore(*)\Commit byte count
+ dataStoreCommitCount *prometheus.Desc // \Hyper-V DataStore(*)\Commit count
+ dataStoreCacheUpdateOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Cache update operation latency microseconds
+ dataStoreCacheUpdateOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Cache update operation count
+ dataStoreCommitOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Commit operation latency microseconds
+ dataStoreCommitOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Commit operation count
+ dataStoreCompactOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Compact operation latency microseconds
+ dataStoreCompactOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Compact operation count
+ dataStoreLoadFileOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Load file operation latency microseconds
+ dataStoreLoadFileOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Load file operation count
+ dataStoreRemoveOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Remove operation latency microseconds
+ dataStoreRemoveOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Remove operation count
+ dataStoreQuerySizeOperationLatency *prometheus.Desc // \Hyper-V DataStore(*)\Query size operation latency microseconds
+ dataStoreQuerySizeOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Query size operation count
+ dataStoreSetOperationLatencyMicro *prometheus.Desc // \Hyper-V DataStore(*)\Set operation latency microseconds
+ dataStoreSetOperationCount *prometheus.Desc // \Hyper-V DataStore(*)\Set operation count
+}
+
+const (
+ // Hyper-V DataStore metrics
+ dataStoreFragmentationRatio = "Fragmentation ratio"
+ dataStoreSectorSize = "Sector size"
+ dataStoreDataAlignment = "Data alignment"
+ dataStoreCurrentReplayLogSize = "Current replay logSize"
+ dataStoreAvailableEntries = "Number of available entries inside object tables"
+ dataStoreEmptyEntries = "Number of empty entries inside object tables"
+ dataStoreFreeBytes = "Number of free bytes inside key tables"
+ dataStoreDataEnd = "Data end"
+ dataStoreFileObjects = "Number of file objects"
+ dataStoreObjectTables = "Number of object tables"
+ dataStoreKeyTables = "Number of key tables"
+ dataStoreFileDataSize = "File data size in bytes"
+ dataStoreTableDataSize = "Table data size in bytes"
+ dataStoreNamesSize = "Names size in bytes"
+ dataStoreNumberOfKeys = "Number of keys"
+ dataStoreReconnectLatencyMicro = "Reconnect latency microseconds"
+ dataStoreDisconnectCount = "Disconnect count"
+ dataStoreWriteToFileByteLatency = "Write to file byte latency microseconds"
+ dataStoreWriteToFileByteCount = "Write to file byte count"
+ dataStoreWriteToFileCount = "Write to file count"
+ dataStoreReadFromFileByteLatency = "Read from file byte latency microseconds"
+ dataStoreReadFromFileByteCount = "Read from file byte count"
+ dataStoreReadFromFileCount = "Read from file count"
+ dataStoreWriteToStorageByteLatency = "Write to storage byte latency microseconds"
+ dataStoreWriteToStorageByteCount = "Write to storage byte count"
+ dataStoreWriteToStorageCount = "Write to storage count"
+ dataStoreReadFromStorageByteLatency = "Read from storage byte latency microseconds"
+ dataStoreReadFromStorageByteCount = "Read from storage byte count"
+ dataStoreReadFromStorageCount = "Read from storage count"
+ dataStoreCommitByteLatency = "Commit byte latency microseconds"
+ dataStoreCommitByteCount = "Commit byte count"
+ dataStoreCommitCount = "Commit count"
+ dataStoreCacheUpdateOperationLatency = "Cache update operation latency microseconds"
+ dataStoreCacheUpdateOperationCount = "Cache update operation count"
+ dataStoreCommitOperationLatency = "Commit operation latency microseconds"
+ dataStoreCommitOperationCount = "Commit operation count"
+ dataStoreCompactOperationLatency = "Compact operation latency microseconds"
+ dataStoreCompactOperationCount = "Compact operation count"
+ dataStoreLoadFileOperationLatency = "Load file operation latency microseconds"
+ dataStoreLoadFileOperationCount = "Load file operation count"
+ dataStoreRemoveOperationLatency = "Remove operation latency microseconds"
+ dataStoreRemoveOperationCount = "Remove operation count"
+ dataStoreQuerySizeOperationLatency = "Query size operation latency microseconds"
+ dataStoreQuerySizeOperationCount = "Query size operation count"
+ dataStoreSetOperationLatencyMicro = "Set operation latency microseconds"
+ dataStoreSetOperationCount = "Set operation count"
+)
+
+func (c *Collector) buildDataStore() error {
+ var err error
+
+ c.perfDataCollectorDataStore, err = perfdata.NewCollector("Hyper-V DataStore", perfdata.InstanceAll, []string{
+ dataStoreFragmentationRatio,
+ dataStoreSectorSize,
+ dataStoreDataAlignment,
+ dataStoreCurrentReplayLogSize,
+ dataStoreAvailableEntries,
+ dataStoreEmptyEntries,
+ dataStoreFreeBytes,
+ dataStoreDataEnd,
+ dataStoreFileObjects,
+ dataStoreObjectTables,
+ dataStoreKeyTables,
+ dataStoreFileDataSize,
+ dataStoreTableDataSize,
+ dataStoreNamesSize,
+ dataStoreNumberOfKeys,
+ dataStoreReconnectLatencyMicro,
+ dataStoreDisconnectCount,
+ dataStoreWriteToFileByteLatency,
+ dataStoreWriteToFileByteCount,
+ dataStoreWriteToFileCount,
+ dataStoreReadFromFileByteLatency,
+ dataStoreReadFromFileByteCount,
+ dataStoreReadFromFileCount,
+ dataStoreWriteToStorageByteLatency,
+ dataStoreWriteToStorageByteCount,
+ dataStoreWriteToStorageCount,
+ dataStoreReadFromStorageByteLatency,
+ dataStoreReadFromStorageByteCount,
+ dataStoreReadFromStorageCount,
+ dataStoreCommitByteLatency,
+ dataStoreCommitByteCount,
+ dataStoreCommitCount,
+ dataStoreCacheUpdateOperationLatency,
+ dataStoreCacheUpdateOperationCount,
+ dataStoreCommitOperationLatency,
+ dataStoreCommitOperationCount,
+ dataStoreCompactOperationLatency,
+ dataStoreCompactOperationCount,
+ dataStoreLoadFileOperationLatency,
+ dataStoreLoadFileOperationCount,
+ dataStoreRemoveOperationLatency,
+ dataStoreRemoveOperationCount,
+ dataStoreQuerySizeOperationLatency,
+ dataStoreQuerySizeOperationCount,
+ dataStoreSetOperationLatencyMicro,
+ dataStoreSetOperationCount,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V DataStore collector: %w", err)
+ }
+
+ c.dataStoreFragmentationRatio = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_fragmentation_ratio"),
+ "Represents the fragmentation ratio of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreSectorSize = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_sector_size_bytes"),
+ "Represents the sector size of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreDataAlignment = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_data_alignment_bytes"),
+ "Represents the data alignment of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCurrentReplayLogSize = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_current_replay_log_size_bytes"),
+ "Represents the current replay log size of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreAvailableEntries = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_available_entries"),
+ "Represents the number of available entries inside object tables.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreEmptyEntries = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_empty_entries"),
+ "Represents the number of empty entries inside object tables.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreFreeBytes = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_free_bytes"),
+ "Represents the number of free bytes inside key tables.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreDataEnd = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_data_end_bytes"),
+ "Represents the data end of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreFileObjects = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_file_objects"),
+ "Represents the number of file objects in the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreObjectTables = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_object_tables"),
+ "Represents the number of object tables in the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreKeyTables = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_key_tables"),
+ "Represents the number of key tables in the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreFileDataSize = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_file_data_size_bytes"),
+ "Represents the file data size in bytes of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreTableDataSize = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_table_data_size_bytes"),
+ "Represents the table data size in bytes of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreNamesSize = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_names_size_bytes"),
+ "Represents the names size in bytes of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreNumberOfKeys = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_number_of_keys"),
+ "Represents the number of keys in the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreReconnectLatencyMicro = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_reconnect_latency_microseconds"),
+ "Represents the reconnect latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreDisconnectCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_disconnect_count"),
+ "Represents the disconnect count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreWriteToFileByteLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_file_byte_latency_microseconds"),
+ "Represents the write to file byte latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreWriteToFileByteCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_file_byte_count"),
+ "Represents the write to file byte count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreWriteToFileCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_file_count"),
+ "Represents the write to file count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreReadFromFileByteLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_file_byte_latency_microseconds"),
+ "Represents the read from file byte latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreReadFromFileByteCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_file_byte_count"),
+ "Represents the read from file byte count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreReadFromFileCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_file_count"),
+ "Represents the read from file count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreWriteToStorageByteLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_storage_byte_latency_microseconds"),
+ "Represents the write to storage byte latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreWriteToStorageByteCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_storage_byte_count"),
+ "Represents the write to storage byte count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreWriteToStorageCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_write_to_storage_count"),
+ "Represents the write to storage count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreReadFromStorageByteLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_storage_byte_latency_microseconds"),
+ "Represents the read from storage byte latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreReadFromStorageByteCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_storage_byte_count"),
+ "Represents the read from storage byte count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreReadFromStorageCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_read_from_storage_count"),
+ "Represents the read from storage count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCommitByteLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_byte_latency_microseconds"),
+ "Represents the commit byte latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCommitByteCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_byte_count"),
+ "Represents the commit byte count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCommitCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_count"),
+ "Represents the commit count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCacheUpdateOperationLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_cache_update_operation_latency_microseconds"),
+ "Represents the cache update operation latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCacheUpdateOperationCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_cache_update_operation_count"),
+ "Represents the cache update operation count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCommitOperationLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_operation_latency_microseconds"),
+ "Represents the commit operation latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCommitOperationCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_commit_operation_count"),
+ "Represents the commit operation count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCompactOperationLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_compact_operation_latency_microseconds"),
+ "Represents the compact operation latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreCompactOperationCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_compact_operation_count"),
+ "Represents the compact operation count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreLoadFileOperationLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_load_file_operation_latency_microseconds"),
+ "Represents the load file operation latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreLoadFileOperationCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_load_file_operation_count"),
+ "Represents the load file operation count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreRemoveOperationLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_remove_operation_latency_microseconds"),
+ "Represents the remove operation latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreRemoveOperationCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_remove_operation_count"),
+ "Represents the remove operation count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreQuerySizeOperationLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_query_size_operation_latency_microseconds"),
+ "Represents the query size operation latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreQuerySizeOperationCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_query_size_operation_count"),
+ "Represents the query size operation count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreSetOperationLatencyMicro = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_set_operation_latency_microseconds"),
+ "Represents the set operation latency in microseconds of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+ c.dataStoreSetOperationCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "datastore_set_operation_count"),
+ "Represents the set operation count of the DataStore.",
+ []string{"datastore"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectDataStore(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorDataStore.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V DataStore metrics: %w", err)
+ }
+
+ for name, page := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreFragmentationRatio,
+ prometheus.GaugeValue,
+ page[dataStoreFragmentationRatio].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreSectorSize,
+ prometheus.GaugeValue,
+ page[dataStoreSectorSize].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreDataAlignment,
+ prometheus.GaugeValue,
+ page[dataStoreDataAlignment].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCurrentReplayLogSize,
+ prometheus.GaugeValue,
+ page[dataStoreCurrentReplayLogSize].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreAvailableEntries,
+ prometheus.GaugeValue,
+ page[dataStoreAvailableEntries].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreEmptyEntries,
+ prometheus.GaugeValue,
+ page[dataStoreEmptyEntries].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreFreeBytes,
+ prometheus.GaugeValue,
+ page[dataStoreFreeBytes].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreDataEnd,
+ prometheus.GaugeValue,
+ page[dataStoreDataEnd].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreFileObjects,
+ prometheus.GaugeValue,
+ page[dataStoreFileObjects].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreObjectTables,
+ prometheus.GaugeValue,
+ page[dataStoreObjectTables].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreKeyTables,
+ prometheus.GaugeValue,
+ page[dataStoreKeyTables].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreFileDataSize,
+ prometheus.GaugeValue,
+ page[dataStoreFileDataSize].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreTableDataSize,
+ prometheus.GaugeValue,
+ page[dataStoreTableDataSize].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreNamesSize,
+ prometheus.GaugeValue,
+ page[dataStoreNamesSize].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreNumberOfKeys,
+ prometheus.GaugeValue,
+ page[dataStoreNumberOfKeys].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreReconnectLatencyMicro,
+ prometheus.GaugeValue,
+ page[dataStoreReconnectLatencyMicro].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreDisconnectCount,
+ prometheus.CounterValue,
+ page[dataStoreDisconnectCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreWriteToFileByteLatency,
+ prometheus.GaugeValue,
+ page[dataStoreWriteToFileByteLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreWriteToFileByteCount,
+ prometheus.CounterValue,
+ page[dataStoreWriteToFileByteCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreWriteToFileCount,
+ prometheus.CounterValue,
+ page[dataStoreWriteToFileCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreReadFromFileByteLatency,
+ prometheus.GaugeValue,
+ page[dataStoreReadFromFileByteLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreReadFromFileByteCount,
+ prometheus.CounterValue,
+ page[dataStoreReadFromFileByteCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreReadFromFileCount,
+ prometheus.CounterValue,
+ page[dataStoreReadFromFileCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreWriteToStorageByteLatency,
+ prometheus.GaugeValue,
+ page[dataStoreWriteToStorageByteLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreWriteToStorageByteCount,
+ prometheus.CounterValue,
+ page[dataStoreWriteToStorageByteCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreWriteToStorageCount,
+ prometheus.CounterValue,
+ page[dataStoreWriteToStorageCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreReadFromStorageByteLatency,
+ prometheus.GaugeValue,
+ page[dataStoreReadFromStorageByteLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreReadFromStorageByteCount,
+ prometheus.CounterValue,
+ page[dataStoreReadFromStorageByteCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreReadFromStorageCount,
+ prometheus.CounterValue,
+ page[dataStoreReadFromStorageCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCommitByteLatency,
+ prometheus.GaugeValue,
+ page[dataStoreCommitByteLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCommitByteCount,
+ prometheus.CounterValue,
+ page[dataStoreCommitByteCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCommitCount,
+ prometheus.CounterValue,
+ page[dataStoreCommitCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCacheUpdateOperationLatency,
+ prometheus.GaugeValue,
+ page[dataStoreCacheUpdateOperationLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCacheUpdateOperationCount,
+ prometheus.CounterValue,
+ page[dataStoreCacheUpdateOperationCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCommitOperationLatency,
+ prometheus.GaugeValue,
+ page[dataStoreCommitOperationLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCommitOperationCount,
+ prometheus.CounterValue,
+ page[dataStoreCommitOperationCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCompactOperationLatency,
+ prometheus.GaugeValue,
+ page[dataStoreCompactOperationLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreCompactOperationCount,
+ prometheus.CounterValue,
+ page[dataStoreCompactOperationCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreLoadFileOperationLatency,
+ prometheus.GaugeValue,
+ page[dataStoreLoadFileOperationLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreLoadFileOperationCount,
+ prometheus.CounterValue,
+ page[dataStoreLoadFileOperationCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreRemoveOperationLatency,
+ prometheus.GaugeValue,
+ page[dataStoreRemoveOperationLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreRemoveOperationCount,
+ prometheus.CounterValue,
+ page[dataStoreRemoveOperationCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreQuerySizeOperationLatency,
+ prometheus.GaugeValue,
+ page[dataStoreQuerySizeOperationLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreQuerySizeOperationCount,
+ prometheus.CounterValue,
+ page[dataStoreQuerySizeOperationCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreSetOperationLatencyMicro,
+ prometheus.GaugeValue,
+ page[dataStoreSetOperationLatencyMicro].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.dataStoreSetOperationCount,
+ prometheus.CounterValue,
+ page[dataStoreSetOperationCount].FirstValue,
+ name,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_dynamic_memory_balancer.go b/internal/collector/hyperv/hyperv_dynamic_memory_balancer.go
new file mode 100644
index 00000000..cfa6e4ee
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_dynamic_memory_balancer.go
@@ -0,0 +1,108 @@
+package hyperv
+
+import (
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus-community/windows_exporter/internal/utils"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorDynamicMemoryBalancer Hyper-V Dynamic Memory Balancer metrics
+type collectorDynamicMemoryBalancer struct {
+ perfDataCollectorDynamicMemoryBalancer *perfdata.Collector
+ vmDynamicMemoryBalancerAvailableMemoryForBalancing *prometheus.Desc // \Hyper-V Dynamic Memory Balancer(*)\Available Memory For Balancing
+ vmDynamicMemoryBalancerSystemCurrentPressure *prometheus.Desc // \Hyper-V Dynamic Memory Balancer(*)\System Current Pressure
+ vmDynamicMemoryBalancerAvailableMemory *prometheus.Desc // \Hyper-V Dynamic Memory Balancer(*)\Available Memory
+ vmDynamicMemoryBalancerAveragePressure *prometheus.Desc // \Hyper-V Dynamic Memory Balancer(*)\Average Pressure
+}
+
+const (
+ // Hyper-V Dynamic Memory Balancer metrics
+ vmDynamicMemoryBalancerAvailableMemory = "Available Memory"
+ vmDynamicMemoryBalancerAvailableMemoryForBalancing = "Available Memory For Balancing"
+ vmDynamicMemoryBalancerAveragePressure = "Average Pressure"
+ vmDynamicMemoryBalancerSystemCurrentPressure = "System Current Pressure"
+)
+
+func (c *Collector) buildDynamicMemoryBalancer() error {
+ var err error
+
+ // https://learn.microsoft.com/en-us/archive/blogs/chrisavis/monitoring-dynamic-memory-in-windows-server-hyper-v-2012
+ c.perfDataCollectorDynamicMemoryBalancer, err = perfdata.NewCollector("Hyper-V Dynamic Memory Balancer", perfdata.InstanceAll, []string{
+ vmDynamicMemoryBalancerAvailableMemory,
+ vmDynamicMemoryBalancerAvailableMemoryForBalancing,
+ vmDynamicMemoryBalancerAveragePressure,
+ vmDynamicMemoryBalancerSystemCurrentPressure,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to create Hyper-V Virtual Machine Health Summary collector: %w", err)
+ }
+
+ c.vmDynamicMemoryBalancerAvailableMemory = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_balancer_available_memory_bytes"),
+ "Represents the amount of memory left on the node.",
+ []string{"balancer"},
+ nil,
+ )
+ c.vmDynamicMemoryBalancerAvailableMemoryForBalancing = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_balancer_available_memory_for_balancing_bytes"),
+ "Represents the available memory for balancing purposes.",
+ []string{"balancer"},
+ nil,
+ )
+ c.vmDynamicMemoryBalancerAveragePressure = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_balancer_average_pressure_ratio"),
+ "Represents the average system pressure on the balancer node among all balanced objects.",
+ []string{"balancer"},
+ nil,
+ )
+ c.vmDynamicMemoryBalancerSystemCurrentPressure = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_balancer_system_current_pressure_ratio"),
+ "Represents the current pressure in the system.",
+ []string{"balancer"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectDynamicMemoryBalancer(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorDynamicMemoryBalancer.Collect()
+ if err != nil {
+ return fmt.Errorf("failed to collect Hyper-V Dynamic Memory Balancer metrics: %w", err)
+ }
+
+ for name, page := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.vmDynamicMemoryBalancerAvailableMemory,
+ prometheus.GaugeValue,
+ utils.MBToBytes(page[vmDynamicMemoryBalancerAvailableMemory].FirstValue),
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmDynamicMemoryBalancerAvailableMemoryForBalancing,
+ prometheus.GaugeValue,
+ utils.MBToBytes(page[vmDynamicMemoryBalancerAvailableMemoryForBalancing].FirstValue),
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmDynamicMemoryBalancerAveragePressure,
+ prometheus.GaugeValue,
+ utils.PercentageToRatio(page[vmDynamicMemoryBalancerAveragePressure].FirstValue),
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmDynamicMemoryBalancerSystemCurrentPressure,
+ prometheus.GaugeValue,
+ utils.PercentageToRatio(page[vmDynamicMemoryBalancerSystemCurrentPressure].FirstValue),
+ name,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_dynamic_memory_vm.go b/internal/collector/hyperv/hyperv_dynamic_memory_vm.go
new file mode 100644
index 00000000..639c3927
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_dynamic_memory_vm.go
@@ -0,0 +1,204 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus-community/windows_exporter/internal/utils"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorDynamicMemoryVM Hyper-V Dynamic Memory VM metrics
+type collectorDynamicMemoryVM struct {
+ perfDataCollectorDynamicMemoryVM *perfdata.Collector
+ vmMemoryAddedMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Added Memory
+ vmMemoryCurrentPressure *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Current Pressure
+ vmMemoryGuestVisiblePhysicalMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Guest Visible Physical Memory
+ vmMemoryMaximumPressure *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Maximum Pressure
+ vmMemoryMemoryAddOperations *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Memory Add Operations
+ vmMemoryMemoryRemoveOperations *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Memory Remove Operations
+ vmMemoryMinimumPressure *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Minimum Pressure
+ vmMemoryPhysicalMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Physical Memory
+ vmMemoryRemovedMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Removed Memory
+ vmMemoryGuestAvailableMemory *prometheus.Desc // \Hyper-V Dynamic Memory VM(*)\Guest Available Memory
+}
+
+const (
+ // Hyper-V Dynamic Memory VM metrics
+ vmMemoryAddedMemory = "Added Memory"
+ vmMemoryCurrentPressure = "Current Pressure"
+ vmMemoryGuestAvailableMemory = "Guest Available Memory"
+ vmMemoryGuestVisiblePhysicalMemory = "Guest Visible Physical Memory"
+ vmMemoryMaximumPressure = "Maximum Pressure"
+ vmMemoryMemoryAddOperations = "Memory Add Operations"
+ vmMemoryMemoryRemoveOperations = "Memory Remove Operations"
+ vmMemoryMinimumPressure = "Minimum Pressure"
+ vmMemoryPhysicalMemory = "Physical Memory"
+ vmMemoryRemovedMemory = "Removed Memory"
+)
+
+func (c *Collector) buildDynamicMemoryVM() error {
+ var err error
+
+ c.perfDataCollectorDynamicMemoryVM, err = perfdata.NewCollector("Hyper-V Dynamic Memory VM", perfdata.InstanceAll, []string{
+ vmMemoryAddedMemory,
+ vmMemoryCurrentPressure,
+ vmMemoryGuestVisiblePhysicalMemory,
+ vmMemoryMaximumPressure,
+ vmMemoryMemoryAddOperations,
+ vmMemoryMemoryRemoveOperations,
+ vmMemoryMinimumPressure,
+ vmMemoryPhysicalMemory,
+ vmMemoryRemovedMemory,
+ vmMemoryGuestAvailableMemory,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V Dynamic Memory VM collector: %w", err)
+ }
+
+ c.vmMemoryAddedMemory = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_added_total"),
+ "Represents the cumulative amount of memory added to the VM.",
+ []string{"vm"},
+ nil,
+ )
+ c.vmMemoryCurrentPressure = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_pressure_current_ratio"),
+ "Represents the current pressure in the VM.",
+ []string{"vm"},
+ nil,
+ )
+ c.vmMemoryGuestAvailableMemory = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_guest_available_bytes"),
+ "Represents the current amount of available memory in the VM (reported by the VM).",
+ []string{"vm"},
+ nil,
+ )
+ c.vmMemoryGuestVisiblePhysicalMemory = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_guest_visible_physical_memory_bytes"),
+ "Represents the amount of memory visible in the VM.'",
+ []string{"vm"},
+ nil,
+ )
+ c.vmMemoryMaximumPressure = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_pressure_maximum_ratio"),
+ "Represents the maximum pressure band in the VM.",
+ []string{"vm"},
+ nil,
+ )
+ c.vmMemoryMemoryAddOperations = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_add_operations_total"),
+ "Represents the total number of add operations for the VM.",
+ []string{"vm"},
+ nil,
+ )
+ c.vmMemoryMemoryRemoveOperations = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_remove_operations_total"),
+ "Represents the total number of remove operations for the VM.",
+ []string{"vm"},
+ nil,
+ )
+ c.vmMemoryMinimumPressure = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_pressure_minimum_ratio"),
+ "Represents the minimum pressure band in the VM.",
+ []string{"vm"},
+ nil,
+ )
+ c.vmMemoryPhysicalMemory = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_physical_bytes"),
+ "Represents the current amount of memory in the VM.",
+ []string{"vm"},
+ nil,
+ )
+ c.vmMemoryRemovedMemory = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "dynamic_memory_vm_removed_bytes_total"),
+ "Represents the cumulative amount of memory removed from the VM.",
+ []string{"vm"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectDynamicMemoryVM(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorDynamicMemoryVM.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V Dynamic Memory VM metrics: %w", err)
+ }
+
+ for vmName, vmData := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryAddedMemory,
+ prometheus.CounterValue,
+ utils.MBToBytes(vmData[vmMemoryAddedMemory].FirstValue),
+ vmName,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryCurrentPressure,
+ prometheus.GaugeValue,
+ utils.PercentageToRatio(vmData[vmMemoryCurrentPressure].FirstValue),
+ vmName,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryGuestAvailableMemory,
+ prometheus.GaugeValue,
+ utils.MBToBytes(vmData[vmMemoryGuestAvailableMemory].FirstValue),
+ vmName,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryGuestVisiblePhysicalMemory,
+ prometheus.GaugeValue,
+ utils.MBToBytes(vmData[vmMemoryGuestVisiblePhysicalMemory].FirstValue),
+ vmName,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryMaximumPressure,
+ prometheus.GaugeValue,
+ utils.PercentageToRatio(vmData[vmMemoryMaximumPressure].FirstValue),
+ vmName,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryMemoryAddOperations,
+ prometheus.CounterValue,
+ vmData[vmMemoryMemoryAddOperations].FirstValue,
+ vmName,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryMemoryRemoveOperations,
+ prometheus.CounterValue,
+ vmData[vmMemoryMemoryRemoveOperations].FirstValue,
+ vmName,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryMinimumPressure,
+ prometheus.GaugeValue,
+ utils.PercentageToRatio(vmData[vmMemoryMinimumPressure].FirstValue),
+ vmName,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryPhysicalMemory,
+ prometheus.GaugeValue,
+ utils.MBToBytes(vmData[vmMemoryPhysicalMemory].FirstValue),
+ vmName,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.vmMemoryRemovedMemory,
+ prometheus.CounterValue,
+ utils.MBToBytes(vmData[vmMemoryRemovedMemory].FirstValue),
+ vmName,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_hypervisor_logical_processor.go b/internal/collector/hyperv/hyperv_hypervisor_logical_processor.go
new file mode 100644
index 00000000..846ba8af
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_hypervisor_logical_processor.go
@@ -0,0 +1,121 @@
+package hyperv
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorHypervisorLogicalProcessor Hyper-V Hypervisor Logical Processor metrics
+type collectorHypervisorLogicalProcessor struct {
+ perfDataCollectorHypervisorLogicalProcessor *perfdata.Collector
+
+ // \Hyper-V Hypervisor Logical Processor(*)\% Guest Run Time
+ // \Hyper-V Hypervisor Logical Processor(*)\% Hypervisor Run Time
+ // \Hyper-V Hypervisor Logical Processor(*)\% Idle Time
+ hypervisorLogicalProcessorTimeTotal *prometheus.Desc
+ hypervisorLogicalProcessorTotalRunTimeTotal *prometheus.Desc // \Hyper-V Hypervisor Logical Processor(*)\% Total Run Time
+ hypervisorLogicalProcessorContextSwitches *prometheus.Desc // \Hyper-V Hypervisor Logical Processor(*)\Context Switches/sec
+}
+
+const (
+ hypervisorLogicalProcessorGuestRunTimePercent = "% Guest Run Time"
+ hypervisorLogicalProcessorHypervisorRunTimePercent = "% Hypervisor Run Time"
+ hypervisorLogicalProcessorTotalRunTimePercent = "% Total Run Time"
+ hypervisorLogicalProcessorIdleRunTimePercent = "% Idle Time"
+ hypervisorLogicalProcessorContextSwitches = "Context Switches/sec"
+)
+
+func (c *Collector) buildHypervisorLogicalProcessor() error {
+ var err error
+
+ c.perfDataCollectorHypervisorLogicalProcessor, err = perfdata.NewCollector("Hyper-V Hypervisor Logical Processor", perfdata.InstanceAll, []string{
+ hypervisorLogicalProcessorGuestRunTimePercent,
+ hypervisorLogicalProcessorHypervisorRunTimePercent,
+ hypervisorLogicalProcessorTotalRunTimePercent,
+ hypervisorLogicalProcessorIdleRunTimePercent,
+ hypervisorLogicalProcessorContextSwitches,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to create Hyper-V Hypervisor Logical Processor collector: %w", err)
+ }
+
+ c.hypervisorLogicalProcessorTimeTotal = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "hypervisor_logical_processor_time_total"),
+ "Time that processor spent in different modes (hypervisor, guest, idle)",
+ []string{"core", "state"},
+ nil,
+ )
+ c.hypervisorLogicalProcessorTotalRunTimeTotal = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "hypervisor_logical_processor_total_run_time_total"),
+ "Time that processor spent",
+ []string{"core"},
+ nil,
+ )
+
+ c.hypervisorLogicalProcessorContextSwitches = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "hypervisor_logical_processor_context_switches_total"),
+ "The rate of virtual processor context switches on the processor.",
+ []string{"core"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectHypervisorLogicalProcessor(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorHypervisorLogicalProcessor.Collect()
+ if err != nil {
+ return fmt.Errorf("failed to collect Hyper-V Hypervisor Logical Processor metrics: %w", err)
+ }
+
+ for coreName, coreData := range data {
+ // The name format is Hv LP
+ parts := strings.Split(coreName, " ")
+ if len(parts) != 3 {
+ return fmt.Errorf("unexpected Hyper-V Hypervisor Logical Processor name format: %s", coreName)
+ }
+
+ coreId := parts[2]
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorLogicalProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorLogicalProcessorGuestRunTimePercent].FirstValue,
+ coreId, "guest",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorLogicalProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorLogicalProcessorHypervisorRunTimePercent].FirstValue,
+ coreId, "hypervisor",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorLogicalProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorLogicalProcessorIdleRunTimePercent].FirstValue,
+ coreId, "idle",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorLogicalProcessorTotalRunTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorLogicalProcessorTotalRunTimePercent].FirstValue,
+ coreId,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorLogicalProcessorContextSwitches,
+ prometheus.CounterValue,
+ coreData[hypervisorLogicalProcessorContextSwitches].FirstValue,
+ coreId,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_hypervisor_root_partition.go b/internal/collector/hyperv/hyperv_hypervisor_root_partition.go
new file mode 100644
index 00000000..763bad17
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_hypervisor_root_partition.go
@@ -0,0 +1,349 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorHypervisorRootPartition Hyper-V Hypervisor Root Partition metrics
+type collectorHypervisorRootPartition struct {
+ perfDataCollectorHypervisorRootPartition *perfdata.Collector
+ hypervisorRootPartitionAddressSpaces *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Address Spaces
+ hypervisorRootPartitionAttachedDevices *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Attached Devices
+ hypervisorRootPartitionDepositedPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Deposited Pages
+ hypervisorRootPartitionDeviceDMAErrors *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Device DMA Errors
+ hypervisorRootPartitionDeviceInterruptErrors *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Device Interrupt Errors
+ hypervisorRootPartitionDeviceInterruptMappings *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Device Interrupt Mappings
+ hypervisorRootPartitionDeviceInterruptThrottleEvents *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Device Interrupt Throttle Events
+ hypervisorRootPartitionGPAPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\GPA Pages
+ hypervisorRootPartitionGPASpaceModifications *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\GPA Space Modifications/sec
+ hypervisorRootPartitionIOTLBFlushCost *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\I/O TLB Flush Cost
+ hypervisorRootPartitionIOTLBFlushes *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\I/O TLB Flushes/sec
+ hypervisorRootPartitionRecommendedVirtualTLBSize *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Recommended Virtual TLB Size
+ hypervisorRootPartitionSkippedTimerTicks *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Skipped Timer Ticks
+ hypervisorRootPartition1GDevicePages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\1G device pages
+ hypervisorRootPartition1GGPAPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\1G GPA pages
+ hypervisorRootPartition2MDevicePages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\2M device pages
+ hypervisorRootPartition2MGPAPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\2M GPA pages
+ hypervisorRootPartition4KDevicePages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\4K device pages
+ hypervisorRootPartition4KGPAPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\4K GPA pages
+ hypervisorRootPartitionVirtualTLBFlushEntries *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Virtual TLB Flush Entries/sec
+ hypervisorRootPartitionVirtualTLBPages *prometheus.Desc // \Hyper-V Hypervisor Root Partition(*)\Virtual TLB Pages
+}
+
+const (
+ hypervisorRootPartitionAddressSpaces = "Address Spaces"
+ hypervisorRootPartitionAttachedDevices = "Attached Devices"
+ hypervisorRootPartitionDepositedPages = "Deposited Pages"
+ hypervisorRootPartitionDeviceDMAErrors = "Device DMA Errors"
+ hypervisorRootPartitionDeviceInterruptErrors = "Device Interrupt Errors"
+ hypervisorRootPartitionDeviceInterruptMappings = "Device Interrupt Mappings"
+ hypervisorRootPartitionDeviceInterruptThrottleEvents = "Device Interrupt Throttle Events"
+ hypervisorRootPartitionGPAPages = "GPA Pages"
+ hypervisorRootPartitionGPASpaceModifications = "GPA Space Modifications/sec"
+ hypervisorRootPartitionIOTLBFlushCost = "I/O TLB Flush Cost"
+ hypervisorRootPartitionIOTLBFlushes = "I/O TLB Flushes/sec"
+ hypervisorRootPartitionRecommendedVirtualTLBSize = "Recommended Virtual TLB Size"
+ hypervisorRootPartitionSkippedTimerTicks = "Skipped Timer Ticks"
+ hypervisorRootPartition1GDevicePages = "1G device pages"
+ hypervisorRootPartition1GGPAPages = "1G GPA pages"
+ hypervisorRootPartition2MDevicePages = "2M device pages"
+ hypervisorRootPartition2MGPAPages = "2M GPA pages"
+ hypervisorRootPartition4KDevicePages = "4K device pages"
+ hypervisorRootPartition4KGPAPages = "4K GPA pages"
+ hypervisorRootPartitionVirtualTLBFlushEntries = "Virtual TLB Flush Entires/sec"
+ hypervisorRootPartitionVirtualTLBPages = "Virtual TLB Pages"
+)
+
+func (c *Collector) buildHypervisorRootPartition() error {
+ var err error
+
+ c.perfDataCollectorHypervisorRootPartition, err = perfdata.NewCollector("Hyper-V Hypervisor Root Partition", []string{"Root"}, []string{
+ hypervisorRootPartitionAddressSpaces,
+ hypervisorRootPartitionAttachedDevices,
+ hypervisorRootPartitionDepositedPages,
+ hypervisorRootPartitionDeviceDMAErrors,
+ hypervisorRootPartitionDeviceInterruptErrors,
+ hypervisorRootPartitionDeviceInterruptMappings,
+ hypervisorRootPartitionDeviceInterruptThrottleEvents,
+ hypervisorRootPartitionGPAPages,
+ hypervisorRootPartitionGPASpaceModifications,
+ hypervisorRootPartitionIOTLBFlushCost,
+ hypervisorRootPartitionIOTLBFlushes,
+ hypervisorRootPartitionRecommendedVirtualTLBSize,
+ hypervisorRootPartitionSkippedTimerTicks,
+ hypervisorRootPartition1GDevicePages,
+ hypervisorRootPartition1GGPAPages,
+ hypervisorRootPartition2MDevicePages,
+ hypervisorRootPartition2MGPAPages,
+ hypervisorRootPartition4KDevicePages,
+ hypervisorRootPartition4KGPAPages,
+ hypervisorRootPartitionVirtualTLBFlushEntries,
+ hypervisorRootPartitionVirtualTLBPages,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to create Hyper-V Hypervisor Root Partition collector: %w", err)
+ }
+
+ c.hypervisorRootPartitionAddressSpaces = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_address_spaces"),
+ "The number of address spaces in the virtual TLB of the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionAttachedDevices = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_attached_devices"),
+ "The number of devices attached to the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionDepositedPages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_deposited_pages"),
+ "The number of pages deposited into the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionDeviceDMAErrors = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_device_dma_errors"),
+ "An indicator of illegal DMA requests generated by all devices assigned to the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionDeviceInterruptErrors = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_device_interrupt_errors"),
+ "An indicator of illegal interrupt requests generated by all devices assigned to the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionDeviceInterruptMappings = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_device_interrupt_mappings"),
+ "The number of device interrupt mappings used by the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionDeviceInterruptThrottleEvents = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "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.hypervisorRootPartitionGPAPages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "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.hypervisorRootPartitionGPASpaceModifications = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_gpa_space_modifications"),
+ "The rate of modifications to the GPA space of the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionIOTLBFlushCost = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_io_tlb_flush_cost"),
+ "The average time (in nanoseconds) spent processing an I/O TLB flush",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionIOTLBFlushes = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_io_tlb_flush"),
+ "The rate of flushes of I/O TLBs of the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionRecommendedVirtualTLBSize = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_recommended_virtual_tlb_size"),
+ "The recommended number of pages to be deposited for the virtual TLB",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionSkippedTimerTicks = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_physical_pages_allocated"),
+ "The number of timer interrupts skipped for the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartition1GDevicePages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_1G_device_pages"),
+ "The number of 1G pages present in the device space of the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartition1GGPAPages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_1G_gpa_pages"),
+ "The number of 1G pages present in the GPA space of the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartition2MDevicePages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_2M_device_pages"),
+ "The number of 2M pages present in the device space of the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartition2MGPAPages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_2M_gpa_pages"),
+ "The number of 2M pages present in the GPA space of the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartition4KDevicePages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_4K_device_pages"),
+ "The number of 4K pages present in the device space of the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartition4KGPAPages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_4K_gpa_pages"),
+ "The number of 4K pages present in the GPA space of the partition",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionVirtualTLBFlushEntries = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_virtual_tlb_flush_entries"),
+ "The rate of flushes of the entire virtual TLB",
+ nil,
+ nil,
+ )
+ c.hypervisorRootPartitionVirtualTLBPages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "root_partition_virtual_tlb_pages"),
+ "The number of pages used by the virtual TLB of the partition",
+ nil,
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectHypervisorRootPartition(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorHypervisorRootPartition.Collect()
+ if err != nil {
+ return fmt.Errorf("failed to collect Hyper-V Hypervisor Root Partition metrics: %w", err)
+ }
+
+ rootData, ok := data["Root"]
+ if !ok {
+ return errors.New("no data returned from Hyper-V Hypervisor Root Partition")
+ }
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionAddressSpaces,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionAddressSpaces].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionAttachedDevices,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionAttachedDevices].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionDepositedPages,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionDepositedPages].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionDeviceDMAErrors,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionDeviceDMAErrors].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionDeviceInterruptErrors,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionDeviceInterruptErrors].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionDeviceInterruptThrottleEvents,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionDeviceInterruptThrottleEvents].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionGPAPages,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionGPAPages].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionGPASpaceModifications,
+ prometheus.CounterValue,
+ rootData[hypervisorRootPartitionGPASpaceModifications].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionIOTLBFlushCost,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionIOTLBFlushCost].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionIOTLBFlushes,
+ prometheus.CounterValue,
+ rootData[hypervisorRootPartitionIOTLBFlushes].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionRecommendedVirtualTLBSize,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionRecommendedVirtualTLBSize].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionSkippedTimerTicks,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionSkippedTimerTicks].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartition1GDevicePages,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartition1GDevicePages].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartition1GGPAPages,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartition1GGPAPages].FirstValue,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartition2MDevicePages,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartition2MDevicePages].FirstValue,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartition2MGPAPages,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartition2MGPAPages].FirstValue,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartition4KDevicePages,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartition4KDevicePages].FirstValue,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartition4KGPAPages,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartition4KGPAPages].FirstValue,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionVirtualTLBFlushEntries,
+ prometheus.CounterValue,
+ rootData[hypervisorRootPartitionVirtualTLBFlushEntries].FirstValue,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootPartitionVirtualTLBPages,
+ prometheus.GaugeValue,
+ rootData[hypervisorRootPartitionVirtualTLBPages].FirstValue,
+ )
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_hypervisor_root_virtual_processor.go b/internal/collector/hyperv/hyperv_hypervisor_root_virtual_processor.go
new file mode 100644
index 00000000..9c7e1d73
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_hypervisor_root_virtual_processor.go
@@ -0,0 +1,133 @@
+package hyperv
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorHypervisorRootVirtualProcessor Hyper-V Hypervisor Root Virtual Processor metrics
+type collectorHypervisorRootVirtualProcessor struct {
+ perfDataCollectorHypervisorRootVirtualProcessor *perfdata.Collector
+
+ // \Hyper-V Hypervisor Root Virtual Processor(*)\% Guest Idle Time
+ // \Hyper-V Hypervisor Root Virtual Processor(*)\% Guest Run Time
+ // \Hyper-V Hypervisor Root Virtual Processor(*)\% Hypervisor Run Time
+ // \Hyper-V Hypervisor Root Virtual Processor(*)\% Remote Run Time
+ // \Hyper-V Hypervisor Root Virtual Processor(*)\% Total Run Time
+ hypervisorRootVirtualProcessorTimeTotal *prometheus.Desc
+ hypervisorRootVirtualProcessorTotalRunTimeTotal *prometheus.Desc
+ hypervisorRootVirtualProcessorCPUWaitTimePerDispatch *prometheus.Desc // \Hyper-V Hypervisor Root Virtual Processor(*)\CPU Wait Time Per Dispatch
+}
+
+const (
+ hypervisorRootVirtualProcessorGuestIdleTimePercent = "% Guest Idle Time"
+ hypervisorRootVirtualProcessorGuestRunTimePercent = "% Guest Run Time"
+ hypervisorRootVirtualProcessorHypervisorRunTimePercent = "% Hypervisor Run Time"
+ hypervisorRootVirtualProcessorTotalRunTimePercent = "% Total Run Time"
+ hypervisorRootVirtualProcessorRemoteRunTimePercent = "% Remote Run Time"
+ hypervisorRootVirtualProcessorCPUWaitTimePerDispatch = "CPU Wait Time Per Dispatch"
+)
+
+func (c *Collector) buildHypervisorRootVirtualProcessor() error {
+ var err error
+
+ c.perfDataCollectorHypervisorRootVirtualProcessor, err = perfdata.NewCollector("Hyper-V Hypervisor Root Virtual Processor", perfdata.InstanceAll, []string{
+ hypervisorRootVirtualProcessorGuestIdleTimePercent,
+ hypervisorRootVirtualProcessorGuestRunTimePercent,
+ hypervisorRootVirtualProcessorHypervisorRunTimePercent,
+ hypervisorRootVirtualProcessorTotalRunTimePercent,
+ hypervisorRootVirtualProcessorRemoteRunTimePercent,
+ hypervisorRootVirtualProcessorCPUWaitTimePerDispatch,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to create Hyper-V Hypervisor Root Virtual Processor collector: %w", err)
+ }
+
+ c.hypervisorRootVirtualProcessorTimeTotal = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "hypervisor_root_virtual_processor_time_total"),
+ "Time that processor spent in different modes (hypervisor, guest_run, guest_idle, remote)",
+ []string{"core", "state"},
+ nil,
+ )
+
+ c.hypervisorRootVirtualProcessorTotalRunTimeTotal = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "hypervisor_root_virtual_processor_total_run_time_total"),
+ "Time that processor spent",
+ []string{"core"},
+ nil,
+ )
+
+ c.hypervisorRootVirtualProcessorCPUWaitTimePerDispatch = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "hypervisor_root_virtual_cpu_wait_time_per_dispatch_total"),
+ "The average time (in nanoseconds) spent waiting for a virtual processor to be dispatched onto a logical processor.",
+ []string{"core"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectHypervisorRootVirtualProcessor(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorHypervisorRootVirtualProcessor.Collect()
+ if err != nil {
+ return fmt.Errorf("failed to collect Hyper-V Hypervisor Root Virtual Processor metrics: %w", err)
+ }
+
+ for coreName, coreData := range data {
+ // The name format is Hv LP
+ parts := strings.Split(coreName, " ")
+ if len(parts) != 3 {
+ return fmt.Errorf("unexpected Hyper-V Hypervisor Root Virtual Processor name format: %s", coreName)
+ }
+
+ coreId := parts[2]
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootVirtualProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorRootVirtualProcessorGuestRunTimePercent].FirstValue,
+ coreId, "guest_run",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootVirtualProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorRootVirtualProcessorHypervisorRunTimePercent].FirstValue,
+ coreId, "hypervisor",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootVirtualProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorRootVirtualProcessorGuestIdleTimePercent].FirstValue,
+ coreId, "guest_idle",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootVirtualProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorRootVirtualProcessorRemoteRunTimePercent].FirstValue,
+ coreId, "remote",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootVirtualProcessorTotalRunTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorRootVirtualProcessorTotalRunTimePercent].FirstValue,
+ coreId,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorRootVirtualProcessorCPUWaitTimePerDispatch,
+ prometheus.CounterValue,
+ coreData[hypervisorRootVirtualProcessorCPUWaitTimePerDispatch].FirstValue,
+ coreId,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_hypervisor_virtual_processor.go b/internal/collector/hyperv/hyperv_hypervisor_virtual_processor.go
new file mode 100644
index 00000000..acf5d077
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_hypervisor_virtual_processor.go
@@ -0,0 +1,137 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorHypervisorVirtualProcessor Hyper-V Hypervisor Virtual Processor metrics
+type collectorHypervisorVirtualProcessor struct {
+ perfDataCollectorHypervisorVirtualProcessor *perfdata.Collector
+
+ // \Hyper-V Hypervisor Virtual Processor(*)\% Guest Idle Time
+ // \Hyper-V Hypervisor Virtual Processor(*)\% Guest Run Time
+ // \Hyper-V Hypervisor Virtual Processor(*)\% Hypervisor Run Time
+ // \Hyper-V Hypervisor Virtual Processor(*)\% Remote Run Time
+ hypervisorVirtualProcessorTimeTotal *prometheus.Desc
+ hypervisorVirtualProcessorTotalRunTimeTotal *prometheus.Desc // \Hyper-V Hypervisor Virtual Processor(*)\% Total Run Time
+ hypervisorVirtualProcessorContextSwitches *prometheus.Desc // \Hyper-V Hypervisor Virtual Processor(*)\CPU Wait Time Per Dispatch
+}
+
+const (
+ hypervisorVirtualProcessorGuestRunTimePercent = "% Guest Run Time"
+ hypervisorVirtualProcessorGuestIdleTimePercent = "% Guest Idle Time"
+ hypervisorVirtualProcessorHypervisorRunTimePercent = "% Hypervisor Run Time"
+ hypervisorVirtualProcessorTotalRunTimePercent = "% Total Run Time"
+ hypervisorVirtualProcessorRemoteRunTimePercent = "% Remote Run Time"
+ hypervisorVirtualProcessorCPUWaitTimePerDispatch = "CPU Wait Time Per Dispatch"
+)
+
+func (c *Collector) buildHypervisorVirtualProcessor() error {
+ var err error
+
+ c.perfDataCollectorHypervisorVirtualProcessor, err = perfdata.NewCollector("Hyper-V Hypervisor Virtual Processor", perfdata.InstanceAll, []string{
+ hypervisorVirtualProcessorGuestRunTimePercent,
+ hypervisorVirtualProcessorGuestIdleTimePercent,
+ hypervisorVirtualProcessorHypervisorRunTimePercent,
+ hypervisorVirtualProcessorTotalRunTimePercent,
+ hypervisorVirtualProcessorRemoteRunTimePercent,
+ hypervisorVirtualProcessorCPUWaitTimePerDispatch,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V Hypervisor Virtual Processor collector: %w", err)
+ }
+
+ c.hypervisorVirtualProcessorTimeTotal = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "hypervisor_virtual_processor_time_total"),
+ "Time that processor spent in different modes (hypervisor, guest_run, guest_idle, remote)",
+ []string{"vm", "core", "state"},
+ nil,
+ )
+ c.hypervisorVirtualProcessorTotalRunTimeTotal = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "hypervisor_virtual_processor_total_run_time_total"),
+ "Time that processor spent",
+ []string{"vm", "core"},
+ nil,
+ )
+ c.hypervisorVirtualProcessorContextSwitches = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "hypervisor_virtual_processor_cpu_wait_time_per_dispatch_total"),
+ "The average time (in nanoseconds) spent waiting for a virtual processor to be dispatched onto a logical processor.",
+ []string{"vm", "core"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectHypervisorVirtualProcessor(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorHypervisorVirtualProcessor.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V Hypervisor Virtual Processor metrics: %w", err)
+ }
+
+ for coreName, coreData := range data {
+ // The name format is :Hv VP
+ parts := strings.Split(coreName, ":")
+ if len(parts) != 2 {
+ return fmt.Errorf("unexpected format of Name in Hyper-V Hypervisor Virtual Processor: %q, expected %q", coreName, ":Hv VP ")
+ }
+
+ coreParts := strings.Split(parts[1], " ")
+ if len(coreParts) != 3 {
+ return fmt.Errorf("unexpected format of core identifier in Hyper-V Hypervisor Virtual Processor: %q, expected %q", parts[1], "Hv VP ")
+ }
+
+ vmName := parts[0]
+ coreId := coreParts[2]
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorVirtualProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorVirtualProcessorGuestRunTimePercent].FirstValue,
+ vmName, coreId, "guest_run",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorVirtualProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorVirtualProcessorHypervisorRunTimePercent].FirstValue,
+ vmName, coreId, "hypervisor",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorVirtualProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorVirtualProcessorGuestIdleTimePercent].FirstValue,
+ vmName, coreId, "guest_idle",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorVirtualProcessorTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorVirtualProcessorGuestIdleTimePercent].FirstValue,
+ vmName, coreId, "guest_idle",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorVirtualProcessorTotalRunTimeTotal,
+ prometheus.CounterValue,
+ coreData[hypervisorVirtualProcessorTotalRunTimePercent].FirstValue,
+ vmName, coreId,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.hypervisorVirtualProcessorContextSwitches,
+ prometheus.CounterValue,
+ coreData[hypervisorVirtualProcessorCPUWaitTimePerDispatch].FirstValue,
+ vmName, coreId,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_legacy_network_adapter.go b/internal/collector/hyperv/hyperv_legacy_network_adapter.go
new file mode 100644
index 00000000..b0ccbccc
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_legacy_network_adapter.go
@@ -0,0 +1,139 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorLegacyNetworkAdapter Hyper-V Legacy Network Adapter metrics
+type collectorLegacyNetworkAdapter struct {
+ perfDataCollectorLegacyNetworkAdapter *perfdata.Collector
+
+ legacyNetworkAdapterBytesDropped *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Bytes Dropped
+ legacyNetworkAdapterBytesReceived *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Bytes Received/sec
+ legacyNetworkAdapterBytesSent *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Bytes Sent/sec
+ legacyNetworkAdapterFramesDropped *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Frames Dropped
+ legacyNetworkAdapterFramesReceived *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Frames Received/sec
+ legacyNetworkAdapterFramesSent *prometheus.Desc // \Hyper-V Legacy Network Adapter(*)\Frames Sent/sec
+}
+
+const (
+ legacyNetworkAdapterBytesDropped = "Bytes Dropped"
+ legacyNetworkAdapterBytesReceived = "Bytes Received/sec"
+ legacyNetworkAdapterBytesSent = "Bytes Sent/sec"
+ legacyNetworkAdapterFramesDropped = "Frames Dropped"
+ legacyNetworkAdapterFramesReceived = "Frames Received/sec"
+ legacyNetworkAdapterFramesSent = "Frames Sent/sec"
+)
+
+func (c *Collector) buildLegacyNetworkAdapter() error {
+ var err error
+
+ c.perfDataCollectorLegacyNetworkAdapter, err = perfdata.NewCollector("Hyper-V Legacy Network Adapter", perfdata.InstanceAll, []string{
+ legacyNetworkAdapterBytesDropped,
+ legacyNetworkAdapterBytesReceived,
+ legacyNetworkAdapterBytesSent,
+ legacyNetworkAdapterFramesDropped,
+ legacyNetworkAdapterFramesReceived,
+ legacyNetworkAdapterFramesSent,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V Legacy Network Adapter collector: %w", err)
+ }
+
+ c.legacyNetworkAdapterBytesDropped = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_bytes_dropped_total"),
+ "Bytes Dropped is the number of bytes dropped on the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.legacyNetworkAdapterBytesReceived = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_bytes_received_total"),
+ "Bytes received is the number of bytes received on the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.legacyNetworkAdapterBytesSent = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_bytes_sent_total"),
+ "Bytes sent is the number of bytes sent over the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.legacyNetworkAdapterFramesDropped = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_frames_dropped_total"),
+ "Frames Dropped is the number of frames dropped on the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.legacyNetworkAdapterFramesReceived = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_frames_received_total"),
+ "Frames received is the number of frames received on the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.legacyNetworkAdapterFramesSent = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "legacy_network_adapter_frames_sent_total"),
+ "Frames sent is the number of frames sent over the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectLegacyNetworkAdapter(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorLegacyNetworkAdapter.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V Legacy Network Adapter metrics: %w", err)
+ }
+
+ for name, adapter := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.legacyNetworkAdapterBytesDropped,
+ prometheus.GaugeValue,
+ adapter[legacyNetworkAdapterBytesDropped].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.legacyNetworkAdapterBytesReceived,
+ prometheus.CounterValue,
+ adapter[legacyNetworkAdapterBytesReceived].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.legacyNetworkAdapterBytesSent,
+ prometheus.CounterValue,
+ adapter[legacyNetworkAdapterBytesSent].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.legacyNetworkAdapterFramesReceived,
+ prometheus.CounterValue,
+ adapter[legacyNetworkAdapterFramesReceived].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.legacyNetworkAdapterFramesDropped,
+ prometheus.CounterValue,
+ adapter[legacyNetworkAdapterFramesDropped].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.legacyNetworkAdapterFramesSent,
+ prometheus.CounterValue,
+ adapter[legacyNetworkAdapterFramesSent].FirstValue,
+ name,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_virtual_machine_health_summary.go b/internal/collector/hyperv/hyperv_virtual_machine_health_summary.go
new file mode 100644
index 00000000..2e71681f
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_virtual_machine_health_summary.go
@@ -0,0 +1,74 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorVirtualMachineHealthSummary Hyper-V Virtual Machine Health Summary metrics
+type collectorVirtualMachineHealthSummary struct {
+ perfDataCollectorVirtualMachineHealthSummary *perfdata.Collector
+
+ // \Hyper-V Virtual Machine Health Summary\Health Critical
+ // \Hyper-V Virtual Machine Health Summary\Health Ok
+ health *prometheus.Desc
+}
+
+const (
+ // Hyper-V Virtual Machine Health Summary
+ healthCritical = "Health Critical"
+ healthOk = "Health Ok"
+)
+
+func (c *Collector) buildVirtualMachineHealthSummary() error {
+ var err error
+
+ c.perfDataCollectorVirtualMachineHealthSummary, err = perfdata.NewCollector("Hyper-V Virtual Machine Health Summary", nil, []string{
+ healthCritical,
+ healthOk,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to create Hyper-V Virtual Machine Health Summary collector: %w", err)
+ }
+
+ c.health = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_machine_health_total_count"),
+ "Represents the number of virtual machines with critical health",
+ []string{"state"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectVirtualMachineHealthSummary(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorVirtualMachineHealthSummary.Collect()
+ if err != nil {
+ return fmt.Errorf("failed to collect Hyper-V Virtual Machine Health Summary metrics: %w", err)
+ }
+
+ healthData, ok := data[perfdata.EmptyInstance]
+ if !ok {
+ return errors.New("no data returned for Hyper-V Virtual Machine Health Summary")
+ }
+
+ ch <- prometheus.MustNewConstMetric(
+ c.health,
+ prometheus.GaugeValue,
+ healthData[healthCritical].FirstValue,
+ "critical",
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.health,
+ prometheus.GaugeValue,
+ healthData[healthOk].FirstValue,
+ "ok",
+ )
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_virtual_machine_vid_partition.go b/internal/collector/hyperv/hyperv_virtual_machine_vid_partition.go
new file mode 100644
index 00000000..740d4233
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_virtual_machine_vid_partition.go
@@ -0,0 +1,90 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorVirtualMachineVidPartition Hyper-V VM Vid Partition metrics
+type collectorVirtualMachineVidPartition struct {
+ perfDataCollectorVirtualMachineVidPartition *perfdata.Collector
+ physicalPagesAllocated *prometheus.Desc // \Hyper-V VM Vid Partition(*)\Physical Pages Allocated
+ preferredNUMANodeIndex *prometheus.Desc // \Hyper-V VM Vid Partition(*)\Preferred NUMA Node Index
+ remotePhysicalPages *prometheus.Desc // \Hyper-V VM Vid Partition(*)\Remote Physical Pages
+}
+
+const (
+ physicalPagesAllocated = "Physical Pages Allocated"
+ preferredNUMANodeIndex = "Preferred NUMA Node Index"
+ remotePhysicalPages = "Remote Physical Pages"
+)
+
+func (c *Collector) buildVirtualMachineVidPartition() error {
+ var err error
+
+ c.perfDataCollectorVirtualMachineVidPartition, err = perfdata.NewCollector("Hyper-V VM Vid Partition", perfdata.InstanceAll, []string{
+ physicalPagesAllocated,
+ preferredNUMANodeIndex,
+ remotePhysicalPages,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V VM Vid Partition collector: %w", err)
+ }
+
+ c.physicalPagesAllocated = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vid_physical_pages_allocated"),
+ "The number of physical pages allocated",
+ []string{"vm"},
+ nil,
+ )
+ c.preferredNUMANodeIndex = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vid_preferred_numa_node_index"),
+ "The preferred NUMA node index associated with this partition",
+ []string{"vm"},
+ nil,
+ )
+ c.remotePhysicalPages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vid_remote_physical_pages"),
+ "The number of physical pages not allocated from the preferred NUMA node",
+ []string{"vm"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectVirtualMachineVidPartition(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorVirtualMachineVidPartition.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V VM Vid Partition metrics: %w", err)
+ }
+
+ for name, page := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.physicalPagesAllocated,
+ prometheus.GaugeValue,
+ page[physicalPagesAllocated].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.preferredNUMANodeIndex,
+ prometheus.GaugeValue,
+ page[preferredNUMANodeIndex].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.remotePhysicalPages,
+ prometheus.GaugeValue,
+ page[remotePhysicalPages].FirstValue,
+ name,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_virtual_network_adapter.go b/internal/collector/hyperv/hyperv_virtual_network_adapter.go
new file mode 100644
index 00000000..6ac083e0
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_virtual_network_adapter.go
@@ -0,0 +1,139 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorVirtualNetworkAdapter Hyper-V Virtual Network Adapter metrics
+type collectorVirtualNetworkAdapter struct {
+ perfDataCollectorVirtualNetworkAdapter *perfdata.Collector
+
+ virtualNetworkAdapterBytesReceived *prometheus.Desc // \Hyper-V Virtual Network Adapter(*)\Bytes Received/sec
+ virtualNetworkAdapterBytesSent *prometheus.Desc // \Hyper-V Virtual Network Adapter(*)\Bytes Sent/sec
+ virtualNetworkAdapterDroppedPacketsIncoming *prometheus.Desc // \Hyper-V Virtual Network Adapter(*)\Dropped Packets Incoming/sec
+ virtualNetworkAdapterDroppedPacketsOutgoing *prometheus.Desc // \Hyper-V Virtual Network Adapter(*)\Dropped Packets Outgoing/sec
+ virtualNetworkAdapterPacketsReceived *prometheus.Desc // \Hyper-V Virtual Network Adapter(*)\Packets Received/sec
+ virtualNetworkAdapterPacketsSent *prometheus.Desc // \Hyper-V Virtual Network Adapter(*)\Packets Sent/sec
+}
+
+const (
+ virtualNetworkAdapterBytesReceived = "Bytes Received/sec"
+ virtualNetworkAdapterBytesSent = "Bytes Sent/sec"
+ virtualNetworkAdapterDroppedPacketsIncoming = "Dropped Packets Incoming/sec"
+ virtualNetworkAdapterDroppedPacketsOutgoing = "Dropped Packets Outgoing/sec"
+ virtualNetworkAdapterPacketsReceived = "Packets Received/sec"
+ virtualNetworkAdapterPacketsSent = "Packets Sent/sec"
+)
+
+func (c *Collector) buildVirtualNetworkAdapter() error {
+ var err error
+
+ c.perfDataCollectorVirtualNetworkAdapter, err = perfdata.NewCollector("Hyper-V Virtual Network Adapter", perfdata.InstanceAll, []string{
+ virtualNetworkAdapterBytesReceived,
+ virtualNetworkAdapterBytesSent,
+ virtualNetworkAdapterDroppedPacketsIncoming,
+ virtualNetworkAdapterDroppedPacketsOutgoing,
+ virtualNetworkAdapterPacketsReceived,
+ virtualNetworkAdapterPacketsSent,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V Virtual Network Adapter collector: %w", err)
+ }
+
+ c.virtualNetworkAdapterBytesReceived = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_network_adapter_received_bytes_total"),
+ "Represents the total number of bytes received per second by the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.virtualNetworkAdapterBytesSent = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_network_adapter_sent_bytes_total"),
+ "Represents the total number of bytes sent per second by the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.virtualNetworkAdapterDroppedPacketsIncoming = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_network_adapter_incoming_dropped_packets_total"),
+ "Represents the total number of dropped packets per second in the incoming direction of the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.virtualNetworkAdapterDroppedPacketsOutgoing = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_network_adapter_outgoing_dropped_packets_total"),
+ "Represents the total number of dropped packets per second in the outgoing direction of the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.virtualNetworkAdapterPacketsReceived = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_network_adapter_received_packets_total"),
+ "Represents the total number of packets received per second by the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+ c.virtualNetworkAdapterPacketsSent = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_network_adapter_sent_packets_total"),
+ "Represents the total number of packets sent per second by the network adapter",
+ []string{"adapter"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectVirtualNetworkAdapter(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorVirtualNetworkAdapter.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V Virtual Network Adapter metrics: %w", err)
+ }
+
+ for name, adapterData := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterBytesReceived,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterBytesReceived].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterBytesSent,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterBytesSent].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDroppedPacketsIncoming,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDroppedPacketsIncoming].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDroppedPacketsOutgoing,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDroppedPacketsOutgoing].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterPacketsReceived,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterPacketsReceived].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterPacketsSent,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterPacketsSent].FirstValue,
+ name,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_virtual_network_adapter_drop_reasons.go b/internal/collector/hyperv/hyperv_virtual_network_adapter_drop_reasons.go
new file mode 100644
index 00000000..b0dae657
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_virtual_network_adapter_drop_reasons.go
@@ -0,0 +1,527 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorVirtualNetworkAdapterDropReasons Hyper-V Virtual Network Adapter Drop Reasons metrics
+type collectorVirtualNetworkAdapterDropReasons struct {
+ perfDataCollectorVirtualNetworkAdapterDropReasons *perfdata.Collector
+
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing LowPowerPacketFilter
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming LowPowerPacketFilter
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing InvalidPDQueue
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming InvalidPDQueue
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing FilteredIsolationUntagged
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming FilteredIsolationUntagged
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing SwitchDataFlowDisabled
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming SwitchDataFlowDisabled
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing FailedPacketFilter
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming FailedPacketFilter
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing NicDisabled
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming NicDisabled
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing FailedDestinationListUpdate
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming FailedDestinationListUpdate
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing InjectedIcmp
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming InjectedIcmp
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing StormLimit
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming StormLimit
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing InvalidFirstNBTooSmall
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming InvalidFirstNBTooSmall
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing InvalidSourceMac
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming InvalidSourceMac
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing InvalidDestMac
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming InvalidDestMac
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing InvalidVlanFormat
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming InvalidVlanFormat
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing NativeFwdingReq
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming NativeFwdingReq
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing MTUMismatch
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming MTUMismatch
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing InvalidConfig
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming InvalidConfig
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing RequiredExtensionMissing
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming RequiredExtensionMissing
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing VirtualSubnetId
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming VirtualSubnetId
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing BridgeReserved
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming BridgeReserved
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing RouterGuard
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming RouterGuard
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing DhcpGuard
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming DhcpGuard
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing MacSpoofing
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming MacSpoofing
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing Ipsec
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming Ipsec
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing Qos
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming Qos
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing FailedPvlanSetting
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming FailedPvlanSetting
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing FailedSecurityPolicy
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming FailedSecurityPolicy
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing UnauthorizedMAC
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming UnauthorizedMAC
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing UnauthorizedVLAN
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming UnauthorizedVLAN
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing FilteredVLAN
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming FilteredVLAN
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing Filtered
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming Filtered
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing Busy
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming Busy
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing NotAccepted
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming NotAccepted
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing Disconnected
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming Disconnected
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing NotReady
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming NotReady
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing Resources
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming Resources
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing InvalidPacket
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming InvalidPacket
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing InvalidData
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming InvalidData
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Outgoing Unknown
+ // \Hyper-V Virtual Network Adapter Drop Reasons(*)\Incoming Unknown
+ virtualNetworkAdapterDropReasons *prometheus.Desc
+}
+
+const (
+ virtualNetworkAdapterDropReasonsOutgoingNativeFwdingReq = "Outgoing NativeFwdingReq"
+ virtualNetworkAdapterDropReasonsIncomingNativeFwdingReq = "Incoming NativeFwdingReq"
+ virtualNetworkAdapterDropReasonsOutgoingMTUMismatch = "Outgoing MTUMismatch"
+ virtualNetworkAdapterDropReasonsIncomingMTUMismatch = "Incoming MTUMismatch"
+ virtualNetworkAdapterDropReasonsOutgoingInvalidConfig = "Outgoing InvalidConfig"
+ virtualNetworkAdapterDropReasonsIncomingInvalidConfig = "Incoming InvalidConfig"
+ virtualNetworkAdapterDropReasonsOutgoingRequiredExtensionMissing = "Outgoing RequiredExtensionMissing"
+ virtualNetworkAdapterDropReasonsIncomingRequiredExtensionMissing = "Incoming RequiredExtensionMissing"
+ virtualNetworkAdapterDropReasonsOutgoingVirtualSubnetId = "Outgoing VirtualSubnetId"
+ virtualNetworkAdapterDropReasonsIncomingVirtualSubnetId = "Incoming VirtualSubnetId"
+ virtualNetworkAdapterDropReasonsOutgoingBridgeReserved = "Outgoing BridgeReserved"
+ virtualNetworkAdapterDropReasonsIncomingBridgeReserved = "Incoming BridgeReserved"
+ virtualNetworkAdapterDropReasonsOutgoingRouterGuard = "Outgoing RouterGuard"
+ virtualNetworkAdapterDropReasonsIncomingRouterGuard = "Incoming RouterGuard"
+ virtualNetworkAdapterDropReasonsOutgoingDhcpGuard = "Outgoing DhcpGuard"
+ virtualNetworkAdapterDropReasonsIncomingDhcpGuard = "Incoming DhcpGuard"
+ virtualNetworkAdapterDropReasonsOutgoingMacSpoofing = "Outgoing MacSpoofing"
+ virtualNetworkAdapterDropReasonsIncomingMacSpoofing = "Incoming MacSpoofing"
+ virtualNetworkAdapterDropReasonsOutgoingIpsec = "Outgoing Ipsec"
+ virtualNetworkAdapterDropReasonsIncomingIpsec = "Incoming Ipsec"
+ virtualNetworkAdapterDropReasonsOutgoingQos = "Outgoing Qos"
+ virtualNetworkAdapterDropReasonsIncomingQos = "Incoming Qos"
+ virtualNetworkAdapterDropReasonsOutgoingFailedPvlanSetting = "Outgoing FailedPvlanSetting"
+ virtualNetworkAdapterDropReasonsIncomingFailedPvlanSetting = "Incoming FailedPvlanSetting"
+ virtualNetworkAdapterDropReasonsOutgoingFailedSecurityPolicy = "Outgoing FailedSecurityPolicy"
+ virtualNetworkAdapterDropReasonsIncomingFailedSecurityPolicy = "Incoming FailedSecurityPolicy"
+ virtualNetworkAdapterDropReasonsOutgoingUnauthorizedMAC = "Outgoing UnauthorizedMAC"
+ virtualNetworkAdapterDropReasonsIncomingUnauthorizedMAC = "Incoming UnauthorizedMAC"
+ virtualNetworkAdapterDropReasonsOutgoingUnauthorizedVLAN = "Outgoing UnauthorizedVLAN"
+ virtualNetworkAdapterDropReasonsIncomingUnauthorizedVLAN = "Incoming UnauthorizedVLAN"
+ virtualNetworkAdapterDropReasonsOutgoingFilteredVLAN = "Outgoing FilteredVLAN"
+ virtualNetworkAdapterDropReasonsIncomingFilteredVLAN = "Incoming FilteredVLAN"
+ virtualNetworkAdapterDropReasonsOutgoingFiltered = "Outgoing Filtered"
+ virtualNetworkAdapterDropReasonsIncomingFiltered = "Incoming Filtered"
+ virtualNetworkAdapterDropReasonsOutgoingBusy = "Outgoing Busy"
+ virtualNetworkAdapterDropReasonsIncomingBusy = "Incoming Busy"
+ virtualNetworkAdapterDropReasonsOutgoingNotAccepted = "Outgoing NotAccepted"
+ virtualNetworkAdapterDropReasonsIncomingNotAccepted = "Incoming NotAccepted"
+ virtualNetworkAdapterDropReasonsOutgoingDisconnected = "Outgoing Disconnected"
+ virtualNetworkAdapterDropReasonsIncomingDisconnected = "Incoming Disconnected"
+ virtualNetworkAdapterDropReasonsOutgoingNotReady = "Outgoing NotReady"
+ virtualNetworkAdapterDropReasonsIncomingNotReady = "Incoming NotReady"
+ virtualNetworkAdapterDropReasonsOutgoingResources = "Outgoing Resources"
+ virtualNetworkAdapterDropReasonsIncomingResources = "Incoming Resources"
+ virtualNetworkAdapterDropReasonsOutgoingInvalidPacket = "Outgoing InvalidPacket"
+ virtualNetworkAdapterDropReasonsIncomingInvalidPacket = "Incoming InvalidPacket"
+ virtualNetworkAdapterDropReasonsOutgoingInvalidData = "Outgoing InvalidData"
+ virtualNetworkAdapterDropReasonsIncomingInvalidData = "Incoming InvalidData"
+ virtualNetworkAdapterDropReasonsOutgoingUnknown = "Outgoing Unknown"
+ virtualNetworkAdapterDropReasonsIncomingUnknown = "Incoming Unknown"
+)
+
+func (c *Collector) buildVirtualNetworkAdapterDropReasons() error {
+ var err error
+
+ c.perfDataCollectorVirtualNetworkAdapterDropReasons, err = perfdata.NewCollector("Hyper-V Virtual Network Adapter Drop Reasons", perfdata.InstanceAll, []string{
+ virtualNetworkAdapterDropReasonsOutgoingNativeFwdingReq,
+ virtualNetworkAdapterDropReasonsIncomingNativeFwdingReq,
+ virtualNetworkAdapterDropReasonsOutgoingMTUMismatch,
+ virtualNetworkAdapterDropReasonsIncomingMTUMismatch,
+ virtualNetworkAdapterDropReasonsOutgoingInvalidConfig,
+ virtualNetworkAdapterDropReasonsIncomingInvalidConfig,
+ virtualNetworkAdapterDropReasonsOutgoingRequiredExtensionMissing,
+ virtualNetworkAdapterDropReasonsIncomingRequiredExtensionMissing,
+ virtualNetworkAdapterDropReasonsOutgoingVirtualSubnetId,
+ virtualNetworkAdapterDropReasonsIncomingVirtualSubnetId,
+ virtualNetworkAdapterDropReasonsOutgoingBridgeReserved,
+ virtualNetworkAdapterDropReasonsIncomingBridgeReserved,
+ virtualNetworkAdapterDropReasonsOutgoingRouterGuard,
+ virtualNetworkAdapterDropReasonsIncomingRouterGuard,
+ virtualNetworkAdapterDropReasonsOutgoingDhcpGuard,
+ virtualNetworkAdapterDropReasonsIncomingDhcpGuard,
+ virtualNetworkAdapterDropReasonsOutgoingMacSpoofing,
+ virtualNetworkAdapterDropReasonsIncomingMacSpoofing,
+ virtualNetworkAdapterDropReasonsOutgoingIpsec,
+ virtualNetworkAdapterDropReasonsIncomingIpsec,
+ virtualNetworkAdapterDropReasonsOutgoingQos,
+ virtualNetworkAdapterDropReasonsIncomingQos,
+ virtualNetworkAdapterDropReasonsOutgoingFailedPvlanSetting,
+ virtualNetworkAdapterDropReasonsIncomingFailedPvlanSetting,
+ virtualNetworkAdapterDropReasonsOutgoingFailedSecurityPolicy,
+ virtualNetworkAdapterDropReasonsIncomingFailedSecurityPolicy,
+ virtualNetworkAdapterDropReasonsOutgoingUnauthorizedMAC,
+ virtualNetworkAdapterDropReasonsIncomingUnauthorizedMAC,
+ virtualNetworkAdapterDropReasonsOutgoingUnauthorizedVLAN,
+ virtualNetworkAdapterDropReasonsIncomingUnauthorizedVLAN,
+ virtualNetworkAdapterDropReasonsOutgoingFilteredVLAN,
+ virtualNetworkAdapterDropReasonsIncomingFilteredVLAN,
+ virtualNetworkAdapterDropReasonsOutgoingFiltered,
+ virtualNetworkAdapterDropReasonsIncomingFiltered,
+ virtualNetworkAdapterDropReasonsOutgoingBusy,
+ virtualNetworkAdapterDropReasonsIncomingBusy,
+ virtualNetworkAdapterDropReasonsOutgoingNotAccepted,
+ virtualNetworkAdapterDropReasonsIncomingNotAccepted,
+ virtualNetworkAdapterDropReasonsOutgoingDisconnected,
+ virtualNetworkAdapterDropReasonsIncomingDisconnected,
+ virtualNetworkAdapterDropReasonsOutgoingNotReady,
+ virtualNetworkAdapterDropReasonsIncomingNotReady,
+ virtualNetworkAdapterDropReasonsOutgoingResources,
+ virtualNetworkAdapterDropReasonsIncomingResources,
+ virtualNetworkAdapterDropReasonsOutgoingInvalidPacket,
+ virtualNetworkAdapterDropReasonsIncomingInvalidPacket,
+ virtualNetworkAdapterDropReasonsOutgoingInvalidData,
+ virtualNetworkAdapterDropReasonsIncomingInvalidData,
+ virtualNetworkAdapterDropReasonsOutgoingUnknown,
+ virtualNetworkAdapterDropReasonsIncomingUnknown,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V Virtual Network Adapter Drop Reasons collector: %w", err)
+ }
+
+ c.virtualNetworkAdapterDropReasons = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_network_adapter_drop_reasons"),
+ "Hyper-V Virtual Network Adapter Drop Reasons",
+ []string{"adapter", "reason", "direction"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectVirtualNetworkAdapterDropReasons(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorVirtualNetworkAdapterDropReasons.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V Virtual Network Adapter Drop Reasons metrics: %w", err)
+ }
+
+ for name, adapterData := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingNativeFwdingReq].FirstValue,
+ name, "NativeFwdingReq", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingNativeFwdingReq].FirstValue,
+ name, "NativeFwdingReq", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingMTUMismatch].FirstValue,
+ name, "MTUMismatch", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingMTUMismatch].FirstValue,
+ name, "MTUMismatch", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingInvalidConfig].FirstValue,
+ name, "InvalidConfig", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingInvalidConfig].FirstValue,
+ name, "InvalidConfig", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingRequiredExtensionMissing].FirstValue,
+ name, "RequiredExtensionMissing", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingRequiredExtensionMissing].FirstValue,
+ name, "RequiredExtensionMissing", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingVirtualSubnetId].FirstValue,
+ name, "VirtualSubnetId", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingVirtualSubnetId].FirstValue,
+ name, "VirtualSubnetId", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingBridgeReserved].FirstValue,
+ name, "BridgeReserved", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingBridgeReserved].FirstValue,
+ name, "BridgeReserved", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingRouterGuard].FirstValue,
+ name, "RouterGuard", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingRouterGuard].FirstValue,
+ name, "RouterGuard", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingDhcpGuard].FirstValue,
+ name, "DhcpGuard", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingDhcpGuard].FirstValue,
+ name, "DhcpGuard", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingMacSpoofing].FirstValue,
+ name, "MacSpoofing", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingMacSpoofing].FirstValue,
+ name, "MacSpoofing", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingIpsec].FirstValue,
+ name, "Ipsec", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingIpsec].FirstValue,
+ name, "Ipsec", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingQos].FirstValue,
+ name, "Qos", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingQos].FirstValue,
+ name, "Qos", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingFailedPvlanSetting].FirstValue,
+ name, "FailedPvlanSetting", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingFailedPvlanSetting].FirstValue,
+ name, "FailedPvlanSetting", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingFailedSecurityPolicy].FirstValue,
+ name, "FailedSecurityPolicy", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingFailedSecurityPolicy].FirstValue,
+ name, "FailedSecurityPolicy", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingUnauthorizedMAC].FirstValue,
+ name, "UnauthorizedMAC", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingUnauthorizedMAC].FirstValue,
+ name, "UnauthorizedMAC", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingUnauthorizedVLAN].FirstValue,
+ name, "UnauthorizedVLAN", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingUnauthorizedVLAN].FirstValue,
+ name, "UnauthorizedVLAN", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingFilteredVLAN].FirstValue,
+ name, "FilteredVLAN", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingFilteredVLAN].FirstValue,
+ name, "FilteredVLAN", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingFiltered].FirstValue,
+ name, "Filtered", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingFiltered].FirstValue,
+ name, "Filtered", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingBusy].FirstValue,
+ name, "Busy", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingBusy].FirstValue,
+ name, "Busy", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingNotAccepted].FirstValue,
+ name, "NotAccepted", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingNotAccepted].FirstValue,
+ name, "NotAccepted", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingDisconnected].FirstValue,
+ name, "Disconnected", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingDisconnected].FirstValue,
+ name, "Disconnected", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingNotReady].FirstValue,
+ name, "NotReady", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingNotReady].FirstValue,
+ name, "NotReady", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingResources].FirstValue,
+ name, "Resources", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingResources].FirstValue,
+ name, "Resources", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingInvalidPacket].FirstValue,
+ name, "InvalidPacket", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingInvalidPacket].FirstValue,
+ name, "InvalidPacket", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingInvalidData].FirstValue,
+ name, "InvalidData", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingInvalidData].FirstValue,
+ name, "InvalidData", "incoming",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsOutgoingUnknown].FirstValue,
+ name, "Unknown", "outgoing",
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualNetworkAdapterDropReasons,
+ prometheus.CounterValue,
+ adapterData[virtualNetworkAdapterDropReasonsIncomingUnknown].FirstValue,
+ name, "Unknown", "incoming",
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_virtual_smb.go b/internal/collector/hyperv/hyperv_virtual_smb.go
new file mode 100644
index 00000000..d1a0146c
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_virtual_smb.go
@@ -0,0 +1,315 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorVirtualSMB Hyper-V Virtual SMB metrics
+type collectorVirtualSMB struct {
+ perfDataCollectorVirtualSMB *perfdata.Collector
+
+ virtualSMBDirectMappedSections *prometheus.Desc // \Hyper-V Virtual SMB(*)\Direct-Mapped Sections
+ virtualSMBDirectMappedPages *prometheus.Desc // \Hyper-V Virtual SMB(*)\Direct-Mapped Pages
+ virtualSMBWriteBytesRDMA *prometheus.Desc // \Hyper-V Virtual SMB(*)\Write Bytes/sec (RDMA)
+ virtualSMBWriteBytes *prometheus.Desc // \Hyper-V Virtual SMB(*)\Write Bytes/sec
+ virtualSMBReadBytesRDMA *prometheus.Desc // \Hyper-V Virtual SMB(*)\Read Bytes/sec (RDMA)
+ virtualSMBReadBytes *prometheus.Desc // \Hyper-V Virtual SMB(*)\Read Bytes/sec
+ virtualSMBFlushRequests *prometheus.Desc // \Hyper-V Virtual SMB(*)\Flush Requests/sec
+ virtualSMBWriteRequestsRDMA *prometheus.Desc // \Hyper-V Virtual SMB(*)\Write Requests/sec (RDMA)
+ virtualSMBWriteRequests *prometheus.Desc // \Hyper-V Virtual SMB(*)\Write Requests/sec
+ virtualSMBReadRequestsRDMA *prometheus.Desc // \Hyper-V Virtual SMB(*)\Read Requests/sec (RDMA)
+ virtualSMBReadRequests *prometheus.Desc // \Hyper-V Virtual SMB(*)\Read Requests/sec
+ virtualSMBCurrentPendingRequests *prometheus.Desc // \Hyper-V Virtual SMB(*)\Current Pending Requests
+ virtualSMBCurrentOpenFileCount *prometheus.Desc // \Hyper-V Virtual SMB(*)\Current Open File Count
+ virtualSMBTreeConnectCount *prometheus.Desc // \Hyper-V Virtual SMB(*)\Tree Connect Count
+ virtualSMBRequests *prometheus.Desc // \Hyper-V Virtual SMB(*)\Requests/sec
+ virtualSMBSentBytes *prometheus.Desc // \Hyper-V Virtual SMB(*)\Sent Bytes/sec
+ virtualSMBReceivedBytes *prometheus.Desc // \Hyper-V Virtual SMB(*)\Received Bytes/sec
+}
+
+const (
+ virtualSMBDirectMappedSections = "Direct-Mapped Sections"
+ virtualSMBDirectMappedPages = "Direct-Mapped Pages"
+ virtualSMBWriteBytesRDMA = "Write Bytes/sec (RDMA)"
+ virtualSMBWriteBytes = "Write Bytes/sec"
+ virtualSMBReadBytesRDMA = "Read Bytes/sec (RDMA)"
+ virtualSMBReadBytes = "Read Bytes/sec"
+ virtualSMBFlushRequests = "Flush Requests/sec"
+ virtualSMBWriteRequestsRDMA = "Write Requests/sec (RDMA)"
+ virtualSMBWriteRequests = "Write Requests/sec"
+ virtualSMBReadRequestsRDMA = "Read Requests/sec (RDMA)"
+ virtualSMBReadRequests = "Read Requests/sec"
+ virtualSMBCurrentPendingRequests = "Current Pending Requests"
+ virtualSMBCurrentOpenFileCount = "Current Open File Count"
+ virtualSMBTreeConnectCount = "Tree Connect Count"
+ virtualSMBRequests = "Requests/sec"
+ virtualSMBSentBytes = "Sent Bytes/sec"
+ virtualSMBReceivedBytes = "Received Bytes/sec"
+)
+
+func (c *Collector) buildVirtualSMB() error {
+ var err error
+
+ c.perfDataCollectorVirtualSMB, err = perfdata.NewCollector("Hyper-V Virtual SMB", perfdata.InstanceAll, []string{
+ virtualSMBDirectMappedSections,
+ virtualSMBDirectMappedPages,
+ virtualSMBWriteBytesRDMA,
+ virtualSMBWriteBytes,
+ virtualSMBReadBytesRDMA,
+ virtualSMBReadBytes,
+ virtualSMBFlushRequests,
+ virtualSMBWriteRequestsRDMA,
+ virtualSMBWriteRequests,
+ virtualSMBReadRequestsRDMA,
+ virtualSMBReadRequests,
+ virtualSMBCurrentPendingRequests,
+ virtualSMBCurrentOpenFileCount,
+ virtualSMBTreeConnectCount,
+ virtualSMBRequests,
+ virtualSMBSentBytes,
+ virtualSMBReceivedBytes,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V Virtual SMB collector: %w", err)
+ }
+
+ c.virtualSMBDirectMappedSections = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_direct_mapped_sections"),
+ "Represents the number of direct-mapped sections in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBDirectMappedPages = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_direct_mapped_pages"),
+ "Represents the number of direct-mapped pages in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBWriteBytesRDMA = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_write_bytes_rdma"),
+ "Represents the number of bytes written per second using RDMA in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBWriteBytes = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_write_bytes"),
+ "Represents the number of bytes written per second in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBReadBytesRDMA = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_read_bytes_rdma"),
+ "Represents the number of bytes read per second using RDMA in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBReadBytes = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_read_bytes"),
+ "Represents the number of bytes read per second in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBFlushRequests = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_flush_requests"),
+ "Represents the number of flush requests per second in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBWriteRequestsRDMA = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_write_requests_rdma"),
+ "Represents the number of write requests per second using RDMA in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBWriteRequests = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_write_requests"),
+ "Represents the number of write requests per second in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBReadRequestsRDMA = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_read_requests_rdma"),
+ "Represents the number of read requests per second using RDMA in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBReadRequests = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_read_requests"),
+ "Represents the number of read requests per second in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBCurrentPendingRequests = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_current_pending_requests"),
+ "Represents the current number of pending requests in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBCurrentOpenFileCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_current_open_file_count"),
+ "Represents the current number of open files in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBTreeConnectCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_tree_connect_count"),
+ "Represents the number of tree connects in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBRequests = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_requests"),
+ "Represents the number of requests per second in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBSentBytes = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_sent_bytes"),
+ "Represents the number of bytes sent per second in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+ c.virtualSMBReceivedBytes = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_received_bytes"),
+ "Represents the number of bytes received per second in the virtual SMB",
+ []string{"instance"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectVirtualSMB(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorVirtualSMB.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V Virtual SMB metrics: %w", err)
+ }
+
+ for name, smbData := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBDirectMappedSections,
+ prometheus.GaugeValue,
+ smbData[virtualSMBDirectMappedSections].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBDirectMappedPages,
+ prometheus.GaugeValue,
+ smbData[virtualSMBDirectMappedPages].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBWriteBytesRDMA,
+ prometheus.CounterValue,
+ smbData[virtualSMBWriteBytesRDMA].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBWriteBytes,
+ prometheus.CounterValue,
+ smbData[virtualSMBWriteBytes].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBReadBytesRDMA,
+ prometheus.CounterValue,
+ smbData[virtualSMBReadBytesRDMA].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBReadBytes,
+ prometheus.CounterValue,
+ smbData[virtualSMBReadBytes].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBFlushRequests,
+ prometheus.CounterValue,
+ smbData[virtualSMBFlushRequests].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBWriteRequestsRDMA,
+ prometheus.CounterValue,
+ smbData[virtualSMBWriteRequestsRDMA].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBWriteRequests,
+ prometheus.CounterValue,
+ smbData[virtualSMBWriteRequests].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBReadRequestsRDMA,
+ prometheus.CounterValue,
+ smbData[virtualSMBReadRequestsRDMA].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBReadRequests,
+ prometheus.CounterValue,
+ smbData[virtualSMBReadRequests].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBCurrentPendingRequests,
+ prometheus.GaugeValue,
+ smbData[virtualSMBCurrentPendingRequests].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBCurrentOpenFileCount,
+ prometheus.GaugeValue,
+ smbData[virtualSMBCurrentOpenFileCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBTreeConnectCount,
+ prometheus.GaugeValue,
+ smbData[virtualSMBTreeConnectCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBRequests,
+ prometheus.CounterValue,
+ smbData[virtualSMBRequests].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBSentBytes,
+ prometheus.CounterValue,
+ smbData[virtualSMBSentBytes].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSMBReceivedBytes,
+ prometheus.CounterValue,
+ smbData[virtualSMBReceivedBytes].FirstValue,
+ name,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_virtual_storage_device.go b/internal/collector/hyperv/hyperv_virtual_storage_device.go
new file mode 100644
index 00000000..ce9451a4
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_virtual_storage_device.go
@@ -0,0 +1,235 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// Hyper-V Virtual Storage Device metrics
+type collectorVirtualStorageDevice struct {
+ perfDataCollectorVirtualStorageDevice *perfdata.Collector
+
+ virtualStorageDeviceErrorCount *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Error Count
+ virtualStorageDeviceQueueLength *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Queue Length
+ virtualStorageDeviceReadBytes *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Read Bytes/sec
+ virtualStorageDeviceReadOperations *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Read Operations/Sec
+ virtualStorageDeviceWriteBytes *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Write Bytes/sec
+ virtualStorageDeviceWriteOperations *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Write Operations/Sec
+ virtualStorageDeviceLatency *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Latency
+ virtualStorageDeviceThroughput *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Throughput
+ virtualStorageDeviceNormalizedThroughput *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Normalized Throughput
+ virtualStorageDeviceLowerQueueLength *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Lower Queue Length
+ virtualStorageDeviceLowerLatency *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\Lower Latency
+ virtualStorageDeviceIOQuotaReplenishmentRate *prometheus.Desc // \Hyper-V Virtual Storage Device(*)\IO Quota Replenishment Rate
+}
+
+const (
+ virtualStorageDeviceErrorCount = "Error Count"
+ virtualStorageDeviceQueueLength = "Queue Length"
+ virtualStorageDeviceReadBytes = "Read Bytes/sec"
+ virtualStorageDeviceReadOperations = "Read Count"
+ virtualStorageDeviceWriteBytes = "Write Bytes/sec"
+ virtualStorageDeviceWriteOperations = "Write Count"
+ virtualStorageDeviceLatency = "Latency"
+ virtualStorageDeviceThroughput = "Throughput"
+ virtualStorageDeviceNormalizedThroughput = "Normalized Throughput"
+ virtualStorageDeviceLowerQueueLength = "Lower Queue Length"
+ virtualStorageDeviceLowerLatency = "Lower Latency"
+ virtualStorageDeviceIOQuotaReplenishmentRate = "IO Quota Replenishment Rate"
+)
+
+func (c *Collector) buildVirtualStorageDevice() error {
+ var err error
+
+ c.perfDataCollectorVirtualStorageDevice, err = perfdata.NewCollector("Hyper-V Virtual Storage Device", perfdata.InstanceAll, []string{
+ virtualStorageDeviceErrorCount,
+ virtualStorageDeviceQueueLength,
+ virtualStorageDeviceReadBytes,
+ virtualStorageDeviceReadOperations,
+ virtualStorageDeviceWriteBytes,
+ virtualStorageDeviceWriteOperations,
+ virtualStorageDeviceLatency,
+ virtualStorageDeviceThroughput,
+ virtualStorageDeviceNormalizedThroughput,
+ virtualStorageDeviceLowerQueueLength,
+ virtualStorageDeviceLowerLatency,
+ virtualStorageDeviceIOQuotaReplenishmentRate,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V Virtual Storage Device collector: %w", err)
+ }
+
+ c.virtualStorageDeviceErrorCount = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_error_count_total"),
+ "Represents the total number of errors that have occurred on this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceQueueLength = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_queue_length"),
+ "Represents the average queue length on this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceReadBytes = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_bytes_read"),
+ "Represents the total number of bytes that have been read on this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceReadOperations = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_operations_read_total"),
+ "Represents the total number of read operations that have occurred on this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceWriteBytes = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_bytes_written"),
+ "Represents the total number of bytes that have been written on this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceWriteOperations = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_operations_written_total"),
+ "Represents the total number of write operations that have occurred on this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_latency_seconds"),
+ "Represents the average IO transfer latency for this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceThroughput = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_throughput"),
+ "Represents the average number of 8KB IO transfers completed by this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceNormalizedThroughput = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_normalized_throughput"),
+ "Represents the average number of IO transfers completed by this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceLowerQueueLength = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_lower_queue_length"),
+ "Represents the average queue length on the underlying storage subsystem for this device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceLowerLatency = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "virtual_storage_device_lower_latency_seconds"),
+ "Represents the average IO transfer latency on the underlying storage subsystem for this virtual device.",
+ []string{"device"},
+ nil,
+ )
+ c.virtualStorageDeviceIOQuotaReplenishmentRate = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "io_quota_replenishment_rate"),
+ "Represents the IO quota replenishment rate for this virtual device.",
+ []string{"device"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectVirtualStorageDevice(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorVirtualStorageDevice.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V Virtual Storage Device metrics: %w", err)
+ }
+
+ for name, device := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceErrorCount,
+ prometheus.CounterValue,
+ device[virtualStorageDeviceErrorCount].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceQueueLength,
+ prometheus.GaugeValue,
+ device[virtualStorageDeviceQueueLength].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceReadBytes,
+ prometheus.CounterValue,
+ device[virtualStorageDeviceReadBytes].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceReadOperations,
+ prometheus.CounterValue,
+ device[virtualStorageDeviceReadOperations].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceWriteBytes,
+ prometheus.CounterValue,
+ device[virtualStorageDeviceWriteBytes].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceWriteOperations,
+ prometheus.CounterValue,
+ device[virtualStorageDeviceWriteOperations].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceLatency,
+ prometheus.GaugeValue,
+ device[virtualStorageDeviceLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceThroughput,
+ prometheus.GaugeValue,
+ device[virtualStorageDeviceThroughput].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceNormalizedThroughput,
+ prometheus.GaugeValue,
+ device[virtualStorageDeviceNormalizedThroughput].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceLowerQueueLength,
+ prometheus.GaugeValue,
+ device[virtualStorageDeviceLowerQueueLength].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceLowerLatency,
+ prometheus.GaugeValue,
+ device[virtualStorageDeviceLowerLatency].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualStorageDeviceIOQuotaReplenishmentRate,
+ prometheus.GaugeValue,
+ device[virtualStorageDeviceIOQuotaReplenishmentRate].FirstValue,
+ name,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/hyperv/hyperv_virtual_switch.go b/internal/collector/hyperv/hyperv_virtual_switch.go
new file mode 100644
index 00000000..353ee598
--- /dev/null
+++ b/internal/collector/hyperv/hyperv_virtual_switch.go
@@ -0,0 +1,368 @@
+package hyperv
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/prometheus-community/windows_exporter/internal/perfdata"
+ "github.com/prometheus-community/windows_exporter/internal/types"
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+// collectorVirtualMachineHealthSummary Hyper-V Virtual Switch Summary metrics
+type collectorVirtualSwitch struct {
+ perfDataCollectorVirtualSwitch *perfdata.Collector
+ virtualSwitchBroadcastPacketsReceived *prometheus.Desc // \Hyper-V Virtual Switch(*)\Broadcast Packets Received/sec
+ virtualSwitchBroadcastPacketsSent *prometheus.Desc // \Hyper-V Virtual Switch(*)\Broadcast Packets Sent/sec
+ virtualSwitchBytes *prometheus.Desc // \Hyper-V Virtual Switch(*)\Bytes/sec
+ virtualSwitchBytesReceived *prometheus.Desc // \Hyper-V Virtual Switch(*)\Bytes Received/sec
+ virtualSwitchBytesSent *prometheus.Desc // \Hyper-V Virtual Switch(*)\Bytes Sent/sec
+ virtualSwitchDirectedPacketsReceived *prometheus.Desc // \Hyper-V Virtual Switch(*)\Directed Packets Received/sec
+ virtualSwitchDirectedPacketsSent *prometheus.Desc // \Hyper-V Virtual Switch(*)\Directed Packets Sent/sec
+ virtualSwitchDroppedPacketsIncoming *prometheus.Desc // \Hyper-V Virtual Switch(*)\Dropped Packets Incoming/sec
+ virtualSwitchDroppedPacketsOutgoing *prometheus.Desc // \Hyper-V Virtual Switch(*)\Dropped Packets Outgoing/sec
+ virtualSwitchExtensionsDroppedPacketsIncoming *prometheus.Desc // \Hyper-V Virtual Switch(*)\Extensions Dropped Packets Incoming/sec
+ virtualSwitchExtensionsDroppedPacketsOutgoing *prometheus.Desc // \Hyper-V Virtual Switch(*)\Extensions Dropped Packets Outgoing/sec
+ virtualSwitchLearnedMacAddresses *prometheus.Desc // \Hyper-V Virtual Switch(*)\Learned Mac Addresses
+ virtualSwitchMulticastPacketsReceived *prometheus.Desc // \Hyper-V Virtual Switch(*)\Multicast Packets Received/sec
+ virtualSwitchMulticastPacketsSent *prometheus.Desc // \Hyper-V Virtual Switch(*)\Multicast Packets Sent/sec
+ virtualSwitchNumberOfSendChannelMoves *prometheus.Desc // \Hyper-V Virtual Switch(*)\Number of Send Channel Moves/sec
+ virtualSwitchNumberOfVMQMoves *prometheus.Desc // \Hyper-V Virtual Switch(*)\Number of VMQ Moves/sec
+ virtualSwitchPacketsFlooded *prometheus.Desc // \Hyper-V Virtual Switch(*)\Packets Flooded
+ virtualSwitchPackets *prometheus.Desc // \Hyper-V Virtual Switch(*)\Packets/sec
+ virtualSwitchPacketsReceived *prometheus.Desc // \Hyper-V Virtual Switch(*)\Packets Received/sec
+ virtualSwitchPacketsSent *prometheus.Desc // \Hyper-V Virtual Switch(*)\Packets Sent/sec
+ virtualSwitchPurgedMacAddresses *prometheus.Desc // \Hyper-V Virtual Switch(*)\Purged Mac Addresses
+}
+
+const (
+ virtualSwitchBroadcastPacketsReceived = "Broadcast Packets Received/sec"
+ virtualSwitchBroadcastPacketsSent = "Broadcast Packets Sent/sec"
+ virtualSwitchBytes = "Bytes/sec"
+ virtualSwitchBytesReceived = "Bytes Received/sec"
+ virtualSwitchBytesSent = "Bytes Sent/sec"
+ virtualSwitchDirectedPacketsReceived = "Directed Packets Received/sec"
+ virtualSwitchDirectedPacketsSent = "Directed Packets Sent/sec"
+ virtualSwitchDroppedPacketsIncoming = "Dropped Packets Incoming/sec"
+ virtualSwitchDroppedPacketsOutgoing = "Dropped Packets Outgoing/sec"
+ virtualSwitchExtensionsDroppedPacketsIncoming = "Extensions Dropped Packets Incoming/sec"
+ virtualSwitchExtensionsDroppedPacketsOutgoing = "Extensions Dropped Packets Outgoing/sec"
+ virtualSwitchLearnedMacAddresses = "Learned Mac Addresses"
+ virtualSwitchMulticastPacketsReceived = "Multicast Packets Received/sec"
+ virtualSwitchMulticastPacketsSent = "Multicast Packets Sent/sec"
+ virtualSwitchNumberOfSendChannelMoves = "Number of Send Channel Moves/sec"
+ virtualSwitchNumberOfVMQMoves = "Number of VMQ Moves/sec"
+ virtualSwitchPacketsFlooded = "Packets Flooded"
+ virtualSwitchPackets = "Packets/sec"
+ virtualSwitchPacketsReceived = "Packets Received/sec"
+ virtualSwitchPacketsSent = "Packets Sent/sec"
+ virtualSwitchPurgedMacAddresses = "Purged Mac Addresses"
+)
+
+func (c *Collector) buildVirtualSwitch() error {
+ var err error
+
+ c.perfDataCollectorVirtualSwitch, err = perfdata.NewCollector("Hyper-V Virtual Switch", perfdata.InstanceAll, []string{
+ virtualSwitchBroadcastPacketsReceived,
+ virtualSwitchBroadcastPacketsSent,
+ virtualSwitchBytes,
+ virtualSwitchBytesReceived,
+ virtualSwitchBytesSent,
+ virtualSwitchDirectedPacketsReceived,
+ virtualSwitchDirectedPacketsSent,
+ virtualSwitchDroppedPacketsIncoming,
+ virtualSwitchDroppedPacketsOutgoing,
+ virtualSwitchExtensionsDroppedPacketsIncoming,
+ virtualSwitchExtensionsDroppedPacketsOutgoing,
+ virtualSwitchLearnedMacAddresses,
+ virtualSwitchMulticastPacketsReceived,
+ virtualSwitchMulticastPacketsSent,
+ virtualSwitchNumberOfSendChannelMoves,
+ virtualSwitchNumberOfVMQMoves,
+ virtualSwitchPacketsFlooded,
+ virtualSwitchPackets,
+ virtualSwitchPacketsReceived,
+ virtualSwitchPacketsSent,
+ virtualSwitchPurgedMacAddresses,
+ })
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to create Hyper-V Virtual Switch collector: %w", err)
+ }
+
+ c.virtualSwitchBroadcastPacketsReceived = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_broadcast_packets_received_total"),
+ "Represents the total number of broadcast packets received per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchBroadcastPacketsSent = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_broadcast_packets_sent_total"),
+ "Represents the total number of broadcast packets sent per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchBytes = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_bytes_total"),
+ "Represents the total number of bytes per second traversing the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchBytesReceived = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_bytes_received_total"),
+ "Represents the total number of bytes received per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchBytesSent = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_bytes_sent_total"),
+ "Represents the total number of bytes sent per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchDirectedPacketsReceived = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_directed_packets_received_total"),
+ "Represents the total number of directed packets received per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchDirectedPacketsSent = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_directed_packets_send_total"),
+ "Represents the total number of directed packets sent per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchDroppedPacketsIncoming = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_dropped_packets_incoming_total"),
+ "Represents the total number of packet dropped per second by the virtual switch in the incoming direction",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchDroppedPacketsOutgoing = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_dropped_packets_outcoming_total"),
+ "Represents the total number of packet dropped per second by the virtual switch in the outgoing direction",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchExtensionsDroppedPacketsIncoming = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_extensions_dropped_packets_incoming_total"),
+ "Represents the total number of packet dropped per second by the virtual switch extensions in the incoming direction",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchExtensionsDroppedPacketsOutgoing = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_extensions_dropped_packets_outcoming_total"),
+ "Represents the total number of packet dropped per second by the virtual switch extensions in the outgoing direction",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchLearnedMacAddresses = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_learned_mac_addresses_total"),
+ "Represents the total number of learned MAC addresses of the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchMulticastPacketsReceived = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_multicast_packets_received_total"),
+ "Represents the total number of multicast packets received per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchMulticastPacketsSent = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_multicast_packets_sent_total"),
+ "Represents the total number of multicast packets sent per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchNumberOfSendChannelMoves = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_number_of_send_channel_moves_total"),
+ "Represents the total number of send channel moves per second on this virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchNumberOfVMQMoves = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_number_of_vmq_moves_total"),
+ "Represents the total number of VMQ moves per second on this virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchPacketsFlooded = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_packets_flooded_total"),
+ "Represents the total number of packets flooded by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchPackets = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_packets_total"),
+ "Represents the total number of packets per second traversing the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchPacketsReceived = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_packets_received_total"),
+ "Represents the total number of packets received per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchPacketsSent = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_packets_sent_total"),
+ "Represents the total number of packets send per second by the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+ c.virtualSwitchPurgedMacAddresses = prometheus.NewDesc(
+ prometheus.BuildFQName(types.Namespace, Name, "vswitch_purged_mac_addresses_total"),
+ "Represents the total number of purged MAC addresses of the virtual switch",
+ []string{"vswitch"},
+ nil,
+ )
+
+ return nil
+}
+
+func (c *Collector) collectVirtualSwitch(ch chan<- prometheus.Metric) error {
+ data, err := c.perfDataCollectorVirtualSwitch.Collect()
+ if err != nil && !errors.Is(err, perfdata.ErrNoData) {
+ return fmt.Errorf("failed to collect Hyper-V Virtual Switch metrics: %w", err)
+ }
+
+ for name, switchData := range data {
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchBroadcastPacketsReceived,
+ prometheus.CounterValue,
+ switchData[virtualSwitchBroadcastPacketsReceived].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchBroadcastPacketsSent,
+ prometheus.CounterValue,
+ switchData[virtualSwitchBroadcastPacketsSent].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchBytes,
+ prometheus.CounterValue,
+ switchData[virtualSwitchBytes].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchBytesReceived,
+ prometheus.CounterValue,
+ switchData[virtualSwitchBytesReceived].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchBytesSent,
+ prometheus.CounterValue,
+ switchData[virtualSwitchBytesSent].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchDirectedPacketsReceived,
+ prometheus.CounterValue,
+ switchData[virtualSwitchDirectedPacketsReceived].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchDirectedPacketsSent,
+ prometheus.CounterValue,
+ switchData[virtualSwitchDirectedPacketsSent].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchDroppedPacketsIncoming,
+ prometheus.CounterValue,
+ switchData[virtualSwitchDroppedPacketsIncoming].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchDroppedPacketsOutgoing,
+ prometheus.CounterValue,
+ switchData[virtualSwitchDroppedPacketsOutgoing].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchExtensionsDroppedPacketsIncoming,
+ prometheus.CounterValue,
+ switchData[virtualSwitchExtensionsDroppedPacketsIncoming].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchExtensionsDroppedPacketsOutgoing,
+ prometheus.CounterValue,
+ switchData[virtualSwitchExtensionsDroppedPacketsOutgoing].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchLearnedMacAddresses,
+ prometheus.CounterValue,
+ switchData[virtualSwitchLearnedMacAddresses].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchMulticastPacketsReceived,
+ prometheus.CounterValue,
+ switchData[virtualSwitchMulticastPacketsReceived].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchMulticastPacketsSent,
+ prometheus.CounterValue,
+ switchData[virtualSwitchMulticastPacketsSent].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchNumberOfSendChannelMoves,
+ prometheus.CounterValue,
+ switchData[virtualSwitchNumberOfSendChannelMoves].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchNumberOfVMQMoves,
+ prometheus.CounterValue,
+ switchData[virtualSwitchNumberOfVMQMoves].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchPacketsFlooded,
+ prometheus.CounterValue,
+ switchData[virtualSwitchPacketsFlooded].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchPackets,
+ prometheus.CounterValue,
+ switchData[virtualSwitchPackets].FirstValue,
+ name,
+ )
+
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchPacketsReceived,
+ prometheus.CounterValue,
+ switchData[virtualSwitchPacketsReceived].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchPacketsSent,
+ prometheus.CounterValue,
+ switchData[virtualSwitchPacketsSent].FirstValue,
+ name,
+ )
+ ch <- prometheus.MustNewConstMetric(
+ c.virtualSwitchPurgedMacAddresses,
+ prometheus.CounterValue,
+ switchData[virtualSwitchPurgedMacAddresses].FirstValue,
+ name,
+ )
+ }
+
+ return nil
+}
diff --git a/internal/collector/mscluster/mscluster.go b/internal/collector/mscluster/mscluster.go
index 887339f0..e531ee54 100644
--- a/internal/collector/mscluster/mscluster.go
+++ b/internal/collector/mscluster/mscluster.go
@@ -35,141 +35,11 @@ type Collector struct {
config Config
miSession *mi.Session
- // cluster
- clusterAddEvictDelay *prometheus.Desc
- clusterAdminAccessPoint *prometheus.Desc
- clusterAutoAssignNodeSite *prometheus.Desc
- clusterAutoBalancerLevel *prometheus.Desc
- clusterAutoBalancerMode *prometheus.Desc
- clusterBackupInProgress *prometheus.Desc
- clusterBlockCacheSize *prometheus.Desc
- clusterClusSvcHangTimeout *prometheus.Desc
- clusterClusSvcRegroupOpeningTimeout *prometheus.Desc
- clusterClusSvcRegroupPruningTimeout *prometheus.Desc
- clusterClusSvcRegroupStageTimeout *prometheus.Desc
- clusterClusSvcRegroupTickInMilliseconds *prometheus.Desc
- clusterClusterEnforcedAntiAffinity *prometheus.Desc
- clusterClusterFunctionalLevel *prometheus.Desc
- clusterClusterGroupWaitDelay *prometheus.Desc
- clusterClusterLogLevel *prometheus.Desc
- clusterClusterLogSize *prometheus.Desc
- clusterClusterUpgradeVersion *prometheus.Desc
- clusterCrossSiteDelay *prometheus.Desc
- clusterCrossSiteThreshold *prometheus.Desc
- clusterCrossSubnetDelay *prometheus.Desc
- clusterCrossSubnetThreshold *prometheus.Desc
- clusterCsvBalancer *prometheus.Desc
- clusterDatabaseReadWriteMode *prometheus.Desc
- clusterDefaultNetworkRole *prometheus.Desc
- clusterDetectedCloudPlatform *prometheus.Desc
- clusterDetectManagedEvents *prometheus.Desc
- clusterDetectManagedEventsThreshold *prometheus.Desc
- clusterDisableGroupPreferredOwnerRandomization *prometheus.Desc
- clusterDrainOnShutdown *prometheus.Desc
- clusterDynamicQuorumEnabled *prometheus.Desc
- clusterEnableSharedVolumes *prometheus.Desc
- clusterFixQuorum *prometheus.Desc
- clusterGracePeriodEnabled *prometheus.Desc
- clusterGracePeriodTimeout *prometheus.Desc
- clusterGroupDependencyTimeout *prometheus.Desc
- clusterHangRecoveryAction *prometheus.Desc
- clusterIgnorePersistentStateOnStartup *prometheus.Desc
- clusterLogResourceControls *prometheus.Desc
- clusterLowerQuorumPriorityNodeId *prometheus.Desc
- clusterMaxNumberOfNodes *prometheus.Desc
- clusterMessageBufferLength *prometheus.Desc
- clusterMinimumNeverPreemptPriority *prometheus.Desc
- clusterMinimumPreemptorPriority *prometheus.Desc
- clusterNetftIPSecEnabled *prometheus.Desc
- clusterPlacementOptions *prometheus.Desc
- clusterPlumbAllCrossSubnetRoutes *prometheus.Desc
- clusterPreventQuorum *prometheus.Desc
- clusterQuarantineDuration *prometheus.Desc
- clusterQuarantineThreshold *prometheus.Desc
- clusterQuorumArbitrationTimeMax *prometheus.Desc
- clusterQuorumArbitrationTimeMin *prometheus.Desc
- clusterQuorumLogFileSize *prometheus.Desc
- clusterQuorumTypeValue *prometheus.Desc
- clusterRequestReplyTimeout *prometheus.Desc
- clusterResiliencyDefaultPeriod *prometheus.Desc
- clusterResiliencyLevel *prometheus.Desc
- clusterResourceDllDeadlockPeriod *prometheus.Desc
- clusterRootMemoryReserved *prometheus.Desc
- clusterRouteHistoryLength *prometheus.Desc
- clusterS2DBusTypes *prometheus.Desc
- clusterS2DCacheDesiredState *prometheus.Desc
- clusterS2DCacheFlashReservePercent *prometheus.Desc
- clusterS2DCachePageSizeKBytes *prometheus.Desc
- clusterS2DEnabled *prometheus.Desc
- clusterS2DIOLatencyThreshold *prometheus.Desc
- clusterS2DOptimizations *prometheus.Desc
- clusterSameSubnetDelay *prometheus.Desc
- clusterSameSubnetThreshold *prometheus.Desc
- clusterSecurityLevel *prometheus.Desc
- clusterSecurityLevelForStorage *prometheus.Desc
- clusterSharedVolumeVssWriterOperationTimeout *prometheus.Desc
- clusterShutdownTimeoutInMinutes *prometheus.Desc
- clusterUseClientAccessNetworksForSharedVolumes *prometheus.Desc
- clusterWitnessDatabaseWriteTimeout *prometheus.Desc
- clusterWitnessDynamicWeight *prometheus.Desc
- clusterWitnessRestartInterval *prometheus.Desc
-
- // network
- networkCharacteristics *prometheus.Desc
- networkFlags *prometheus.Desc
- networkMetric *prometheus.Desc
- networkRole *prometheus.Desc
- networkState *prometheus.Desc
-
- // node
- nodeBuildNumber *prometheus.Desc
- nodeCharacteristics *prometheus.Desc
- nodeDetectedCloudPlatform *prometheus.Desc
- nodeDynamicWeight *prometheus.Desc
- nodeFlags *prometheus.Desc
- nodeMajorVersion *prometheus.Desc
- nodeMinorVersion *prometheus.Desc
- nodeNeedsPreventQuorum *prometheus.Desc
- nodeNodeDrainStatus *prometheus.Desc
- nodeNodeHighestVersion *prometheus.Desc
- nodeNodeLowestVersion *prometheus.Desc
- nodeNodeWeight *prometheus.Desc
- nodeState *prometheus.Desc
- nodeStatusInformation *prometheus.Desc
-
- resourceCharacteristics *prometheus.Desc
- resourceDeadlockTimeout *prometheus.Desc
- resourceEmbeddedFailureAction *prometheus.Desc
- resourceFlags *prometheus.Desc
- resourceIsAlivePollInterval *prometheus.Desc
- resourceLooksAlivePollInterval *prometheus.Desc
- resourceMonitorProcessId *prometheus.Desc
- resourceOwnerNode *prometheus.Desc
- resourcePendingTimeout *prometheus.Desc
- resourceResourceClass *prometheus.Desc
- resourceRestartAction *prometheus.Desc
- resourceRestartDelay *prometheus.Desc
- resourceRestartPeriod *prometheus.Desc
- resourceRestartThreshold *prometheus.Desc
- resourceRetryPeriodOnFailure *prometheus.Desc
- resourceState *prometheus.Desc
- resourceSubClass *prometheus.Desc
-
- // ResourceGroup
- resourceGroupAutoFailbackType *prometheus.Desc
- resourceGroupCharacteristics *prometheus.Desc
- resourceGroupColdStartSetting *prometheus.Desc
- resourceGroupDefaultOwner *prometheus.Desc
- resourceGroupFailbackWindowEnd *prometheus.Desc
- resourceGroupFailbackWindowStart *prometheus.Desc
- resourceGroupFailOverPeriod *prometheus.Desc
- resourceGroupFailOverThreshold *prometheus.Desc
- resourceGroupFlags *prometheus.Desc
- resourceGroupGroupType *prometheus.Desc
- resourceGroupOwnerNode *prometheus.Desc
- resourceGroupPriority *prometheus.Desc
- resourceGroupResiliencyPeriod *prometheus.Desc
- resourceGroupState *prometheus.Desc
+ collectorCluster
+ collectorNetwork
+ collectorNode
+ collectorResource
+ collectorResourceGroup
}
func New(config *Config) *Collector {
diff --git a/internal/collector/mscluster/mscluster_cluster.go b/internal/collector/mscluster/mscluster_cluster.go
index 056bb72a..d6651d02 100644
--- a/internal/collector/mscluster/mscluster_cluster.go
+++ b/internal/collector/mscluster/mscluster_cluster.go
@@ -13,6 +13,86 @@ import (
const nameCluster = Name + "_cluster"
+type collectorCluster struct {
+ clusterAddEvictDelay *prometheus.Desc
+ clusterAdminAccessPoint *prometheus.Desc
+ clusterAutoAssignNodeSite *prometheus.Desc
+ clusterAutoBalancerLevel *prometheus.Desc
+ clusterAutoBalancerMode *prometheus.Desc
+ clusterBackupInProgress *prometheus.Desc
+ clusterBlockCacheSize *prometheus.Desc
+ clusterClusSvcHangTimeout *prometheus.Desc
+ clusterClusSvcRegroupOpeningTimeout *prometheus.Desc
+ clusterClusSvcRegroupPruningTimeout *prometheus.Desc
+ clusterClusSvcRegroupStageTimeout *prometheus.Desc
+ clusterClusSvcRegroupTickInMilliseconds *prometheus.Desc
+ clusterClusterEnforcedAntiAffinity *prometheus.Desc
+ clusterClusterFunctionalLevel *prometheus.Desc
+ clusterClusterGroupWaitDelay *prometheus.Desc
+ clusterClusterLogLevel *prometheus.Desc
+ clusterClusterLogSize *prometheus.Desc
+ clusterClusterUpgradeVersion *prometheus.Desc
+ clusterCrossSiteDelay *prometheus.Desc
+ clusterCrossSiteThreshold *prometheus.Desc
+ clusterCrossSubnetDelay *prometheus.Desc
+ clusterCrossSubnetThreshold *prometheus.Desc
+ clusterCsvBalancer *prometheus.Desc
+ clusterDatabaseReadWriteMode *prometheus.Desc
+ clusterDefaultNetworkRole *prometheus.Desc
+ clusterDetectedCloudPlatform *prometheus.Desc
+ clusterDetectManagedEvents *prometheus.Desc
+ clusterDetectManagedEventsThreshold *prometheus.Desc
+ clusterDisableGroupPreferredOwnerRandomization *prometheus.Desc
+ clusterDrainOnShutdown *prometheus.Desc
+ clusterDynamicQuorumEnabled *prometheus.Desc
+ clusterEnableSharedVolumes *prometheus.Desc
+ clusterFixQuorum *prometheus.Desc
+ clusterGracePeriodEnabled *prometheus.Desc
+ clusterGracePeriodTimeout *prometheus.Desc
+ clusterGroupDependencyTimeout *prometheus.Desc
+ clusterHangRecoveryAction *prometheus.Desc
+ clusterIgnorePersistentStateOnStartup *prometheus.Desc
+ clusterLogResourceControls *prometheus.Desc
+ clusterLowerQuorumPriorityNodeId *prometheus.Desc
+ clusterMaxNumberOfNodes *prometheus.Desc
+ clusterMessageBufferLength *prometheus.Desc
+ clusterMinimumNeverPreemptPriority *prometheus.Desc
+ clusterMinimumPreemptorPriority *prometheus.Desc
+ clusterNetftIPSecEnabled *prometheus.Desc
+ clusterPlacementOptions *prometheus.Desc
+ clusterPlumbAllCrossSubnetRoutes *prometheus.Desc
+ clusterPreventQuorum *prometheus.Desc
+ clusterQuarantineDuration *prometheus.Desc
+ clusterQuarantineThreshold *prometheus.Desc
+ clusterQuorumArbitrationTimeMax *prometheus.Desc
+ clusterQuorumArbitrationTimeMin *prometheus.Desc
+ clusterQuorumLogFileSize *prometheus.Desc
+ clusterQuorumTypeValue *prometheus.Desc
+ clusterRequestReplyTimeout *prometheus.Desc
+ clusterResiliencyDefaultPeriod *prometheus.Desc
+ clusterResiliencyLevel *prometheus.Desc
+ clusterResourceDllDeadlockPeriod *prometheus.Desc
+ clusterRootMemoryReserved *prometheus.Desc
+ clusterRouteHistoryLength *prometheus.Desc
+ clusterS2DBusTypes *prometheus.Desc
+ clusterS2DCacheDesiredState *prometheus.Desc
+ clusterS2DCacheFlashReservePercent *prometheus.Desc
+ clusterS2DCachePageSizeKBytes *prometheus.Desc
+ clusterS2DEnabled *prometheus.Desc
+ clusterS2DIOLatencyThreshold *prometheus.Desc
+ clusterS2DOptimizations *prometheus.Desc
+ clusterSameSubnetDelay *prometheus.Desc
+ clusterSameSubnetThreshold *prometheus.Desc
+ clusterSecurityLevel *prometheus.Desc
+ clusterSecurityLevelForStorage *prometheus.Desc
+ clusterSharedVolumeVssWriterOperationTimeout *prometheus.Desc
+ clusterShutdownTimeoutInMinutes *prometheus.Desc
+ clusterUseClientAccessNetworksForSharedVolumes *prometheus.Desc
+ clusterWitnessDatabaseWriteTimeout *prometheus.Desc
+ clusterWitnessDynamicWeight *prometheus.Desc
+ clusterWitnessRestartInterval *prometheus.Desc
+}
+
// msClusterCluster represents the MSCluster_Cluster WMI class
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-cluster
type msClusterCluster struct {
diff --git a/internal/collector/mscluster/mscluster_network.go b/internal/collector/mscluster/mscluster_network.go
index fefba789..a62d78c5 100644
--- a/internal/collector/mscluster/mscluster_network.go
+++ b/internal/collector/mscluster/mscluster_network.go
@@ -13,6 +13,14 @@ import (
const nameNetwork = Name + "_network"
+type collectorNetwork struct {
+ networkCharacteristics *prometheus.Desc
+ networkFlags *prometheus.Desc
+ networkMetric *prometheus.Desc
+ networkRole *prometheus.Desc
+ networkState *prometheus.Desc
+}
+
// msClusterNetwork represents the MSCluster_Network WMI class
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-network
type msClusterNetwork struct {
diff --git a/internal/collector/mscluster/mscluster_node.go b/internal/collector/mscluster/mscluster_node.go
index 58b4e26a..7a32cf0b 100644
--- a/internal/collector/mscluster/mscluster_node.go
+++ b/internal/collector/mscluster/mscluster_node.go
@@ -13,6 +13,23 @@ import (
const nameNode = Name + "_node"
+type collectorNode struct {
+ nodeBuildNumber *prometheus.Desc
+ nodeCharacteristics *prometheus.Desc
+ nodeDetectedCloudPlatform *prometheus.Desc
+ nodeDynamicWeight *prometheus.Desc
+ nodeFlags *prometheus.Desc
+ nodeMajorVersion *prometheus.Desc
+ nodeMinorVersion *prometheus.Desc
+ nodeNeedsPreventQuorum *prometheus.Desc
+ nodeNodeDrainStatus *prometheus.Desc
+ nodeNodeHighestVersion *prometheus.Desc
+ nodeNodeLowestVersion *prometheus.Desc
+ nodeNodeWeight *prometheus.Desc
+ nodeState *prometheus.Desc
+ nodeStatusInformation *prometheus.Desc
+}
+
// msClusterNode represents the MSCluster_Node WMI class
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-node
type msClusterNode struct {
diff --git a/internal/collector/mscluster/mscluster_resource.go b/internal/collector/mscluster/mscluster_resource.go
index 34706aee..2c683955 100644
--- a/internal/collector/mscluster/mscluster_resource.go
+++ b/internal/collector/mscluster/mscluster_resource.go
@@ -13,6 +13,26 @@ import (
const nameResource = Name + "_resource"
+type collectorResource struct {
+ resourceCharacteristics *prometheus.Desc
+ resourceDeadlockTimeout *prometheus.Desc
+ resourceEmbeddedFailureAction *prometheus.Desc
+ resourceFlags *prometheus.Desc
+ resourceIsAlivePollInterval *prometheus.Desc
+ resourceLooksAlivePollInterval *prometheus.Desc
+ resourceMonitorProcessId *prometheus.Desc
+ resourceOwnerNode *prometheus.Desc
+ resourcePendingTimeout *prometheus.Desc
+ resourceResourceClass *prometheus.Desc
+ resourceRestartAction *prometheus.Desc
+ resourceRestartDelay *prometheus.Desc
+ resourceRestartPeriod *prometheus.Desc
+ resourceRestartThreshold *prometheus.Desc
+ resourceRetryPeriodOnFailure *prometheus.Desc
+ resourceState *prometheus.Desc
+ resourceSubClass *prometheus.Desc
+}
+
// msClusterResource represents the MSCluster_Resource WMI class
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resource
type msClusterResource struct {
diff --git a/internal/collector/mscluster/mscluster_resourcegroup.go b/internal/collector/mscluster/mscluster_resourcegroup.go
index 05ff4d95..7fb66f17 100644
--- a/internal/collector/mscluster/mscluster_resourcegroup.go
+++ b/internal/collector/mscluster/mscluster_resourcegroup.go
@@ -13,6 +13,23 @@ import (
const nameResourceGroup = Name + "_resourcegroup"
+type collectorResourceGroup struct {
+ resourceGroupAutoFailbackType *prometheus.Desc
+ resourceGroupCharacteristics *prometheus.Desc
+ resourceGroupColdStartSetting *prometheus.Desc
+ resourceGroupDefaultOwner *prometheus.Desc
+ resourceGroupFailbackWindowEnd *prometheus.Desc
+ resourceGroupFailbackWindowStart *prometheus.Desc
+ resourceGroupFailOverPeriod *prometheus.Desc
+ resourceGroupFailOverThreshold *prometheus.Desc
+ resourceGroupFlags *prometheus.Desc
+ resourceGroupGroupType *prometheus.Desc
+ resourceGroupOwnerNode *prometheus.Desc
+ resourceGroupPriority *prometheus.Desc
+ resourceGroupResiliencyPeriod *prometheus.Desc
+ resourceGroupState *prometheus.Desc
+}
+
// msClusterResourceGroup represents the MSCluster_ResourceGroup WMI class
// - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cluswmi/mscluster-resourcegroup
type msClusterResourceGroup struct {
diff --git a/internal/perfdata/collector.go b/internal/perfdata/collector.go
index 0800854c..5f5d69b6 100644
--- a/internal/perfdata/collector.go
+++ b/internal/perfdata/collector.go
@@ -112,7 +112,7 @@ func NewCollector(object string, instances []string, counters []string) (*Collec
}
if _, err := collector.Collect(); err != nil {
- return nil, fmt.Errorf("failed to collect initial data: %w", err)
+ return collector, fmt.Errorf("failed to collect initial data: %w", err)
}
return collector, nil
diff --git a/internal/perfdata/error.go b/internal/perfdata/error.go
index f7a03ca2..3418344a 100644
--- a/internal/perfdata/error.go
+++ b/internal/perfdata/error.go
@@ -4,6 +4,8 @@ package perfdata
import "errors"
+var ErrNoData = NewPdhError(PdhNoData)
+
// Error represents error returned from Performance Counters API.
type Error struct {
ErrorCode uint32
diff --git a/internal/utils/utils.go b/internal/utils/utils.go
index 44401798..b9085df0 100644
--- a/internal/utils/utils.go
+++ b/internal/utils/utils.go
@@ -22,6 +22,10 @@ func ToPTR[t any](v t) *t {
return &v
}
+func PercentageToRatio(percentage float64) float64 {
+ return percentage / 100
+}
+
// Must panics if the error is not nil.
//
//nolint:ireturn