Skip to content

Commit 55edeb2

Browse files
stefans-elasticishleenk17
authored andcommitted
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)
1 parent 39b2ad7 commit 55edeb2

File tree

10 files changed

+582
-141
lines changed

10 files changed

+582
-141
lines changed

CHANGELOG.next.asciidoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff]
293293
- Bump aerospike-client-go to version v7.7.1 and add support for basic auth in Aerospike module {pull}41233[41233]
294294
- Only watch metadata for ReplicaSets in metricbeat k8s module {pull}41289[41289]
295295
- Updated Meraki API endpoint for Channel Utilization data. Switched to `GetOrganizationWirelessDevicesChannelUtilizationByDevice`. {pull}43485[43485]
296+
- Upgrade Prometheus Library to v0.300.1. {pull}43540[43540]
297+
- Add GCP Dataproc metadata collector in GCP module. {pull}43518[43518]
298+
- 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]
296299
- Added checks for the Resty response object in all Meraki module API calls to ensure proper handling of nil responses. {pull}44193[44193]
297300
- Add `enable_batch_api` option in azure monitor to allow metrics collection of multiple resources using azure batch Api {pull}41790[41790]
298301

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)