Skip to content

Commit 18094c4

Browse files
[8.19](backport #44205) capture extra vsphere metrics (cpu %, disk average, disk rate, disk n… (#44495)
* capture extra vsphere metrics (cpu %, disk average, disk rate, disk n… (#44205) * 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 14ac057) # Conflicts: # auditbeat/module/file_integrity/mock_performance.go # auditbeat/module/file_integrity/performance.go # auditbeat/module/file_integrity/performance_test.go * resolve merge * clean up changelog * fix missing imports * update docs/fields.asciidoc * fix linter --------- Co-authored-by: stefans-elastic <stefan.stas@elastic.co>
1 parent e391eaf commit 18094c4

File tree

11 files changed

+660
-144
lines changed

11 files changed

+660
-144
lines changed

CHANGELOG.next.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ otherwise no tag is added. {issue}42208[42208] {pull}42403[42403]
454454
- Add a warning log to metricbeat.vsphere in case vSphere connection has been configured as insecure. {pull}43104[43104]
455455
- Upgrade Prometheus Library to v0.300.1. {pull}43540[43540]
456456
- Updated Meraki API endpoint for Channel Utilization data. Switched to `GetOrganizationWirelessDevicesChannelUtilizationByDevice`. {pull}43485[43485]
457+
- 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]
457458
- Added checks for the Resty response object in all Meraki module API calls to ensure proper handling of nil responses. {pull}44193[44193]
458459
- Add latency config option to Azure Monitor module. {pull}44366[44366]
459460

metricbeat/docs/fields.asciidoc

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69629,6 +69629,16 @@ type: long
6962969629

6963069630
--
6963169631

69632+
*`vsphere.virtualmachine.cpu.usage.percent`*::
69633+
+
69634+
--
69635+
CPU usage as a percentage.
69636+
69637+
69638+
type: scaled_float
69639+
69640+
--
69641+
6963269642
*`vsphere.virtualmachine.memory.used.guest.bytes`*::
6963369643
+
6963469644
--
@@ -69677,6 +69687,16 @@ format: bytes
6967769687

6967869688
--
6967969689

69690+
*`vsphere.virtualmachine.memory.usage.percent`*::
69691+
+
69692+
--
69693+
Memory usage as percent of total configured or available memory.
69694+
69695+
69696+
type: scaled_float
69697+
69698+
--
69699+
6968069700
*`vsphere.virtualmachine.custom_fields`*::
6968169701
+
6968269702
--
@@ -69788,6 +69808,57 @@ type: object
6978869808

6978969809
--
6979069810

69811+
69812+
*`vsphere.virtualmachine.disk.average.bytes`*::
69813+
+
69814+
--
69815+
Aggregated disk I/O rate.
69816+
69817+
69818+
type: long
69819+
69820+
--
69821+
69822+
*`vsphere.virtualmachine.disk.read.average.bytes`*::
69823+
+
69824+
--
69825+
Rate at which data is read from each virtual disk on the virtual machine.
69826+
69827+
69828+
type: long
69829+
69830+
--
69831+
69832+
*`vsphere.virtualmachine.disk.write.average.bytes`*::
69833+
+
69834+
--
69835+
Rate at which data is written to each virtual disk on the virtual machine.
69836+
69837+
69838+
type: long
69839+
69840+
--
69841+
69842+
*`vsphere.virtualmachine.disk.numberRead.count`*::
69843+
+
69844+
--
69845+
Number of times data was read.
69846+
69847+
69848+
type: long
69849+
69850+
--
69851+
69852+
*`vsphere.virtualmachine.disk.numberWrite.count`*::
69853+
+
69854+
--
69855+
Number of disk writes.
69856+
69857+
69858+
type: long
69859+
69860+
--
69861+
6979169862
[[exported-fields-windows]]
6979269863
== Windows fields
6979369864

metricbeat/module/vsphere/client/mock_performance.go

Lines changed: 105 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package client
19+
20+
import (
21+
"context"
22+
"fmt"
23+
"strings"
24+
25+
"github.com/vmware/govmomi/performance"
26+
"github.com/vmware/govmomi/vim25/types"
27+
28+
"github.com/elastic/elastic-agent-libs/logp"
29+
)
30+
31+
type PerfManager interface {
32+
AvailableMetric(ctx context.Context, entity types.ManagedObjectReference, interval int32) (performance.MetricList, error)
33+
Query(ctx context.Context, spec []types.PerfQuerySpec) ([]types.BasePerfEntityMetricBase, error)
34+
ToMetricSeries(ctx context.Context, series []types.BasePerfEntityMetricBase) ([]performance.EntityMetric, error)
35+
}
36+
37+
type PerformanceDataFetcher struct {
38+
perfManager PerfManager
39+
logger *logp.Logger
40+
}
41+
42+
func NewPerformanceDataFetcher(logger *logp.Logger, perfManager PerfManager) *PerformanceDataFetcher {
43+
return &PerformanceDataFetcher{
44+
logger: logger,
45+
perfManager: perfManager,
46+
}
47+
}
48+
49+
func (p *PerformanceDataFetcher) GetPerfMetrics(ctx context.Context,
50+
period int32,
51+
objectType string,
52+
objectName string,
53+
objectReference types.ManagedObjectReference,
54+
metrics map[string]*types.PerfCounterInfo,
55+
metricSet map[string]struct{}) (metricMap map[string]interface{}, err error) {
56+
57+
metricMap = make(map[string]interface{})
58+
59+
availableMetric, err := p.perfManager.AvailableMetric(ctx, objectReference, period)
60+
if err != nil {
61+
return nil, fmt.Errorf("failed to get available metrics: %w", err)
62+
}
63+
64+
availableMetricByKey := availableMetric.ByKey()
65+
66+
// Filter for required metrics
67+
var metricIDs []types.PerfMetricId
68+
for key, metric := range metricSet {
69+
if counter, ok := metrics[key]; ok {
70+
if _, exists := availableMetricByKey[counter.Key]; exists {
71+
metricIDs = append(metricIDs, types.PerfMetricId{
72+
CounterId: counter.Key,
73+
Instance: "*",
74+
})
75+
}
76+
} else {
77+
p.logger.Warnf("Metric %s not found", metric)
78+
}
79+
}
80+
81+
spec := types.PerfQuerySpec{
82+
Entity: objectReference,
83+
MetricId: metricIDs,
84+
MaxSample: 1,
85+
IntervalId: period,
86+
}
87+
88+
// Query performance data
89+
samples, err := p.perfManager.Query(ctx, []types.PerfQuerySpec{spec})
90+
if err != nil {
91+
if strings.Contains(err.Error(), "ServerFaultCode: A specified parameter was not correct: querySpec.interval") {
92+
return metricMap, fmt.Errorf("failed to query performance data: use one of the system's supported interval. consider adjusting period: %w", err)
93+
}
94+
95+
return metricMap, fmt.Errorf("failed to query performance data: %w", err)
96+
}
97+
98+
if len(samples) == 0 {
99+
p.logger.Debug("No samples returned from performance manager")
100+
return metricMap, nil
101+
}
102+
103+
results, err := p.perfManager.ToMetricSeries(ctx, samples)
104+
if err != nil {
105+
return metricMap, fmt.Errorf("failed to convert performance data to metric series: %w", err)
106+
}
107+
108+
if len(results) == 0 {
109+
p.logger.Debug("No results returned from metric series conversion")
110+
return metricMap, nil
111+
}
112+
113+
for _, result := range results[0].Value {
114+
if len(result.Value) > 0 {
115+
value := result.Value[0]
116+
if result.Unit == string(types.PerformanceManagerUnitPercent) {
117+
metricMap[result.Name] = float64(value) / 100.0
118+
} else {
119+
metricMap[result.Name] = value
120+
}
121+
continue
122+
}
123+
p.logger.Debugf("For %s %s, Metric %s: No result found", objectType, objectName, result.Name)
124+
}
125+
126+
return metricMap, nil
127+
}

0 commit comments

Comments
 (0)