mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 10:09:05 +02:00
hyperv: label replica relationships with the VM ID (#2747)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
+14
-13
@@ -206,22 +206,23 @@ Sub-collector `replica_vm`, enabled by default. The performance counter metrics
|
||||
The `health` and `state` metrics come from the `Msvm_ReplicationRelationship` WMI class in the
|
||||
`root/virtualization/v2` namespace and exist for every virtual machine, including those without replication.
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------------|---------------------------------------------------------------------|---------|----------------------|
|
||||
| `windows_hyperv_replica_vm_average_replication_latency_seconds` | The average time taken to replicate the virtual machine | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_average_replication_size_bytes` | The average size of the replicated data | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_compression_efficiency` | The compression efficiency of the replicated data | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_last_replication_size_bytes` | The size of the last replicated data | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_network_received_bytes_total` | The total number of bytes received over the network for replication | counter | `vm` |
|
||||
| `windows_hyperv_replica_vm_network_sent_bytes_total` | The total number of bytes sent over the network for replication | counter | `vm` |
|
||||
| `windows_hyperv_replica_vm_replications_total` | The total number of replication cycles | counter | `vm` |
|
||||
| `windows_hyperv_replica_vm_replication_latency_seconds` | The time taken by the last replication of the virtual machine | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_resynchronized_bytes_total` | The total number of bytes sent during resynchronization | counter | `vm` |
|
||||
| `windows_hyperv_replica_vm_health` | The replication health of the virtual machine, see below | gauge | `vm`, `relationship` |
|
||||
| `windows_hyperv_replica_vm_state` | The replication state of the virtual machine, see below | gauge | `vm`, `relationship` |
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------------|---------------------------------------------------------------------|---------|-------------------------------|
|
||||
| `windows_hyperv_replica_vm_average_replication_latency_seconds` | The average time taken to replicate the virtual machine | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_average_replication_size_bytes` | The average size of the replicated data | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_compression_efficiency` | The compression efficiency of the replicated data | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_last_replication_size_bytes` | The size of the last replicated data | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_network_received_bytes_total` | The total number of bytes received over the network for replication | counter | `vm` |
|
||||
| `windows_hyperv_replica_vm_network_sent_bytes_total` | The total number of bytes sent over the network for replication | counter | `vm` |
|
||||
| `windows_hyperv_replica_vm_replications_total` | The total number of replication cycles | counter | `vm` |
|
||||
| `windows_hyperv_replica_vm_replication_latency_seconds` | The time taken by the last replication of the virtual machine | gauge | `vm` |
|
||||
| `windows_hyperv_replica_vm_resynchronized_bytes_total` | The total number of bytes sent during resynchronization | counter | `vm` |
|
||||
| `windows_hyperv_replica_vm_health` | The replication health of the virtual machine, see below | gauge | `vm`, `vm_id`, `relationship` |
|
||||
| `windows_hyperv_replica_vm_state` | The replication state of the virtual machine, see below | gauge | `vm`, `vm_id`, `relationship` |
|
||||
|
||||
The `relationship` label is `primary` for the primary replication relationship and `extended` for
|
||||
[extended replication](https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-replicationrelationship).
|
||||
The `vm_id` label is the ID of the virtual machine, which keeps virtual machines with the same name apart.
|
||||
|
||||
Values of `windows_hyperv_replica_vm_health`:
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ func (c *Collector) buildReplicaVM() error {
|
||||
c.replicaVMHealth = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "replica_vm_health"),
|
||||
"The replication health of the virtual machine. 0: Not applicable; 1: OK; 2: Warning; 3: Critical",
|
||||
[]string{"vm", "relationship"},
|
||||
[]string{"vm", "vm_id", "relationship"},
|
||||
nil,
|
||||
)
|
||||
c.replicaVMState = prometheus.NewDesc(
|
||||
@@ -172,7 +172,7 @@ func (c *Collector) buildReplicaVM() error {
|
||||
"13: Failback in progress; 14: Failback complete; 15: Disk update in progress; 16: Disk update critical; 17: Unknown; "+
|
||||
"18: Repurpose replication in progress; 19: Prepared for sync replication; 20: Prepared for group reverse replication; "+
|
||||
"21: Fire drill in progress",
|
||||
[]string{"vm", "relationship"},
|
||||
[]string{"vm", "vm_id", "relationship"},
|
||||
nil,
|
||||
)
|
||||
|
||||
@@ -280,13 +280,14 @@ func (c *Collector) collectReplicaVMRelationships(ch chan<- prometheus.Metric, s
|
||||
}
|
||||
|
||||
for _, relationship := range dst {
|
||||
relationshipType := replicationRelationshipType(relationship.InstanceID)
|
||||
vmID, relationshipType := parseReplicationRelationshipID(relationship.InstanceID)
|
||||
|
||||
ch <- scrape.MustNewConstMetric(
|
||||
c.replicaVMHealth,
|
||||
prometheus.GaugeValue,
|
||||
float64(relationship.ReplicationHealth),
|
||||
relationship.ElementName,
|
||||
vmID,
|
||||
relationshipType,
|
||||
)
|
||||
|
||||
@@ -295,6 +296,7 @@ func (c *Collector) collectReplicaVMRelationships(ch chan<- prometheus.Metric, s
|
||||
prometheus.GaugeValue,
|
||||
float64(relationship.ReplicationState),
|
||||
relationship.ElementName,
|
||||
vmID,
|
||||
relationshipType,
|
||||
)
|
||||
}
|
||||
@@ -302,16 +304,23 @@ func (c *Collector) collectReplicaVMRelationships(ch chan<- prometheus.Metric, s
|
||||
return nil
|
||||
}
|
||||
|
||||
// replicationRelationshipType returns the relationship type encoded in the
|
||||
// InstanceID ("Microsoft:<vm id>\HVR\<0|1>"). 0 is the primary relationship,
|
||||
// 1 the extended replication.
|
||||
func replicationRelationshipType(instanceID string) string {
|
||||
// parseReplicationRelationshipID returns the ID of the virtual machine and the
|
||||
// relationship type encoded in the InstanceID of a replication relationship
|
||||
// ("Microsoft:<vm id>\HVR\<0|1>"). The VM ID keeps the series of VMs with the
|
||||
// same name apart. Relationship 0 is the primary relationship, 1 the extended
|
||||
// replication.
|
||||
func parseReplicationRelationshipID(instanceID string) (string, string) {
|
||||
vmID := strings.TrimPrefix(instanceID, "Microsoft:")
|
||||
if i := strings.Index(vmID, `\`); i >= 0 {
|
||||
vmID = vmID[:i]
|
||||
}
|
||||
|
||||
switch instanceID[strings.LastIndex(instanceID, `\`)+1:] {
|
||||
case "0":
|
||||
return "primary"
|
||||
return vmID, "primary"
|
||||
case "1":
|
||||
return "extended"
|
||||
return vmID, "extended"
|
||||
default:
|
||||
return "unknown"
|
||||
return vmID, "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParseReplicationRelationshipID(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, tc := range []struct {
|
||||
instanceID string
|
||||
vmID string
|
||||
relationshipType string
|
||||
}{
|
||||
{`Microsoft:6B1F2E1A-3C4D-4E5F-8A9B-0C1D2E3F4A5B\HVR\0`, "6B1F2E1A-3C4D-4E5F-8A9B-0C1D2E3F4A5B", "primary"},
|
||||
{`Microsoft:6B1F2E1A-3C4D-4E5F-8A9B-0C1D2E3F4A5B\HVR\1`, "6B1F2E1A-3C4D-4E5F-8A9B-0C1D2E3F4A5B", "extended"},
|
||||
{`Microsoft:6B1F2E1A-3C4D-4E5F-8A9B-0C1D2E3F4A5B\HVR\2`, "6B1F2E1A-3C4D-4E5F-8A9B-0C1D2E3F4A5B", "unknown"},
|
||||
{`unexpected`, "unexpected", "unknown"},
|
||||
{``, "", "unknown"},
|
||||
} {
|
||||
t.Run(tc.instanceID, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
vmID, relationshipType := parseReplicationRelationshipID(tc.instanceID)
|
||||
require.Equal(t, tc.vmID, vmID)
|
||||
require.Equal(t, tc.relationshipType, relationshipType)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,9 @@ func TestCollector(t *testing.T) {
|
||||
// The fixture VM is not replicated, but every VM has a primary replication relationship.
|
||||
if metric := testutils.RequireFixtureMetric(t, metrics, hyperv.Name, "windows_hyperv_replica_vm_state", prometheus.Labels{"vm": "GitHubActions", "relationship": "primary"}); metric != nil {
|
||||
require.InDelta(t, 0, metric.GetGauge().GetValue(), 0, "expected replication to be disabled")
|
||||
|
||||
// vm_id keeps VMs with the same name apart; it is the VM's GUID.
|
||||
require.Regexp(t, `^[0-9A-Fa-f-]{36}$`, labelValue(metric, "vm_id"))
|
||||
}
|
||||
|
||||
// The health query reports failures as 0 instead of an error, so check the value.
|
||||
|
||||
Reference in New Issue
Block a user