Skip to content

Commit

Permalink
Changed collection method of the second counter value in the Windows …
Browse files Browse the repository at this point in the history
…Perfmon module of Metricbeat (#32305)

* changed collection method of the second counter value required to create a displayable value

Co-authored-by: Craig MacKenzie <craig.mackenzie@elastic.co>
Co-authored-by: Dan Kortschak <90160302+efd6@users.noreply.github.com>
Co-authored-by: Tiago Queiroz <contato@tiago.eti.br>
(cherry picked from commit f0bc6c8)

# Conflicts:
#	metricbeat/module/windows/perfmon/reader.go
  • Loading branch information
jorgeta authored and mergify[bot] committed Sep 6, 2022
1 parent c3d36e1 commit 02945c2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 39 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d

*Metricbeat*

- in module/windows/perfmon, changed collection method of the second counter value required to create a displayable value {pull}32305[32305]
- Fix and improve AWS metric period calculation to avoid zero-length intervals {pull}32724[32724]

*Packetbeat*
Expand Down
60 changes: 21 additions & 39 deletions metricbeat/module/windows/perfmon/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,21 @@ import (
"fmt"
"regexp"
"strings"
"time"
"unicode"

"github.com/elastic/beats/v7/metricbeat/helper/windows/pdh"

<<<<<<< HEAD
"github.com/pkg/errors"

"math/rand"

"golang.org/x/sys/windows"

"github.com/elastic/beats/v7/libbeat/logp"
=======
>>>>>>> f0bc6c8012 (Changed collection method of the second counter value in the Windows Perfmon module of Metricbeat (#32305))
"github.com/elastic/beats/v7/metricbeat/mb"
)

Expand All @@ -52,7 +56,6 @@ type Reader struct {
log *logp.Logger //
config Config // Metricset configuration
counters []PerfCounter
event windows.Handle
}

type PerfCounter struct {
Expand All @@ -72,18 +75,13 @@ func NewReader(config Config) (*Reader, error) {
if err := query.Open(); err != nil {
return nil, err
}
event, err := windows.CreateEvent(nil, 0, 0, nil)
if err != nil {
return nil, err
}
r := &Reader{
query: query,
log: logp.NewLogger("perfmon"),
config: config,
event: event,
}
r.mapCounters(config)
_, err = r.getCounterPaths()
_, err := r.getCounterPaths()
if err != nil {
return nil, err
}
Expand All @@ -94,11 +92,11 @@ func NewReader(config Config) (*Reader, error) {
func (re *Reader) RefreshCounterPaths() error {
newCounters, err := re.getCounterPaths()
if err != nil {
return errors.Wrap(err, "failed retrieving counter paths")
return fmt.Errorf("failed retrieving counter paths: %w", err)
}
err = re.query.RemoveUnusedCounters(newCounters)
if err != nil {
return errors.Wrap(err, "failed removing unused counter values")
return fmt.Errorf("failed removing unused counter values: %w", err)
}
return nil
}
Expand All @@ -110,17 +108,17 @@ func (re *Reader) Read() ([]mb.Event, error) {
if err := re.query.CollectData(); err != nil {
// users can encounter the case no counters are found (services/processes stopped), this should not generate an event with the error message,
//could be the case the specific services are started after and picked up by the next RefreshCounterPaths func
if err == pdh.PDH_NO_COUNTERS {
if err == pdh.PDH_NO_COUNTERS { //nolint:errorlint // Bad linter! This is always errno or nil.
re.log.Warnf("%s %v", collectFailedMsg, err)
} else {
return nil, errors.Wrap(err, collectFailedMsg)
return nil, fmt.Errorf("%v: %w", collectFailedMsg, err)
}
}

// Get the values.
values, err := re.getValues()
if err != nil {
return nil, errors.Wrap(err, "failed formatting counter values")
return nil, fmt.Errorf("failed formatting counter values: %w", err)
}
var events []mb.Event
// GroupAllCountersTo config option where counters for all instances are aggregated and instance count is added in the event under the string value provided by this option.
Expand All @@ -135,41 +133,25 @@ func (re *Reader) Read() ([]mb.Event, error) {

func (re *Reader) getValues() (map[string][]pdh.CounterValue, error) {
var val map[string][]pdh.CounterValue
var sec uint32 = 1
err := re.query.CollectDataEx(sec, re.event)
// Sleep for one second before collecting the second raw value-
time.Sleep(time.Second)

// Collect the second raw value.
err := re.query.CollectData()
if err != nil {
return nil, err
}
waitFor, err := windows.WaitForSingleObject(re.event, windows.INFINITE)

// Collect the displayable value.
val, err = re.query.GetFormattedCounterValues()
if err != nil {
return nil, err
}
switch waitFor {
case windows.WAIT_OBJECT_0:
val, err = re.query.GetFormattedCounterValues()
if err != nil {
return nil, err
}
case windows.WAIT_FAILED:
return nil, errors.New("WaitForSingleObject has failed")
default:
return nil, errors.New("WaitForSingleObject was abandoned or still waiting for completion")
}
return val, err
}

func randSeq(n int) string {
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}

// Close will close the PDH query for now.
func (re *Reader) Close() error {
defer windows.CloseHandle(re.event)
return re.query.Close()
}

Expand All @@ -181,23 +163,23 @@ func (re *Reader) getCounterPaths() ([]string, error) {
childQueries, err := re.query.GetCounterPaths(counter.QueryName)
if err != nil {
if re.config.IgnoreNECounters {
switch err {
switch err { //nolint:errorlint // Bad linter! This is always errno or nil.
case pdh.PDH_CSTATUS_NO_COUNTER, pdh.PDH_CSTATUS_NO_COUNTERNAME,
pdh.PDH_CSTATUS_NO_INSTANCE, pdh.PDH_CSTATUS_NO_OBJECT:
re.log.Infow("Ignoring non existent counter", "error", err,
logp.Namespace("perfmon"), "query", counter.QueryName)
continue
}
} else {
return newCounters, errors.Wrapf(err, `failed to expand counter (query="%v")`, counter.QueryName)
return newCounters, fmt.Errorf("failed to expand counter (query='%v'): %w", counter.QueryName, err)
}
}
newCounters = append(newCounters, childQueries...)
// there are cases when the ExpandWildCardPath will retrieve a successful status but not an expanded query so we need to check for the size of the list
if err == nil && len(childQueries) >= 1 && !strings.Contains(childQueries[0], "*") {
for _, v := range childQueries {
if err := re.query.AddCounter(v, counter.InstanceName, counter.Format, isWildcard(childQueries, counter.InstanceName)); err != nil {
return newCounters, errors.Wrapf(err, "failed to add counter (query='%v')", counter.QueryName)
return newCounters, fmt.Errorf("failed to add counter (query='%v'): %w", counter.QueryName, err)
}
re.counters[i].ChildQueries = append(re.counters[i].ChildQueries, v)
}
Expand Down

0 comments on commit 02945c2

Please sign in to comment.