From 9534dfa1bfa73a31ee91896324e21035ee35616e Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Mon, 5 May 2025 16:55:36 +0300 Subject: [PATCH 01/21] capture extra vsphere metrics (cpu %, disk average, disk rate, disk number, memory usage %) --- .../module/vsphere/client/performance.go | 101 ++++++++++++++++++ metricbeat/module/vsphere/host/host.go | 72 +------------ .../module/vsphere/virtualmachine/data.go | 21 ++++ .../vsphere/virtualmachine/virtualmachine.go | 33 ++++++ 4 files changed, 157 insertions(+), 70 deletions(-) create mode 100644 metricbeat/module/vsphere/client/performance.go diff --git a/metricbeat/module/vsphere/client/performance.go b/metricbeat/module/vsphere/client/performance.go new file mode 100644 index 000000000000..9bc6c28ca5b6 --- /dev/null +++ b/metricbeat/module/vsphere/client/performance.go @@ -0,0 +1,101 @@ +package client + +import ( + "context" + "fmt" + "strings" + + "github.com/elastic/elastic-agent-libs/logp" + "github.com/vmware/govmomi/performance" + "github.com/vmware/govmomi/vim25/types" +) + +type PerformanceDataFetcher struct { + perfManager *performance.Manager + logger *logp.Logger +} + +func NewPerformanceDataFetcher(logger *logp.Logger, perfManager *performance.Manager) *PerformanceDataFetcher { + return &PerformanceDataFetcher{ + logger: logger, + perfManager: perfManager, + } +} + +func (p *PerformanceDataFetcher) GetPerfMetrics(ctx context.Context, + period int32, + objectType string, + objectName string, + objectReference types.ManagedObjectReference, + metrics map[string]*types.PerfCounterInfo, + metricSet map[string]struct{}) (metricMap map[string]interface{}, err error) { + + metricMap = make(map[string]interface{}) + + availableMetric, err := p.perfManager.AvailableMetric(ctx, objectReference, period) + if err != nil { + return nil, fmt.Errorf("failed to get available metrics: %w", err) + } + + availableMetricByKey := availableMetric.ByKey() + + // Filter for required metrics + var metricIDs []types.PerfMetricId + for key, metric := range metricSet { + if counter, ok := metrics[key]; ok { + if _, exists := availableMetricByKey[counter.Key]; exists { + metricIDs = append(metricIDs, types.PerfMetricId{ + CounterId: counter.Key, + Instance: "*", + }) + } + } else { + p.logger.Warnf("Metric %s not found", metric) + } + } + + spec := types.PerfQuerySpec{ + Entity: objectReference, + MetricId: metricIDs, + MaxSample: 1, + IntervalId: period, + } + + // Query performance data + samples, err := p.perfManager.Query(ctx, []types.PerfQuerySpec{spec}) + if err != nil { + if strings.Contains(err.Error(), "ServerFaultCode: A specified parameter was not correct: querySpec.interval") { + return metricMap, fmt.Errorf("failed to query performance data: use one of the system's supported interval. consider adjusting period: %w", err) + } + + return metricMap, fmt.Errorf("failed to query performance data: %w", err) + } + + if len(samples) == 0 { + p.logger.Debug("No samples returned from performance manager") + return metricMap, nil + } + + results, err := p.perfManager.ToMetricSeries(ctx, samples) + if err != nil { + return metricMap, fmt.Errorf("failed to convert performance data to metric series: %w", err) + } + + if len(results) == 0 { + p.logger.Debug("No results returned from metric series conversion") + return metricMap, nil + } + + for _, result := range results[0].Value { + if len(result.Value) > 0 { + if objectType == "virtualMachine" { + p.logger.Infof("METRIC RESULT: %+v", result) + } + metricMap[result.Name] = result.Value[0] + continue + } + p.logger.Debugf("For %s %s, Metric %s: No result found", objectType, objectName, result.Name) + } + + return metricMap, nil +} diff --git a/metricbeat/module/vsphere/host/host.go b/metricbeat/module/vsphere/host/host.go index 0150d25330da..e2f3989933ca 100644 --- a/metricbeat/module/vsphere/host/host.go +++ b/metricbeat/module/vsphere/host/host.go @@ -163,7 +163,8 @@ func (m *HostMetricSet) Fetch(ctx context.Context, reporter mb.ReporterV2) error m.Logger().Errorf("Failed to retrieve object from host %s: %v", hst[i].Name, err) } - metricMap, err := m.getPerfMetrics(ctx, perfManager, hst[i], metrics) + perfFetcher := vSphereClientUtil.NewPerformanceDataFetcher(m.Logger(), perfManager) + metricMap, err := perfFetcher.GetPerfMetrics(ctx, int32(m.Module().Config().Period.Seconds()), "host", hst[i].Name, hst[i].Reference(), metrics, metricSet) if err != nil { m.Logger().Errorf("Failed to retrieve performance metrics from host %s: %v", hst[i].Name, err) } @@ -266,72 +267,3 @@ func getTriggeredAlarm(ctx context.Context, pc *property.Collector, triggeredAla return triggeredAlarms, nil } - -func (m *HostMetricSet) getPerfMetrics(ctx context.Context, perfManager *performance.Manager, hst mo.HostSystem, metrics map[string]*types.PerfCounterInfo) (metricMap map[string]interface{}, err error) { - metricMap = make(map[string]interface{}) - - period := int32(m.Module().Config().Period.Seconds()) - availableMetric, err := perfManager.AvailableMetric(ctx, hst.Reference(), period) - if err != nil { - return nil, fmt.Errorf("failed to get available metrics: %w", err) - } - - availableMetricByKey := availableMetric.ByKey() - - // Filter for required metrics - var metricIDs []types.PerfMetricId - for key, metric := range metricSet { - if counter, ok := metrics[key]; ok { - if _, exists := availableMetricByKey[counter.Key]; exists { - metricIDs = append(metricIDs, types.PerfMetricId{ - CounterId: counter.Key, - Instance: "*", - }) - } - } else { - m.Logger().Warnf("Metric %s not found", metric) - } - } - - spec := types.PerfQuerySpec{ - Entity: hst.Reference(), - MetricId: metricIDs, - MaxSample: 1, - IntervalId: period, - } - - // Query performance data - samples, err := perfManager.Query(ctx, []types.PerfQuerySpec{spec}) - if err != nil { - if strings.Contains(err.Error(), "ServerFaultCode: A specified parameter was not correct: querySpec.interval") { - return metricMap, fmt.Errorf("failed to query performance data: use one of the system's supported interval. consider adjusting period: %w", err) - } - - return metricMap, fmt.Errorf("failed to query performance data: %w", err) - } - - if len(samples) == 0 { - m.Logger().Debug("No samples returned from performance manager") - return metricMap, nil - } - - results, err := perfManager.ToMetricSeries(ctx, samples) - if err != nil { - return metricMap, fmt.Errorf("failed to convert performance data to metric series: %w", err) - } - - if len(results) == 0 { - m.Logger().Debug("No results returned from metric series conversion") - return metricMap, nil - } - - for _, result := range results[0].Value { - if len(result.Value) > 0 { - metricMap[result.Name] = result.Value[0] - continue - } - m.Logger().Debugf("For host %s, Metric %s: No result found", hst.Name, result.Name) - } - - return metricMap, nil -} diff --git a/metricbeat/module/vsphere/virtualmachine/data.go b/metricbeat/module/vsphere/virtualmachine/data.go index 0839f5789cca..74de6a8bd765 100644 --- a/metricbeat/module/vsphere/virtualmachine/data.go +++ b/metricbeat/module/vsphere/virtualmachine/data.go @@ -78,6 +78,27 @@ func (m *MetricSet) mapEvent(data VMData) mapstr.M { if len(data.triggeredAlarms) > 0 { event.Put("triggered_alarms", data.triggeredAlarms) } + if val, ok := data.PerformanceData["cpu.usage.average"]; ok { + event.Put("cpu.perc", val.(int64)) + } + if val, ok := data.PerformanceData["disk.usage.average"]; ok { + event.Put("disk.average", val.(int64)) + } + if val, ok := data.PerformanceData["disk.read.average"]; ok { + event.Put("disk.read.average", val.(int64)) + } + if val, ok := data.PerformanceData["disk.write.average"]; ok { + event.Put("disk.write.average", val.(int64)) + } + if val, ok := data.PerformanceData["disk.numberRead.summation"]; ok { + event.Put("disk.numberRead", val.(int64)) + } + if val, ok := data.PerformanceData["disk.numberWrite.summation"]; ok { + event.Put("disk.numberWrite", val.(int64)) + } + if val, ok := data.PerformanceData["mem.usage.average"]; ok { + event.Put("memory.perc", val.(int64)) + } return event } diff --git a/metricbeat/module/vsphere/virtualmachine/virtualmachine.go b/metricbeat/module/vsphere/virtualmachine/virtualmachine.go index 5436af8f1a79..dcde2b06e89c 100644 --- a/metricbeat/module/vsphere/virtualmachine/virtualmachine.go +++ b/metricbeat/module/vsphere/virtualmachine/virtualmachine.go @@ -32,6 +32,7 @@ import ( "github.com/vmware/govmomi" "github.com/vmware/govmomi/object" + "github.com/vmware/govmomi/performance" "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/view" "github.com/vmware/govmomi/vim25" @@ -39,6 +40,20 @@ import ( "github.com/vmware/govmomi/vim25/types" ) +var metricSet = map[string]struct{}{ + "cpu.usage.average": {}, + + "disk.usage.average": {}, + + "disk.read.average": {}, + "disk.write.average": {}, + + "disk.numberRead.summation": {}, + "disk.numberWrite.summation": {}, + + "mem.usage.average": {}, +} + func init() { mb.Registry.MustAddMetricSet("vsphere", "virtualmachine", New, mb.WithHostParser(vsphere.HostParser), @@ -69,6 +84,7 @@ type VMData struct { DatastoreNames []string CustomFields mapstr.M Snapshots []VMSnapshotData + PerformanceData map[string]interface{} triggeredAlarms []triggeredAlarm } @@ -157,6 +173,15 @@ func (m *MetricSet) Fetch(ctx context.Context, reporter mb.ReporterV2) error { return fmt.Errorf("virtualmachine: error in Retrieve: %w", err) } + // Create a performance manager + perfManager := performance.NewManager(c) + + // Retrieve all available metrics + metrics, err := perfManager.CounterInfoByName(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve metrics: %w", err) + } + pc := property.DefaultCollector(c) for _, vm := range vmt { var hostID, hostName string @@ -178,6 +203,13 @@ func (m *MetricSet) Fetch(ctx context.Context, reporter mb.ReporterV2) error { "from host/guest") } + perfFetcher := vSphereClientUtil.NewPerformanceDataFetcher(m.Logger(), perfManager) + + metricMap, err := perfFetcher.GetPerfMetrics(ctx, int32(m.Module().Config().Period.Seconds()), "virtualMachine", vm.Name, vm.Reference(), metrics, metricSet) + if err != nil { + m.Logger().Errorf("Failed to retrieve performance metrics from virtual machine %s: %v", vm.Name, err) + } + // Retrieve custom fields if enabled if m.GetCustomFields && vm.Summary.CustomValue != nil { customFields = getCustomFields(vm.Summary.CustomValue, customFieldsMap) @@ -223,6 +255,7 @@ func (m *MetricSet) Fetch(ctx context.Context, reporter mb.ReporterV2) error { DatastoreNames: datastoreNames, CustomFields: customFields, Snapshots: snapshots, + PerformanceData: metricMap, triggeredAlarms: triggeredAlarm, } From 4249986a11c434df312ec7836efe4fa05b99935f Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Mon, 5 May 2025 17:15:24 +0300 Subject: [PATCH 02/21] add missing license headers --- metricbeat/module/vsphere/client/performance.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/metricbeat/module/vsphere/client/performance.go b/metricbeat/module/vsphere/client/performance.go index 9bc6c28ca5b6..0e96b12658ac 100644 --- a/metricbeat/module/vsphere/client/performance.go +++ b/metricbeat/module/vsphere/client/performance.go @@ -1,3 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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. + package client import ( From 247cd5a076fb40c8de6d8650548230758eddde72 Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Mon, 5 May 2025 17:17:23 +0300 Subject: [PATCH 03/21] mage fmt --- metricbeat/module/vsphere/client/performance.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/metricbeat/module/vsphere/client/performance.go b/metricbeat/module/vsphere/client/performance.go index 0e96b12658ac..91a281c94f40 100644 --- a/metricbeat/module/vsphere/client/performance.go +++ b/metricbeat/module/vsphere/client/performance.go @@ -22,9 +22,10 @@ import ( "fmt" "strings" - "github.com/elastic/elastic-agent-libs/logp" "github.com/vmware/govmomi/performance" "github.com/vmware/govmomi/vim25/types" + + "github.com/elastic/elastic-agent-libs/logp" ) type PerformanceDataFetcher struct { From fc31132a545931269367ce7f77ff84244e0e3c4f Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Tue, 6 May 2025 11:31:31 +0300 Subject: [PATCH 04/21] convert percentage values from fixed point integers --- metricbeat/module/vsphere/client/performance.go | 6 +++++- metricbeat/module/vsphere/virtualmachine/data.go | 14 +++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/metricbeat/module/vsphere/client/performance.go b/metricbeat/module/vsphere/client/performance.go index 91a281c94f40..b932812d890a 100644 --- a/metricbeat/module/vsphere/client/performance.go +++ b/metricbeat/module/vsphere/client/performance.go @@ -109,7 +109,11 @@ func (p *PerformanceDataFetcher) GetPerfMetrics(ctx context.Context, if objectType == "virtualMachine" { p.logger.Infof("METRIC RESULT: %+v", result) } - metricMap[result.Name] = result.Value[0] + value := result.Value[0] + if result.Unit == string(types.PerformanceManagerUnitPercent) { + value = value / 100 + } + metricMap[result.Name] = value continue } p.logger.Debugf("For %s %s, Metric %s: No result found", objectType, objectName, result.Name) diff --git a/metricbeat/module/vsphere/virtualmachine/data.go b/metricbeat/module/vsphere/virtualmachine/data.go index 74de6a8bd765..751e0ae28754 100644 --- a/metricbeat/module/vsphere/virtualmachine/data.go +++ b/metricbeat/module/vsphere/virtualmachine/data.go @@ -79,25 +79,25 @@ func (m *MetricSet) mapEvent(data VMData) mapstr.M { event.Put("triggered_alarms", data.triggeredAlarms) } if val, ok := data.PerformanceData["cpu.usage.average"]; ok { - event.Put("cpu.perc", val.(int64)) + event.Put("cpu.percent", val) } if val, ok := data.PerformanceData["disk.usage.average"]; ok { - event.Put("disk.average", val.(int64)) + event.Put("disk.average.kiloBytesPerSecond", val) } if val, ok := data.PerformanceData["disk.read.average"]; ok { - event.Put("disk.read.average", val.(int64)) + event.Put("disk.read.average.kiloBytesPerSecond", val) } if val, ok := data.PerformanceData["disk.write.average"]; ok { - event.Put("disk.write.average", val.(int64)) + event.Put("disk.write.average.kiloBytesPerSecond", val) } if val, ok := data.PerformanceData["disk.numberRead.summation"]; ok { - event.Put("disk.numberRead", val.(int64)) + event.Put("disk.numberRead", val) } if val, ok := data.PerformanceData["disk.numberWrite.summation"]; ok { - event.Put("disk.numberWrite", val.(int64)) + event.Put("disk.numberWrite", val) } if val, ok := data.PerformanceData["mem.usage.average"]; ok { - event.Put("memory.perc", val.(int64)) + event.Put("memory.percent", val) } return event From 5cad1e3476ad79f6ee22f07dcec8c2e384e0d60b Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Tue, 6 May 2025 12:28:57 +0300 Subject: [PATCH 05/21] add CHANGELOG.next.asciidoc entry --- CHANGELOG.next.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 86e96a014db2..596c11f9c5f7 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -489,6 +489,7 @@ otherwise no tag is added. {issue}42208[42208] {pull}42403[42403] - Updated Meraki API endpoint for Channel Utilization data. Switched to `GetOrganizationWirelessDevicesChannelUtilizationByDevice`. {pull}43485[43485] - Upgrade Prometheus Library to v0.300.1. {pull}43540[43540] - Add GCP Dataproc metadata collector in GCP module. {pull}43518[43518] +- Add new metrics to vSphere Virtual Machine dataset (CPU usage percentage, disk average usage, disk read/write rate, number of disk reads/writes, memory usage percentage). {pull}44205[44205] *Metricbeat* From ea0be4fa0b00c867b11de11c95406ae9bfddaaf7 Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Tue, 6 May 2025 13:24:13 +0300 Subject: [PATCH 06/21] refactor performance data fetching for datastore --- metricbeat/module/vsphere/datastore/datastore.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/metricbeat/module/vsphere/datastore/datastore.go b/metricbeat/module/vsphere/datastore/datastore.go index 956a1db23324..6d8a4afd8ebc 100644 --- a/metricbeat/module/vsphere/datastore/datastore.go +++ b/metricbeat/module/vsphere/datastore/datastore.go @@ -150,7 +150,9 @@ func (m *DataStoreMetricSet) Fetch(ctx context.Context, reporter mb.ReporterV2) m.Logger().Errorf("Failed to retrieve object from datastore %s: %v", dst[i].Name, err) } - metricMap, err := m.getPerfMetrics(ctx, perfManager, dst[i], metrics) + perfFetcher := vSphereClientUtil.NewPerformanceDataFetcher(m.Logger(), perfManager) + metricMap, err := perfFetcher.GetPerfMetrics(ctx, int32(m.Module().Config().Period.Seconds()), "datastore", dst[i].Name, dst[i].Reference(), metrics, metricSet) + if err != nil { m.Logger().Errorf("Failed to retrieve performance metrics from datastore %s: %v", dst[i].Name, err) } From 00135e3625e8f4b50c60125d2abfd34b42d50565 Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Tue, 6 May 2025 13:26:04 +0300 Subject: [PATCH 07/21] document new fields --- metricbeat/module/vsphere/fields.go | 2 +- .../vsphere/virtualmachine/_meta/fields.yml | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/metricbeat/module/vsphere/fields.go b/metricbeat/module/vsphere/fields.go index c67607c61002..104741c24718 100644 --- a/metricbeat/module/vsphere/fields.go +++ b/metricbeat/module/vsphere/fields.go @@ -32,5 +32,5 @@ func init() { // AssetVsphere returns asset data. // This is the base64 encoded zlib format compressed contents of module/vsphere. func AssetVsphere() string { - return "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" + return "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" } diff --git a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml index eb6cc6d88e52..af3c009b4583 100644 --- a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml +++ b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml @@ -39,6 +39,10 @@ type: long description: > Available CPU in Mhz. + - name: cpu.percent + type: long + description: > + CPU usage as a percentage. - name: memory.used.guest.bytes type: long description: > @@ -59,6 +63,10 @@ description: > Free memory of Guest in bytes. format: bytes + - name: memory.percent + type: long + description: > + Memory usage as percent of total configured or available memory. - name: custom_fields type: object object_type: keyword @@ -113,3 +121,26 @@ object_type: keyword description: > List of all the triggered alarms. + - name: disk + type: group + fields: + - name: average.kiloBytesPerSecond + type: long + description: > + Aggregated disk I/O rate. + - name: read.average.kiloBytesPerSecond + type: long + description: > + Rate at which data is read from each virtual disk on the virtual machine. + - name: write.average.kiloBytesPerSecond + type: long + description: > + Rate at which data is written to each virtual disk on the virtual machine. + - name: numberRead + type: long + description: > + Number of times data was read. + - name: numberWrite + type: long + description: > + Number of disk writes. From af410f9cbce0128513222f97c6744db1d609991a Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Tue, 6 May 2025 13:36:08 +0300 Subject: [PATCH 08/21] remove unused function --- .../module/vsphere/datastore/datastore.go | 69 ------------------- 1 file changed, 69 deletions(-) diff --git a/metricbeat/module/vsphere/datastore/datastore.go b/metricbeat/module/vsphere/datastore/datastore.go index 6d8a4afd8ebc..c1899048240b 100644 --- a/metricbeat/module/vsphere/datastore/datastore.go +++ b/metricbeat/module/vsphere/datastore/datastore.go @@ -260,72 +260,3 @@ func getTriggeredAlarm(ctx context.Context, pc *property.Collector, triggeredAla return triggeredAlarms, nil } - -func (m *DataStoreMetricSet) getPerfMetrics(ctx context.Context, perfManager *performance.Manager, dst mo.Datastore, metrics map[string]*types.PerfCounterInfo) (metricMap map[string]interface{}, err error) { - metricMap = make(map[string]interface{}) - - period := int32(m.Module().Config().Period.Seconds()) - availableMetric, err := perfManager.AvailableMetric(ctx, dst.Reference(), period) - if err != nil { - return nil, fmt.Errorf("failed to get available metrics: %w", err) - } - - availableMetricByKey := availableMetric.ByKey() - - // Filter for required metrics - var metricIDs []types.PerfMetricId - for key, metric := range metricSet { - if counter, ok := metrics[key]; ok { - if _, exists := availableMetricByKey[counter.Key]; exists { - metricIDs = append(metricIDs, types.PerfMetricId{ - CounterId: counter.Key, - Instance: "*", - }) - } - } else { - m.Logger().Warnf("Metric %s not found", metric) - } - } - - spec := types.PerfQuerySpec{ - Entity: dst.Reference(), - MetricId: metricIDs, - MaxSample: 1, - IntervalId: period, // using refreshRate as interval - } - - // Query performance data - samples, err := perfManager.Query(ctx, []types.PerfQuerySpec{spec}) - if err != nil { - if strings.Contains(err.Error(), "ServerFaultCode: A specified parameter was not correct: querySpec.interval") { - return metricMap, fmt.Errorf("failed to query performance data: use one of the system's supported interval. consider adjusting period: %w", err) - } - - return metricMap, fmt.Errorf("failed to query performance data: %w", err) - } - - if len(samples) == 0 { - m.Logger().Debug("No samples returned from performance manager") - return metricMap, nil - } - - results, err := perfManager.ToMetricSeries(ctx, samples) - if err != nil { - return metricMap, fmt.Errorf("failed to convert performance data to metric series: %w", err) - } - - if len(results) == 0 { - m.Logger().Debug("No results returned from metric series conversion") - return metricMap, nil - } - - for _, result := range results[0].Value { - if len(result.Value) > 0 { - metricMap[result.Name] = result.Value[0] - continue - } - m.Logger().Debugf("For datastore %s, Metric %s: No result found", dst.Name, result.Name) - } - - return metricMap, nil -} From 0357c1588d114b462f6eb141cfe36ca470854fef Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Tue, 6 May 2025 15:15:54 +0300 Subject: [PATCH 09/21] remove debug log --- metricbeat/module/vsphere/client/performance.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/metricbeat/module/vsphere/client/performance.go b/metricbeat/module/vsphere/client/performance.go index b932812d890a..4489a3dc0116 100644 --- a/metricbeat/module/vsphere/client/performance.go +++ b/metricbeat/module/vsphere/client/performance.go @@ -106,9 +106,6 @@ func (p *PerformanceDataFetcher) GetPerfMetrics(ctx context.Context, for _, result := range results[0].Value { if len(result.Value) > 0 { - if objectType == "virtualMachine" { - p.logger.Infof("METRIC RESULT: %+v", result) - } value := result.Value[0] if result.Unit == string(types.PerformanceManagerUnitPercent) { value = value / 100 From a728e249469e0aefe5533ceff74f0c6be36bc755 Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Wed, 7 May 2025 15:41:21 +0300 Subject: [PATCH 10/21] add unit tests --- .../module/vsphere/client/mock_performance.go | 105 ++++++++ .../module/vsphere/client/performance.go | 10 +- .../module/vsphere/client/performance_test.go | 245 ++++++++++++++++++ 3 files changed, 358 insertions(+), 2 deletions(-) create mode 100644 metricbeat/module/vsphere/client/mock_performance.go create mode 100644 metricbeat/module/vsphere/client/performance_test.go diff --git a/metricbeat/module/vsphere/client/mock_performance.go b/metricbeat/module/vsphere/client/mock_performance.go new file mode 100644 index 000000000000..722851ae036e --- /dev/null +++ b/metricbeat/module/vsphere/client/mock_performance.go @@ -0,0 +1,105 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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. + +// Code generated by MockGen. DO NOT EDIT. +// Source: performance.go +// +// Generated by this command: +// +// mockgen -source=performance.go -destination=mock_performance.go -package client -mock_names=Logouter=MockPerfManager +// + +// Package client is a generated GoMock package. +package client + +import ( + context "context" + reflect "reflect" + + performance "github.com/vmware/govmomi/performance" + types "github.com/vmware/govmomi/vim25/types" + gomock "go.uber.org/mock/gomock" +) + +// MockPerfManager is a mock of PerfManager interface. +type MockPerfManager struct { + ctrl *gomock.Controller + recorder *MockPerfManagerMockRecorder + isgomock struct{} +} + +// MockPerfManagerMockRecorder is the mock recorder for MockPerfManager. +type MockPerfManagerMockRecorder struct { + mock *MockPerfManager +} + +// NewMockPerfManager creates a new mock instance. +func NewMockPerfManager(ctrl *gomock.Controller) *MockPerfManager { + mock := &MockPerfManager{ctrl: ctrl} + mock.recorder = &MockPerfManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPerfManager) EXPECT() *MockPerfManagerMockRecorder { + return m.recorder +} + +// AvailableMetric mocks base method. +func (m *MockPerfManager) AvailableMetric(ctx context.Context, entity types.ManagedObjectReference, interval int32) (performance.MetricList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AvailableMetric", ctx, entity, interval) + ret0, _ := ret[0].(performance.MetricList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AvailableMetric indicates an expected call of AvailableMetric. +func (mr *MockPerfManagerMockRecorder) AvailableMetric(ctx, entity, interval any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AvailableMetric", reflect.TypeOf((*MockPerfManager)(nil).AvailableMetric), ctx, entity, interval) +} + +// Query mocks base method. +func (m *MockPerfManager) Query(ctx context.Context, spec []types.PerfQuerySpec) ([]types.BasePerfEntityMetricBase, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Query", ctx, spec) + ret0, _ := ret[0].([]types.BasePerfEntityMetricBase) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Query indicates an expected call of Query. +func (mr *MockPerfManagerMockRecorder) Query(ctx, spec any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockPerfManager)(nil).Query), ctx, spec) +} + +// ToMetricSeries mocks base method. +func (m *MockPerfManager) ToMetricSeries(ctx context.Context, series []types.BasePerfEntityMetricBase) ([]performance.EntityMetric, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ToMetricSeries", ctx, series) + ret0, _ := ret[0].([]performance.EntityMetric) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ToMetricSeries indicates an expected call of ToMetricSeries. +func (mr *MockPerfManagerMockRecorder) ToMetricSeries(ctx, series any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToMetricSeries", reflect.TypeOf((*MockPerfManager)(nil).ToMetricSeries), ctx, series) +} diff --git a/metricbeat/module/vsphere/client/performance.go b/metricbeat/module/vsphere/client/performance.go index 4489a3dc0116..8c7628809d9b 100644 --- a/metricbeat/module/vsphere/client/performance.go +++ b/metricbeat/module/vsphere/client/performance.go @@ -28,12 +28,18 @@ import ( "github.com/elastic/elastic-agent-libs/logp" ) +type PerfManager interface { + AvailableMetric(ctx context.Context, entity types.ManagedObjectReference, interval int32) (performance.MetricList, error) + Query(ctx context.Context, spec []types.PerfQuerySpec) ([]types.BasePerfEntityMetricBase, error) + ToMetricSeries(ctx context.Context, series []types.BasePerfEntityMetricBase) ([]performance.EntityMetric, error) +} + type PerformanceDataFetcher struct { - perfManager *performance.Manager + perfManager PerfManager logger *logp.Logger } -func NewPerformanceDataFetcher(logger *logp.Logger, perfManager *performance.Manager) *PerformanceDataFetcher { +func NewPerformanceDataFetcher(logger *logp.Logger, perfManager PerfManager) *PerformanceDataFetcher { return &PerformanceDataFetcher{ logger: logger, perfManager: perfManager, diff --git a/metricbeat/module/vsphere/client/performance_test.go b/metricbeat/module/vsphere/client/performance_test.go new file mode 100644 index 000000000000..4dfb125b2e7f --- /dev/null +++ b/metricbeat/module/vsphere/client/performance_test.go @@ -0,0 +1,245 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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. + +package client + +import ( + "context" + "errors" + "testing" + + "github.com/elastic/elastic-agent-libs/logp/logptest" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/vmware/govmomi/performance" + "github.com/vmware/govmomi/vim25/types" + "go.uber.org/mock/gomock" +) + +// Run 'go generate' to create mocks that are used in tests. +//go:generate go run go.uber.org/mock/mockgen -source=performance.go -destination=mock_performance.go -package client -mock_names=Logouter=MockPerfManager + +func TestGetPerfMetrics(t *testing.T) { + var tPeriod int32 = 5 + tObjType := "test-type" + tObjName := "test-name" + tObjRef := types.ManagedObjectReference{Type: tObjType, Value: "test-obj-ref-value", ServerGUID: "test-guid-1"} + metrics := map[string]*types.PerfCounterInfo{ + "metric1": { + Key: 111, + }, + } + metricSet := map[string]struct{}{ + "metric1": {}, + } + + mSamples := []types.BasePerfEntityMetricBase{ + &types.PerfEntityMetric{ + Value: []types.BasePerfMetricSeries{ + &types.PerfMetricSeries{ + Id: types.PerfMetricId{ + CounterId: 111, + Instance: "*", + }, + }, + }, + }, + } + + tests := []struct { + name string + mockPerfManager func(manager *MockPerfManager) + assertResults func(t2 *testing.T, metricsMap map[string]interface{}, err error) + }{ + { + name: "success (percentage metric)", + mockPerfManager: func(manager *MockPerfManager) { + manager.EXPECT().AvailableMetric(gomock.Any(), tObjRef, tPeriod).Return([]types.PerfMetricId{ + { + CounterId: 111, + Instance: "*", + }, + }, nil) + manager.EXPECT().Query(gomock.Any(), []types.PerfQuerySpec{ + { + Entity: tObjRef, + MetricId: []types.PerfMetricId{ + { + CounterId: 111, + Instance: "*", + }, + }, + MaxSample: 1, + IntervalId: tPeriod, + }, + }).Return(mSamples, nil) + manager.EXPECT().ToMetricSeries(gomock.Any(), mSamples).Return([]performance.EntityMetric{ + { + Entity: tObjRef, + Value: []performance.MetricSeries{ + { + Name: "metric1", + Unit: string(types.PerformanceManagerUnitPercent), + Value: []int64{5320}, + }, + }, + }, + }, nil) + }, + assertResults: func(t2 *testing.T, metricMap map[string]interface{}, err error) { + require.NoError(t, err) + assert.InDeltaMapValues(t, map[string]interface{}{ + "metric1": 53, + }, metricMap, 0) + }, + }, + { + name: "success (not percentage metric)", + mockPerfManager: func(manager *MockPerfManager) { + manager.EXPECT().AvailableMetric(gomock.Any(), tObjRef, tPeriod).Return([]types.PerfMetricId{ + { + CounterId: 111, + Instance: "*", + }, + }, nil) + manager.EXPECT().Query(gomock.Any(), []types.PerfQuerySpec{ + { + Entity: tObjRef, + MetricId: []types.PerfMetricId{ + { + CounterId: 111, + Instance: "*", + }, + }, + MaxSample: 1, + IntervalId: tPeriod, + }, + }).Return(mSamples, nil) + manager.EXPECT().ToMetricSeries(gomock.Any(), mSamples).Return([]performance.EntityMetric{ + { + Entity: tObjRef, + Value: []performance.MetricSeries{ + { + Name: "metric1", + Unit: string(types.PerformanceManagerUnitKiloBytesPerSecond), + Value: []int64{1024}, + }, + }, + }, + }, nil) + }, + assertResults: func(t2 *testing.T, metricMap map[string]interface{}, err error) { + require.NoError(t, err) + assert.InDeltaMapValues(t, map[string]interface{}{ + "metric1": 1024, + }, metricMap, 0) + }, + }, + { + name: "no available metrics", + mockPerfManager: func(manager *MockPerfManager) { + manager.EXPECT().AvailableMetric(gomock.Any(), tObjRef, tPeriod).Return(nil, nil) + manager.EXPECT().Query(gomock.Any(), []types.PerfQuerySpec{ + { + Entity: tObjRef, + MetricId: nil, + MaxSample: 1, + IntervalId: tPeriod, + }, + }).Return(nil, nil) + }, + assertResults: func(t2 *testing.T, metricMap map[string]interface{}, err error) { + require.NoError(t, err) + assert.InDeltaMapValues(t, map[string]interface{}{}, metricMap, 0) + }, + }, + { + name: "query error", + mockPerfManager: func(manager *MockPerfManager) { + manager.EXPECT().AvailableMetric(gomock.Any(), tObjRef, tPeriod).Return([]types.PerfMetricId{ + { + CounterId: 111, + Instance: "*", + }, + }, nil) + manager.EXPECT().Query(gomock.Any(), []types.PerfQuerySpec{ + { + Entity: tObjRef, + MetricId: []types.PerfMetricId{ + { + CounterId: 111, + Instance: "*", + }, + }, + MaxSample: 1, + IntervalId: tPeriod, + }, + }).Return(nil, errors.New("query error")) + }, + assertResults: func(t *testing.T, metricMap map[string]interface{}, err error) { + assert.Error(t, err, "query error") + }, + }, + { + name: "error converting to metric series", + mockPerfManager: func(manager *MockPerfManager) { + manager.EXPECT().AvailableMetric(gomock.Any(), tObjRef, tPeriod).Return([]types.PerfMetricId{ + { + CounterId: 111, + Instance: "*", + }, + }, nil) + manager.EXPECT().Query(gomock.Any(), []types.PerfQuerySpec{ + { + Entity: tObjRef, + MetricId: []types.PerfMetricId{ + { + CounterId: 111, + Instance: "*", + }, + }, + MaxSample: 1, + IntervalId: tPeriod, + }, + }).Return(mSamples, nil) + manager.EXPECT().ToMetricSeries(gomock.Any(), mSamples).Return(nil, errors.New("ToMetricSeries error")) + }, + assertResults: func(t2 *testing.T, metricMap map[string]interface{}, err error) { + assert.Error(t, err, "ToMetricSeries error") + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + + mPerfManager := NewMockPerfManager(ctrl) + if tt.mockPerfManager != nil { + tt.mockPerfManager(mPerfManager) + } + + manager := &PerformanceDataFetcher{ + logger: logptest.NewTestingLogger(t, ""), + perfManager: mPerfManager, + } + + metricMap, err := manager.GetPerfMetrics(context.Background(), tPeriod, tObjType, tObjName, tObjRef, metrics, metricSet) + tt.assertResults(t, metricMap, err) + }) + } +} From 5273df41a099dedf4be5cbcac790d6661246c007 Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Wed, 7 May 2025 15:55:22 +0300 Subject: [PATCH 11/21] mage fmt --- metricbeat/module/vsphere/client/performance_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/metricbeat/module/vsphere/client/performance_test.go b/metricbeat/module/vsphere/client/performance_test.go index 4dfb125b2e7f..106a4add2d00 100644 --- a/metricbeat/module/vsphere/client/performance_test.go +++ b/metricbeat/module/vsphere/client/performance_test.go @@ -22,12 +22,13 @@ import ( "errors" "testing" - "github.com/elastic/elastic-agent-libs/logp/logptest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/vmware/govmomi/performance" "github.com/vmware/govmomi/vim25/types" "go.uber.org/mock/gomock" + + "github.com/elastic/elastic-agent-libs/logp/logptest" ) // Run 'go generate' to create mocks that are used in tests. From 764c34a151b37b9af2f172c7b6c20b597fd70bdc Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Thu, 22 May 2025 16:09:18 +0300 Subject: [PATCH 12/21] fixed precision issue for percentage performance manager values --- metricbeat/module/vsphere/client/performance.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metricbeat/module/vsphere/client/performance.go b/metricbeat/module/vsphere/client/performance.go index 8c7628809d9b..e5c820b4822f 100644 --- a/metricbeat/module/vsphere/client/performance.go +++ b/metricbeat/module/vsphere/client/performance.go @@ -112,9 +112,9 @@ func (p *PerformanceDataFetcher) GetPerfMetrics(ctx context.Context, for _, result := range results[0].Value { if len(result.Value) > 0 { - value := result.Value[0] + value := float64(result.Value[0]) if result.Unit == string(types.PerformanceManagerUnitPercent) { - value = value / 100 + value = value / 100.0 } metricMap[result.Name] = value continue From ce7e055089bf87d15149fb2de9a7e88dda75e10d Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Thu, 22 May 2025 16:19:55 +0300 Subject: [PATCH 13/21] correct percentage property names --- metricbeat/module/vsphere/virtualmachine/_meta/fields.yml | 4 ++-- metricbeat/module/vsphere/virtualmachine/data.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml index af3c009b4583..138fd11e951d 100644 --- a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml +++ b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml @@ -39,7 +39,7 @@ type: long description: > Available CPU in Mhz. - - name: cpu.percent + - name: cpu.usage.percent type: long description: > CPU usage as a percentage. @@ -63,7 +63,7 @@ description: > Free memory of Guest in bytes. format: bytes - - name: memory.percent + - name: memory.usage.percent type: long description: > Memory usage as percent of total configured or available memory. diff --git a/metricbeat/module/vsphere/virtualmachine/data.go b/metricbeat/module/vsphere/virtualmachine/data.go index 751e0ae28754..1ba7dfc5392c 100644 --- a/metricbeat/module/vsphere/virtualmachine/data.go +++ b/metricbeat/module/vsphere/virtualmachine/data.go @@ -79,7 +79,7 @@ func (m *MetricSet) mapEvent(data VMData) mapstr.M { event.Put("triggered_alarms", data.triggeredAlarms) } if val, ok := data.PerformanceData["cpu.usage.average"]; ok { - event.Put("cpu.percent", val) + event.Put("cpu.usage.percent", val) } if val, ok := data.PerformanceData["disk.usage.average"]; ok { event.Put("disk.average.kiloBytesPerSecond", val) @@ -97,7 +97,7 @@ func (m *MetricSet) mapEvent(data VMData) mapstr.M { event.Put("disk.numberWrite", val) } if val, ok := data.PerformanceData["mem.usage.average"]; ok { - event.Put("memory.percent", val) + event.Put("memory.usage.percent", val) } return event From ab815033e335edd5244ff9a5bd313a388e1d92d1 Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Thu, 22 May 2025 16:24:50 +0300 Subject: [PATCH 14/21] converts kilobytes per sec to bytes per sec --- metricbeat/module/vsphere/virtualmachine/_meta/fields.yml | 6 +++--- metricbeat/module/vsphere/virtualmachine/data.go | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml index 138fd11e951d..b1550f69c190 100644 --- a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml +++ b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml @@ -124,15 +124,15 @@ - name: disk type: group fields: - - name: average.kiloBytesPerSecond + - name: average.bytesPerSecond type: long description: > Aggregated disk I/O rate. - - name: read.average.kiloBytesPerSecond + - name: read.average.bytesPerSecond type: long description: > Rate at which data is read from each virtual disk on the virtual machine. - - name: write.average.kiloBytesPerSecond + - name: write.average.bytesPerSecond type: long description: > Rate at which data is written to each virtual disk on the virtual machine. diff --git a/metricbeat/module/vsphere/virtualmachine/data.go b/metricbeat/module/vsphere/virtualmachine/data.go index 1ba7dfc5392c..51067392298c 100644 --- a/metricbeat/module/vsphere/virtualmachine/data.go +++ b/metricbeat/module/vsphere/virtualmachine/data.go @@ -23,6 +23,7 @@ import ( func (m *MetricSet) mapEvent(data VMData) mapstr.M { const bytesMultiplier = int64(1024 * 1024) + const kilobytesToBytesMultiplier = int64(1024) usedMemory := int64(data.VM.Summary.QuickStats.GuestMemoryUsage) * bytesMultiplier usedCPU := data.VM.Summary.QuickStats.OverallCpuUsage totalCPU := data.VM.Summary.Config.CpuReservation @@ -82,13 +83,13 @@ func (m *MetricSet) mapEvent(data VMData) mapstr.M { event.Put("cpu.usage.percent", val) } if val, ok := data.PerformanceData["disk.usage.average"]; ok { - event.Put("disk.average.kiloBytesPerSecond", val) + event.Put("disk.average.bytes", val.(int64)*kilobytesToBytesMultiplier) } if val, ok := data.PerformanceData["disk.read.average"]; ok { - event.Put("disk.read.average.kiloBytesPerSecond", val) + event.Put("disk.read.average.bytes", val.(int64)*kilobytesToBytesMultiplier) } if val, ok := data.PerformanceData["disk.write.average"]; ok { - event.Put("disk.write.average.kiloBytesPerSecond", val) + event.Put("disk.write.average.bytes", val.(int64)*kilobytesToBytesMultiplier) } if val, ok := data.PerformanceData["disk.numberRead.summation"]; ok { event.Put("disk.numberRead", val) From 26d9f49f649a2a2518d57a65468f91baea42d2c7 Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Thu, 22 May 2025 16:34:43 +0300 Subject: [PATCH 15/21] update fields.go --- metricbeat/module/vsphere/fields.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metricbeat/module/vsphere/fields.go b/metricbeat/module/vsphere/fields.go index 104741c24718..dcbf64b744f4 100644 --- a/metricbeat/module/vsphere/fields.go +++ b/metricbeat/module/vsphere/fields.go @@ -32,5 +32,5 @@ func init() { // AssetVsphere returns asset data. // This is the base64 encoded zlib format compressed contents of module/vsphere. func AssetVsphere() string { - return "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" + return "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" } From 17a459dd45c5e8a01d0b90a26949150c69bca05d Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Thu, 22 May 2025 16:38:53 +0300 Subject: [PATCH 16/21] fix linter --- metricbeat/module/vsphere/virtualmachine/data.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/metricbeat/module/vsphere/virtualmachine/data.go b/metricbeat/module/vsphere/virtualmachine/data.go index 51067392298c..3212cc5b7161 100644 --- a/metricbeat/module/vsphere/virtualmachine/data.go +++ b/metricbeat/module/vsphere/virtualmachine/data.go @@ -83,13 +83,22 @@ func (m *MetricSet) mapEvent(data VMData) mapstr.M { event.Put("cpu.usage.percent", val) } if val, ok := data.PerformanceData["disk.usage.average"]; ok { - event.Put("disk.average.bytes", val.(int64)*kilobytesToBytesMultiplier) + intVal, assertOk := val.(int64) + if assertOk { + event.Put("disk.average.bytes", intVal*kilobytesToBytesMultiplier) + } } if val, ok := data.PerformanceData["disk.read.average"]; ok { - event.Put("disk.read.average.bytes", val.(int64)*kilobytesToBytesMultiplier) + intVal, assertOk := val.(int64) + if assertOk { + event.Put("disk.read.average.bytes", intVal*kilobytesToBytesMultiplier) + } } if val, ok := data.PerformanceData["disk.write.average"]; ok { - event.Put("disk.write.average.bytes", val.(int64)*kilobytesToBytesMultiplier) + intVal, assertOk := val.(int64) + if assertOk { + event.Put("disk.write.average.bytes", intVal*kilobytesToBytesMultiplier) + } } if val, ok := data.PerformanceData["disk.numberRead.summation"]; ok { event.Put("disk.numberRead", val) From c366bf9da27832fea8ea0898bdf8c16e8b35ffc8 Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Thu, 22 May 2025 17:19:08 +0300 Subject: [PATCH 17/21] fix type assertion pabic --- metricbeat/module/vsphere/client/performance.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/metricbeat/module/vsphere/client/performance.go b/metricbeat/module/vsphere/client/performance.go index e5c820b4822f..a1b8d67750fa 100644 --- a/metricbeat/module/vsphere/client/performance.go +++ b/metricbeat/module/vsphere/client/performance.go @@ -112,11 +112,12 @@ func (p *PerformanceDataFetcher) GetPerfMetrics(ctx context.Context, for _, result := range results[0].Value { if len(result.Value) > 0 { - value := float64(result.Value[0]) + value := result.Value[0] if result.Unit == string(types.PerformanceManagerUnitPercent) { - value = value / 100.0 + metricMap[result.Name] = float64(value) / 100.0 + } else { + metricMap[result.Name] = value } - metricMap[result.Name] = value continue } p.logger.Debugf("For %s %s, Metric %s: No result found", objectType, objectName, result.Name) From cf2ae15ec14a59b9deade2e0c095297b88170515 Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Thu, 22 May 2025 17:46:51 +0300 Subject: [PATCH 18/21] fix unit test failure --- metricbeat/module/vsphere/client/performance_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metricbeat/module/vsphere/client/performance_test.go b/metricbeat/module/vsphere/client/performance_test.go index 106a4add2d00..e0c60aae849a 100644 --- a/metricbeat/module/vsphere/client/performance_test.go +++ b/metricbeat/module/vsphere/client/performance_test.go @@ -104,7 +104,7 @@ func TestGetPerfMetrics(t *testing.T) { assertResults: func(t2 *testing.T, metricMap map[string]interface{}, err error) { require.NoError(t, err) assert.InDeltaMapValues(t, map[string]interface{}{ - "metric1": 53, + "metric1": 53.2, }, metricMap, 0) }, }, From 09ff7ab8ea4785e521d9d4cd0ad8fa6919b68b27 Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Fri, 23 May 2025 10:53:31 +0300 Subject: [PATCH 19/21] address PR comments --- metricbeat/module/vsphere/fields.go | 2 +- metricbeat/module/vsphere/virtualmachine/_meta/fields.yml | 4 ++-- metricbeat/module/vsphere/virtualmachine/data.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/metricbeat/module/vsphere/fields.go b/metricbeat/module/vsphere/fields.go index dcbf64b744f4..14bbf04e2c73 100644 --- a/metricbeat/module/vsphere/fields.go +++ b/metricbeat/module/vsphere/fields.go @@ -32,5 +32,5 @@ func init() { // AssetVsphere returns asset data. // This is the base64 encoded zlib format compressed contents of module/vsphere. func AssetVsphere() string { - return "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" + return "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" } diff --git a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml index b1550f69c190..017db730e614 100644 --- a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml +++ b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml @@ -136,11 +136,11 @@ type: long description: > Rate at which data is written to each virtual disk on the virtual machine. - - name: numberRead + - name: numberRead.count type: long description: > Number of times data was read. - - name: numberWrite + - name: numberWrite.count type: long description: > Number of disk writes. diff --git a/metricbeat/module/vsphere/virtualmachine/data.go b/metricbeat/module/vsphere/virtualmachine/data.go index 3212cc5b7161..24735bf1e3ad 100644 --- a/metricbeat/module/vsphere/virtualmachine/data.go +++ b/metricbeat/module/vsphere/virtualmachine/data.go @@ -101,10 +101,10 @@ func (m *MetricSet) mapEvent(data VMData) mapstr.M { } } if val, ok := data.PerformanceData["disk.numberRead.summation"]; ok { - event.Put("disk.numberRead", val) + event.Put("disk.numberRead.count", val) } if val, ok := data.PerformanceData["disk.numberWrite.summation"]; ok { - event.Put("disk.numberWrite", val) + event.Put("disk.numberWrite.count", val) } if val, ok := data.PerformanceData["mem.usage.average"]; ok { event.Put("memory.usage.percent", val) From b53555fa24a194a2645c2d3b9ea6efb23ea3731d Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Fri, 23 May 2025 11:17:17 +0300 Subject: [PATCH 20/21] changed percentage fields to scaled_float type --- metricbeat/module/vsphere/fields.go | 2 +- metricbeat/module/vsphere/virtualmachine/_meta/fields.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/metricbeat/module/vsphere/fields.go b/metricbeat/module/vsphere/fields.go index 14bbf04e2c73..7a5c820fcec2 100644 --- a/metricbeat/module/vsphere/fields.go +++ b/metricbeat/module/vsphere/fields.go @@ -32,5 +32,5 @@ func init() { // AssetVsphere returns asset data. // This is the base64 encoded zlib format compressed contents of module/vsphere. func AssetVsphere() string { - return "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" + return "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" } diff --git a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml index 017db730e614..a270d596bf6c 100644 --- a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml +++ b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml @@ -40,7 +40,7 @@ description: > Available CPU in Mhz. - name: cpu.usage.percent - type: long + type: scaled_float description: > CPU usage as a percentage. - name: memory.used.guest.bytes @@ -64,7 +64,7 @@ Free memory of Guest in bytes. format: bytes - name: memory.usage.percent - type: long + type: scaled_float description: > Memory usage as percent of total configured or available memory. - name: custom_fields From 8e3a69b0dfddbfc4f5fd574bfc23951d0fc9bc56 Mon Sep 17 00:00:00 2001 From: Stefan Stas Date: Fri, 23 May 2025 12:44:31 +0300 Subject: [PATCH 21/21] make field names same between fields.go and fields.yml --- metricbeat/module/vsphere/fields.go | 2 +- metricbeat/module/vsphere/virtualmachine/_meta/fields.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/metricbeat/module/vsphere/fields.go b/metricbeat/module/vsphere/fields.go index 7a5c820fcec2..fff391f13457 100644 --- a/metricbeat/module/vsphere/fields.go +++ b/metricbeat/module/vsphere/fields.go @@ -32,5 +32,5 @@ func init() { // AssetVsphere returns asset data. // This is the base64 encoded zlib format compressed contents of module/vsphere. func AssetVsphere() string { - return "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" + return "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" } diff --git a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml index a270d596bf6c..ba5717806357 100644 --- a/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml +++ b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml @@ -124,15 +124,15 @@ - name: disk type: group fields: - - name: average.bytesPerSecond + - name: average.bytes type: long description: > Aggregated disk I/O rate. - - name: read.average.bytesPerSecond + - name: read.average.bytes type: long description: > Rate at which data is read from each virtual disk on the virtual machine. - - name: write.average.bytesPerSecond + - name: write.average.bytes type: long description: > Rate at which data is written to each virtual disk on the virtual machine.