mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 10:09:05 +02:00
hyperv: label unnamed dynamic memory VMs as (unknown) (#2653)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
2b21e74f0e
commit
025359921e
@@ -86,17 +86,21 @@ Some metrics explained: https://learn.microsoft.com/en-us/archive/blogs/chrisavi
|
||||
|
||||
| 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_added_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_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_physical_bytes` | 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` |
|
||||
|
||||
Windows reports no instance name for VMs managed by the Host Compute Service, such as the WSL 2 VM.
|
||||
The first such VM has `vm="(unknown)"`, further ones `vm="(unknown)#1"`, `vm="(unknown)#2"` and so on.
|
||||
The suffix only keeps the series unique and does not identify the VM across scrapes.
|
||||
|
||||
### Hyper-V Host
|
||||
|
||||
Metrics about the host's CPU allocation. Processor counts per virtual machine are
|
||||
|
||||
@@ -19,6 +19,7 @@ package hyperv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/osversion"
|
||||
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
||||
@@ -88,7 +89,7 @@ func (c *Collector) buildDynamicMemoryVM() error {
|
||||
)
|
||||
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.'",
|
||||
"Represents the amount of memory visible in the VM.",
|
||||
[]string{"vm"},
|
||||
nil,
|
||||
)
|
||||
@@ -139,18 +140,20 @@ func (c *Collector) collectDynamicMemoryVM(ch chan<- prometheus.Metric) error {
|
||||
}
|
||||
|
||||
for _, data := range c.perfDataObjectDynamicMemoryVM {
|
||||
vmName := dynamicMemoryVMName(data.Name)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.vmMemoryAddedMemory,
|
||||
prometheus.CounterValue,
|
||||
utils.MBToBytes(data.VmMemoryAddedMemory),
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.vmMemoryCurrentPressure,
|
||||
prometheus.GaugeValue,
|
||||
utils.PercentageToRatio(data.VmMemoryCurrentPressure),
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
|
||||
if osversion.Build() >= osversion.LTSC2022 {
|
||||
@@ -158,7 +161,7 @@ func (c *Collector) collectDynamicMemoryVM(ch chan<- prometheus.Metric) error {
|
||||
c.vmMemoryGuestAvailableMemory,
|
||||
prometheus.GaugeValue,
|
||||
utils.MBToBytes(data.VmMemoryGuestAvailableMemory),
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -166,51 +169,72 @@ func (c *Collector) collectDynamicMemoryVM(ch chan<- prometheus.Metric) error {
|
||||
c.vmMemoryGuestVisiblePhysicalMemory,
|
||||
prometheus.GaugeValue,
|
||||
utils.MBToBytes(data.VmMemoryGuestVisiblePhysicalMemory),
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.vmMemoryMaximumPressure,
|
||||
prometheus.GaugeValue,
|
||||
utils.PercentageToRatio(data.VmMemoryMaximumPressure),
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.vmMemoryMemoryAddOperations,
|
||||
prometheus.CounterValue,
|
||||
data.VmMemoryMemoryAddOperations,
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.vmMemoryMemoryRemoveOperations,
|
||||
prometheus.CounterValue,
|
||||
data.VmMemoryMemoryRemoveOperations,
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.vmMemoryMinimumPressure,
|
||||
prometheus.GaugeValue,
|
||||
utils.PercentageToRatio(data.VmMemoryMinimumPressure),
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.vmMemoryPhysicalMemory,
|
||||
prometheus.GaugeValue,
|
||||
utils.MBToBytes(data.VmMemoryPhysicalMemory),
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.vmMemoryRemovedMemory,
|
||||
prometheus.CounterValue,
|
||||
utils.MBToBytes(data.VmMemoryRemovedMemory),
|
||||
data.Name,
|
||||
vmName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// vmUnknown is the vm label value for Hyper-V Dynamic Memory VM instances
|
||||
// without a name.
|
||||
const vmUnknown = "(unknown)"
|
||||
|
||||
// dynamicMemoryVMName returns the vm label value for a Hyper-V Dynamic Memory VM
|
||||
// instance. Windows reports an empty instance name for VMs managed by the Host
|
||||
// Compute Service, e.g. WSL 2, which pdh exposes as
|
||||
// pdh.InstanceEmpty. The occurrence suffix of duplicates is kept, so the
|
||||
// series stay unique.
|
||||
func dynamicMemoryVMName(name string) string {
|
||||
if name == pdh.InstanceEmpty {
|
||||
return vmUnknown
|
||||
}
|
||||
|
||||
if suffix, ok := strings.CutPrefix(name, pdh.InstanceEmpty+"#"); ok {
|
||||
return vmUnknown + "#" + suffix
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// Copyright The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build windows
|
||||
|
||||
package hyperv
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDynamicMemoryVMName(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for name, want := range map[string]string{
|
||||
pdh.InstanceEmpty: "(unknown)",
|
||||
pdh.InstanceEmpty + "#1": "(unknown)#1",
|
||||
pdh.InstanceEmpty + "#12": "(unknown)#12",
|
||||
"GitHubActions": "GitHubActions",
|
||||
"GitHubActions#1": "GitHubActions#1",
|
||||
"vm-------": "vm-------",
|
||||
} {
|
||||
require.Equal(t, want, dynamicMemoryVMName(name), name)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user