From f11592b4b601aee02e4749c1afbfe6d7ba46db90 Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Mon, 26 May 2025 11:41:01 +0300 Subject: [PATCH 1/4] =?UTF-8?q?capture=20extra=20vsphere=20metrics=20(cpu?= =?UTF-8?q?=20%,=20disk=20average,=20disk=20rate,=20disk=20n=E2=80=A6=20(#?= =?UTF-8?q?44205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * capture extra vsphere metrics (cpu %, disk average, disk rate, disk number, memory usage %) * add missing license headers * mage fmt * convert percentage values from fixed point integers * add CHANGELOG.next.asciidoc entry * refactor performance data fetching for datastore * document new fields * remove unused function * remove debug log * add unit tests * mage fmt * fixed precision issue for percentage performance manager values * correct percentage property names * converts kilobytes per sec to bytes per sec * update fields.go * fix linter * fix type assertion pabic * fix unit test failure * address PR comments * changed percentage fields to scaled_float type * make field names same between fields.go and fields.yml --------- Co-authored-by: Ishleen Kaur <102962586+ishleenk17@users.noreply.github.com> (cherry picked from commit 14ac0571abedd09aca8e6399c4353a72603adb0e) --- CHANGELOG.next.asciidoc | 3 + .../module/vsphere/client/mock_performance.go | 105 ++++++++ .../module/vsphere/client/performance.go | 127 +++++++++ .../module/vsphere/client/performance_test.go | 246 ++++++++++++++++++ .../module/vsphere/datastore/datastore.go | 73 +----- metricbeat/module/vsphere/fields.go | 2 +- metricbeat/module/vsphere/host/host.go | 72 +---- .../vsphere/virtualmachine/_meta/fields.yml | 31 +++ .../module/vsphere/virtualmachine/data.go | 31 +++ .../vsphere/virtualmachine/virtualmachine.go | 33 +++ 10 files changed, 582 insertions(+), 141 deletions(-) create mode 100644 metricbeat/module/vsphere/client/mock_performance.go create mode 100644 metricbeat/module/vsphere/client/performance.go create mode 100644 metricbeat/module/vsphere/client/performance_test.go diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 8cd81d684c29..9167c36eed50 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -253,6 +253,9 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff] - Add new metricset network for the vSphere module. {pull}40559[40559] - Add new metricset resourcepool for the vSphere module. {pull}40456[40456] - 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] - Added checks for the Resty response object in all Meraki module API calls to ensure proper handling of nil responses. {pull}44193[44193] - Add latency config option to Azure Monitor module. {pull}44366[44366] 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 new file mode 100644 index 000000000000..a1b8d67750fa --- /dev/null +++ b/metricbeat/module/vsphere/client/performance.go @@ -0,0 +1,127 @@ +// 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" + "fmt" + "strings" + + "github.com/vmware/govmomi/performance" + "github.com/vmware/govmomi/vim25/types" + + "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 PerfManager + logger *logp.Logger +} + +func NewPerformanceDataFetcher(logger *logp.Logger, perfManager PerfManager) *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 { + value := result.Value[0] + if result.Unit == string(types.PerformanceManagerUnitPercent) { + metricMap[result.Name] = float64(value) / 100.0 + } else { + metricMap[result.Name] = value + } + 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/client/performance_test.go b/metricbeat/module/vsphere/client/performance_test.go new file mode 100644 index 000000000000..e0c60aae849a --- /dev/null +++ b/metricbeat/module/vsphere/client/performance_test.go @@ -0,0 +1,246 @@ +// 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/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. +//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.2, + }, 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) + }) + } +} diff --git a/metricbeat/module/vsphere/datastore/datastore.go b/metricbeat/module/vsphere/datastore/datastore.go index 956a1db23324..c1899048240b 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) } @@ -258,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 -} diff --git a/metricbeat/module/vsphere/fields.go b/metricbeat/module/vsphere/fields.go index c67607c61002..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 "eJzUXM1y2zgSvucpuuayyZajB/Bhq7JOzThV68xU7PjqgsCWiDUIcABQKuXppwDwTyJBSRRIWzr4IFPor3/R3WjwM7zi7hY2Ok9R4QcAwwzHW/ht8+i++e0DQIKaKpYbJsUt/OcDAED5X8hkUnD7M4UcicZbWJMPACuGPNG37tHPIEiGbRL2Y3a5fVjJIi+/6aGyv1B7McoLbVDV3/ctaD81rCUa0vq+l5j/3PmlgYmVVBmxjyxaDxwiaqNKiCHayJrJYWyh1dor2r+6899qxVfcbaVKev4/wF/1+R/TBuQKCOdgUmzAe6JAtJaUEYMJbJlJ3TOl2BdBvFQWwgTxcinW48B+L7IlKgu3hnkGwkY/+oVKsWKHKMYriCQZ09raCJXCKMkXKMiSY59SPJWllByJGCeHbyJhlBjUsE3RpKhAG8WoaXBAiQOYhhJKWF0zY62ixv0XWCExhcIgygphKvWhPY1X1vTWaeGOdJ0ZXd2iPNfLK5jsEMMQviPYfgr2d1HTg29f+0nav/GIVvHdrhqgh2Yr1esVmV2J+P1bXgl0rPEZxdZrVJi8EE5Uphf/7lWSXP4f6aHE/ZcvF1jOITM1GijRdNKUvoSg344GSPctsp9uVZ+h3ISSnFBmdouVQlwsd6aj8qA5HhHL7woR3IJWOHupxKHN+YzqFrrkOzCNNIRHxflkV4wPtNCYRMX5U2MyEcy84xUepKaEY/Ky4pIcPnAE7F+oKApD1riXnNV0wdENwM79j/tzNaZfFzX6mPK9cxlgYf1Ws18YQcj7WAtN1nE97ClFIJndRSxYC9LKuxYxLZRCYfgOlsjE2maAusicEV3MVa7khtm8MrKRf+mwo9EA0SxBC82ajYVPLmFgpS26eJnD74yj3mmDmVslnLAu+nb8sZI6SC4HqPbt4xG3uyZrnC0zbOLJPLnh170auJ+iQhLXFX4Q44KQXdi6r2UaVkpml4YlbYgpIhrEo1vvSLy8tlStjXmTTeS5zw9hihN77fPDkM9uFTNx96rKmu3KtTUbOcaWO1n0hF2/xvPvOkSG0upJg968hfFT2kc7HAgnSc58kl6nNi7WMF0nCblMboAJbygjMgKF+KJzQiPnZw60XRzc4iBFVNiN30wcLE7pAXdMJNRrrTBPE1JbfWAmzgF2LRtToAN6dvvg3qZtrcMMn1pUrVgUG6akyFCYxWX9hbzwNWaW/opZCN/99dMq+OH+VyAK5UXZK4hH2PvzKZRdMyUeYddKOUb3raLBm/u5FHUdEsDyfutwqSr4KIxFN64cT3DDKHJiUNDdgmzQIlhk0apyv2CLScMyBGbAkFfUNo+jMss5GgQi4PHu8Zv9IiMi8WElT3eaUcLBA7V2nDHOmUYqRRIyIctZxVPpy7E4umfrFLWBcnnYEF4gEKqk1s7QLXHtulRWTXWdezrw6PVgpQRR+4BvBlpCrbqQ6VdAQlPwEEcaVPwCIATfUjIo6logDv74beLHInNxx+JzIrfG7cQEyp1mtkBfkNNNUDg4ww3VChlmUk3V/X9wi18gjRLdVE3/WPim6fVfjC5uHXhf9fkGT0dfIicf39sng4OUp057xOlIpkl56tPcowlPhWNJRLJliUkXRhGhMxtpp9mUbAgEYmCbMpr65s6WaGiRhaRQNvuxyJkwqDaEL+DJlsMKc4UahdHuvzXqqqVYsXO+A3TkoJAi28wrhIrm+5DAZDtj5R9tnds9smbfb5NVOOuVxmj+ckJf0eg9O5/GC0tKbTaHnbCCVpvetLhqMieBQqWkmlNsrl/kqZ4vwhLtTJJsQx0nVedqMUH6tEUMQT0NYVZwwyjRZgbV17TG+04Dd2Ldd7Gep/mWXCdXfgfraRATJfMckxkU394JKnFW1M+COrHS6x3qIpDzefsgvNinu08pgrQJDueQIuEmLUm43Ljuitht/Ejz+Pp67W3MRW5YoJwa1zF09lIuuy/Lsrnkovq5on3rk+PJzso3TJmCcMgITZkItX3Ds7rRjoTLivSzcv3WZMyFEEIpas2WvN+e+sfrj0iqO1ZPDFjmDEhRdS810GbKzUhwY1wJ+lPJ3iKjGVa2v1vEji5d1Fan5TRVSjQkaJC6UqKG7o+rmNbFwKxVL8R3dtXmuztMLUs8f0WASiE8v64fGtIKvMHthROhTdjIrCrMeeYerHYG6++pdtw/UNjtttptT4EQd6DxaZcfcg4fcbFe3FTB7+OjISIhKvl0A1+ZNootC4PJs4/RuVTmU2h7uDrH7Gw879JHx6K8tpSsGbfUslAUcyn5FLv8j3J9sATOnpM4MhERzQf8WXZ30AAi2NZ/iWbUTR3kqBz7gqILdkwbRvVN7zRCG12CGRF9kx/vA547ceeYHV41aOPrUwoMKKa9fj/fR3k/kX/oDB5YWVRuUXF/AyYlxvv/84O/Vum4tmHhBogGSjgtfCa73MHXH49dgcHBZsdoQKexefPE9hhra83dCCCHoW+2dETthYjhA9a4Hj+Jua4L1Kb3YGCfxuWq/cNSKgUDhWGc/fKh9cB7e489a5aCZwOHjLkKcQ6+3AnppGzNFbrmkNZ+8PJia+QTLXCdYyllcJuL+zK8lRZzeoSLZUW5YhsSGPM5yusJfFoebS1gfSCsYqZhrYgoM9UOsz7fElJ81imxGWHaeFkf+6ex7te6Bs5b7Na/KiWxRLNFFN1rJGdJYktcM/kKRFG1Sf6lHWo/VD+e8yXhXAZvMMbivX2XtKQIiWIb9yqZc337NMbkBlWKJPz+jmvcGpr4+LGS0CdvO1vGOSyxHtbsWg9Zyg0CM9onOc2KfxdMuUAbIc2oxnpn2z4aCVUK7/Gu4PCxkaAKa4DPD5ftIlRmuUIdGoE7yvWJftRw2xCsFNkw2Z6tfn4Y60zTXaQSrabiXv1wvYd5EVt6b9AmK0+RBnQBM/ccR0C81iZeyWrJ6dE23gD94Ern31iKenrUaTtAHGvxt7cGXuFluegJXxHJt0NZeBR1gr7L4e4+z3HQ8wHV8CS0jBiwD6n+maMi7gL1oz8jHbiHO/HNu3T2m3c/UKPanAgh8hW8LxvCOFlyPEq8fScg3FO7SAVl2iNXZSstzgWGYJ8sEtbyxmmUuyDxBetNLLpknRnGR+uu18QDSwttZPbid7M5c4Y7R7jcRt/bxZKrem/r3pl1c0W3dVW/Ogfez5Xe30tbT8EZnvOCq1BQ35sZ359+xqKcqnz9c790JSLZK19POgiMPsfZTHCW05HNBGdAKoLkOpURiwyxkp1SD4ZDN5wWvjsy+IqGMF7bccWLrl/JMp/1un5KbavnIbmWivmfAAAA//9lhV/l" + return "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" } 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/_meta/fields.yml b/metricbeat/module/vsphere/virtualmachine/_meta/fields.yml index eb6cc6d88e52..ba5717806357 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.usage.percent + type: scaled_float + 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.usage.percent + type: scaled_float + 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.bytes + type: long + description: > + Aggregated disk I/O rate. + - name: read.average.bytes + type: long + description: > + Rate at which data is read from each virtual disk on the virtual machine. + - name: write.average.bytes + type: long + description: > + Rate at which data is written to each virtual disk on the virtual machine. + - name: numberRead.count + type: long + description: > + Number of times data was read. + - 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 0839f5789cca..24735bf1e3ad 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 @@ -78,6 +79,36 @@ 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.usage.percent", val) + } + if val, ok := data.PerformanceData["disk.usage.average"]; ok { + intVal, assertOk := val.(int64) + if assertOk { + event.Put("disk.average.bytes", intVal*kilobytesToBytesMultiplier) + } + } + if val, ok := data.PerformanceData["disk.read.average"]; ok { + intVal, assertOk := val.(int64) + if assertOk { + event.Put("disk.read.average.bytes", intVal*kilobytesToBytesMultiplier) + } + } + if val, ok := data.PerformanceData["disk.write.average"]; ok { + 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.count", val) + } + if val, ok := data.PerformanceData["disk.numberWrite.summation"]; ok { + event.Put("disk.numberWrite.count", val) + } + if val, ok := data.PerformanceData["mem.usage.average"]; ok { + event.Put("memory.usage.percent", val) + } 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 74a661576feb902f9f1de6445beeec3a95f25182 Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Tue, 27 May 2025 15:02:47 +0300 Subject: [PATCH 2/4] clean up changelog --- CHANGELOG.next.asciidoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 9167c36eed50..3fbf3355c330 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -253,8 +253,6 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff] - Add new metricset network for the vSphere module. {pull}40559[40559] - Add new metricset resourcepool for the vSphere module. {pull}40456[40456] - 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] - Added checks for the Resty response object in all Meraki module API calls to ensure proper handling of nil responses. {pull}44193[44193] - Add latency config option to Azure Monitor module. {pull}44366[44366] From 16f7e623db975ba6f0da9160b6dd469285ad2860 Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Tue, 27 May 2025 15:10:56 +0300 Subject: [PATCH 3/4] go mod tidy --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 37b75f839070..5a4bff8e7da9 100644 --- a/go.mod +++ b/go.mod @@ -176,7 +176,7 @@ require ( github.com/elastic/bayeux v1.0.5 github.com/elastic/ebpfevents v0.6.0 github.com/elastic/elastic-agent-autodiscover v0.9.0 - github.com/elastic/elastic-agent-libs v0.19.1 + github.com/elastic/elastic-agent-libs v0.19.5 github.com/elastic/elastic-agent-system-metrics v0.11.10 github.com/elastic/go-elasticsearch/v8 v8.17.1 github.com/elastic/go-quark v0.3.0 diff --git a/go.sum b/go.sum index f54d9494d6ed..fe95142631f8 100644 --- a/go.sum +++ b/go.sum @@ -342,8 +342,8 @@ github.com/elastic/elastic-agent-autodiscover v0.9.0 h1:+iWIKh0u3e8I+CJa3FfWe9h0 github.com/elastic/elastic-agent-autodiscover v0.9.0/go.mod h1:5iUxLHhVdaGSWYTveSwfJEY4RqPXTG13LPiFoxcpFd4= github.com/elastic/elastic-agent-client/v7 v7.15.0 h1:nDB7v8TBoNuD6IIzC3z7Q0y+7bMgXoT2DsHfolO2CHE= github.com/elastic/elastic-agent-client/v7 v7.15.0/go.mod h1:6h+f9QdIr3GO2ODC0Y8+aEXRwzbA5W4eV4dd/67z7nI= -github.com/elastic/elastic-agent-libs v0.19.1 h1:6jiH0SPB5RzoF3W8Ipk+mI/Xl6zXqVPZkKADuzeChw0= -github.com/elastic/elastic-agent-libs v0.19.1/go.mod h1:1HNxREH8C27kGrJCtKZh/ot8pV8joH8VREP21+FrH5s= +github.com/elastic/elastic-agent-libs v0.19.5 h1:br0kvmwowHu4KQpPy5C4DjkFdiGafbp8BV4CeXR4wUs= +github.com/elastic/elastic-agent-libs v0.19.5/go.mod h1:1HNxREH8C27kGrJCtKZh/ot8pV8joH8VREP21+FrH5s= github.com/elastic/elastic-agent-system-metrics v0.11.10 h1:51u6roLaI0WhX1wbU4hPaervODegOxNFLcLouDAAi8A= github.com/elastic/elastic-agent-system-metrics v0.11.10/go.mod h1:BlS6Fm/l/umAa9xKy7GxsSYtCfu/iqg551PULKSeCQM= github.com/elastic/elastic-transport-go/v8 v8.6.1 h1:h2jQRqH6eLGiBSN4eZbQnJLtL4bC5b4lfVFRjw2R4e4= From 20549419d71cf43114b737e50127b44f910fafb7 Mon Sep 17 00:00:00 2001 From: stefans-elastic Date: Tue, 27 May 2025 15:15:07 +0300 Subject: [PATCH 4/4] update NOTICE.txt --- NOTICE.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 12b0d9fc9fc3..81a6d0901707 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -12317,11 +12317,11 @@ SOFTWARE -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-libs -Version: v0.19.1 +Version: v0.19.5 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.19.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.19.5/LICENSE: Apache License Version 2.0, January 2004