Skip to content

Commit

Permalink
Expose CPU affinity metric
Browse files Browse the repository at this point in the history
This patch introduces the kubevirt_vmi_cpu_affinity metric which
displays the cpu pinning map via boolean labels in the form of
vcpu_X_cpu_Y.

Signed-off-by: Yuval Turgeman <yturgema@redhat.com>
  • Loading branch information
Yuval Turgeman committed Mar 17, 2021
1 parent 74bf53d commit d5b1ce5
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 2 deletions.
6 changes: 5 additions & 1 deletion docs/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ A design proposal and its implementation history can be seen [here](https://docs
## kubevirt_vmi_network_transmit_packets_total
#### HELP kubevirt_vmi_network_transmit_packets_total Network traffic transmit packets

# Other Metrics
# Other Metrics
## kubevirt_vmi_memory_actual_balloon_bytes
#### HELP kubevirt_vmi_memory_actual_balloon_bytes current balloon bytes.
## kubevirt_vmi_memory_pgmajfault
Expand All @@ -170,3 +170,7 @@ A design proposal and its implementation history can be seen [here](https://docs
#### HELP kubevirt_vmi_memory_usable_bytes The amount of memory which can be reclaimed by balloon without causing host swapping in bytes.
## kubevirt_vmi_memory_used_total_bytes
#### HELP kubevirt_vmi_memory_used_total_bytes The amount of memory in bytes used by the domain.

# Other Metrics
## kubevirt_vmi_cpu_affinity
#### HELP kubevirt_vmi_cpu_affinity vcpu affinity details
1 change: 1 addition & 0 deletions pkg/monitoring/vms/prometheus/fakeCollector.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func (fc fakeCollector) Collect(ch chan<- prometheus.Metric) {
out.Memory.UsableSet = true
out.Memory.MinorFaultSet = true
out.Memory.MajorFaultSet = true
out.CPUMapSet = true

vmi := k6tv1.VirtualMachineInstance{
Status: k6tv1.VirtualMachineInstanceStatus{
Expand Down
24 changes: 24 additions & 0 deletions pkg/monitoring/vms/prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,26 @@ func (metrics *vmiMetrics) updateMemory(mem *stats.DomainStatsMemory) {
}
}

func (metrics *vmiMetrics) updateCPUAffinity(cpuMap [][]bool) {
affinityLabels := []string{}
affinityValues := []string{}

for vidx := 0; vidx < len(cpuMap); vidx++ {
for cidx := 0; cidx < len(cpuMap[vidx]); cidx++ {
affinityLabels = append(affinityLabels, fmt.Sprintf("vcpu_%v_cpu_%v", vidx, cidx))
affinityValues = append(affinityValues, fmt.Sprintf("%t", cpuMap[vidx][cidx]))
}
}

metrics.pushCustomMetric(
"kubevirt_vmi_cpu_affinity",
"vcpu affinity details",
prometheus.CounterValue, 1,
affinityLabels,
affinityValues,
)
}

func (metrics *vmiMetrics) updateVcpu(vcpuStats []stats.DomainStatsVcpu) {
for vcpuIdx, vcpu := range vcpuStats {
stringVcpuIdx := fmt.Sprintf("%d", vcpuIdx)
Expand Down Expand Up @@ -585,6 +605,10 @@ func (metrics *vmiMetrics) updateMetrics(vmStats *stats.DomainStats) {
metrics.updateVcpu(vmStats.Vcpu)
metrics.updateBlock(vmStats.Block)
metrics.updateNetwork(vmStats.Net)

if vmStats.CPUMapSet {
metrics.updateCPUAffinity(vmStats.CPUMap)
}
}

func (metrics *vmiMetrics) newPrometheusDesc(name string, help string, customLabels []string) *prometheus.Desc {
Expand Down
35 changes: 35 additions & 0 deletions pkg/monitoring/vms/prometheus/prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
package prometheus

import (
"fmt"

"github.com/prometheus/client_golang/prometheus"
io_prometheus_client "github.com/prometheus/client_model/go"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -932,6 +934,39 @@ var _ = Describe("Prometheus", func() {
Expect(result).ToNot(BeNil())
Expect(result.Desc().String()).To(ContainSubstring("kubevirt_vmi_vcpu_wait_seconds"))
})

It("should expose vcpu to cpu pinning metric", func() {
ch := make(chan prometheus.Metric, 1)
defer close(ch)

ps := prometheusScraper{ch: ch}

vmStats := &stats.DomainStats{
Cpu: &stats.DomainStatsCPU{},
Memory: &stats.DomainStatsMemory{},
Net: []stats.DomainStatsNet{},
Vcpu: []stats.DomainStatsVcpu{},
CPUMapSet: true,
CPUMap: [][]bool{{true, false, true}},
}

vmi := k6tv1.VirtualMachineInstance{}
ps.Report("test", &vmi, vmStats)

result := <-ch
dto := &io_prometheus_client.Metric{}
result.Write(dto)

Expect(result).ToNot(BeNil())
Expect(result.Desc().String()).To(ContainSubstring("kubevirt_vmi_cpu_affinity"))
s := ""
for _, lp := range dto.GetLabel() {
s += fmt.Sprintf("%v=%v ", lp.GetName(), lp.GetValue())
}
Expect(s).To(ContainSubstring("vcpu_0_cpu_0=true"))
Expect(s).To(ContainSubstring("vcpu_0_cpu_1=false"))
Expect(s).To(ContainSubstring("vcpu_0_cpu_2=true"))
})
})
})

Expand Down
8 changes: 8 additions & 0 deletions pkg/virt-launcher/virtwrap/cli/libvirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,14 @@ func (l *LibvirtConnection) GetDomainStats(statsTypes libvirt.DomainStatsTypes,
return list, err
}

cpuMap, err := domStat.Domain.GetVcpuPinInfo(libvirt.DOMAIN_AFFECT_CURRENT)
if err != nil {
return list, err
}

stat.CPUMap = cpuMap
stat.CPUMapSet = true

list = append(list, stat)
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/virt-launcher/virtwrap/stats/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ type DomainStats struct {
Net []DomainStatsNet
Block []DomainStatsBlock
// omitted from libvirt-go: Perf
// extra stats
CPUMapSet bool
CPUMap [][]bool
}

type DomainStatsCPU struct {
Expand Down
4 changes: 3 additions & 1 deletion pkg/virt-launcher/virtwrap/statsconv/util/domstats_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,9 @@ var Testdataexpected = `{
"WaitSet": true,
"Wait": 1500
}
]
],
"CPUMapSet": false,
"CPUMap": null
}`

func LoadStats() ([]libvirt.DomainStats, error) {
Expand Down

0 comments on commit d5b1ce5

Please sign in to comment.