Skip to content

Commit

Permalink
Add refresh list of perf counters at every fetch elastic#13091
Browse files Browse the repository at this point in the history
  • Loading branch information
narph committed Aug 26, 2019
1 parent 9cfc4e3 commit b8d25c5
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Expand Up @@ -320,6 +320,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Add AWS elb metricset. {pull}12952[12952] {issue}11701[11701]
- Add AWS ebs metricset. {pull}13167[13167] {issue}11699[11699]
- Add rate metrics for ec2 metricset. {pull}13203[13203]
- Add refresh list of perf counters at every fetch {issue}13091[13091]

*Packetbeat*

Expand Down
5 changes: 4 additions & 1 deletion metricbeat/module/windows/perfmon/pdh_query_windows.go
Expand Up @@ -67,7 +67,7 @@ func (q *Query) Open() error {
// AddCounter adds the specified counter to the query.
func (q *Query) AddCounter(counterPath string, counter CounterConfig, wildcard bool) error {
if _, found := q.counters[counterPath]; found {
return errors.Errorf("counter %s has been already added", counterPath)
return nil
}
var err error
var instanceName string
Expand Down Expand Up @@ -130,6 +130,9 @@ func (q *Query) ExpandWildCardPath(wildCardPath string) ([]string, error) {
if err != nil {
return nil, err
}
if expdPaths == nil {
return nil, errors.New("No counter paths found")
}
return UTF16ToStringArray(expdPaths), nil
}

Expand Down
10 changes: 6 additions & 4 deletions metricbeat/module/windows/perfmon/perfmon.go
Expand Up @@ -20,9 +20,8 @@
package perfmon

import (
"strings"

"github.com/pkg/errors"
"strings"

"github.com/elastic/beats/libbeat/common/cfgwarn"
"github.com/elastic/beats/libbeat/logp"
Expand Down Expand Up @@ -80,7 +79,6 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
if err != nil {
return nil, errors.Wrap(err, "initialization of reader failed")
}

return &MetricSet{
BaseMetricSet: base,
reader: reader,
Expand All @@ -89,13 +87,17 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
}

func (m *MetricSet) Fetch(report mb.ReporterV2) {
var err error
// refresh performance counter list
if m.reader.executed {
err = m.reader.RefreshCounterPaths()
}
events, err := m.reader.Read()
if err != nil {
m.log.Debugw("Failed reading counters", "error", err)
err = errors.Wrap(err, "failed reading counters")
report.Error(err)
}

for _, event := range events {
report.Event(event)
}
Expand Down
54 changes: 42 additions & 12 deletions metricbeat/module/windows/perfmon/reader.go
Expand Up @@ -37,12 +37,12 @@ var (

// Reader will contain the config options
type Reader struct {
query Query // PDH Query
instanceLabel map[string]string // Mapping of counter path to key used for the label (e.g. processor.name)
measurement map[string]string // Mapping of counter path to key used for the value (e.g. processor.cpu_time).
executed bool // Indicates if the query has been executed.
log *logp.Logger //
groupMeasurements bool // Indicates if measurements with the same instance label should be sent in the same event
query Query // PDH Query
instanceLabel map[string]string // Mapping of counter path to key used for the label (e.g. processor.name)
measurement map[string]string // Mapping of counter path to key used for the value (e.g. processor.cpu_time).
executed bool // Indicates if the query has been executed.
log *logp.Logger //
config Config // Metricset configuration
}

// NewReader creates a new instance of Reader.
Expand All @@ -53,11 +53,11 @@ func NewReader(config Config) (*Reader, error) {
}

r := &Reader{
query: query,
instanceLabel: map[string]string{},
measurement: map[string]string{},
log: logp.NewLogger("perfmon"),
groupMeasurements: config.GroupMeasurements,
query: query,
instanceLabel: map[string]string{},
measurement: map[string]string{},
log: logp.NewLogger("perfmon"),
config: config,
}
for _, counter := range config.CounterConfig {
childQueries, err := query.ExpandWildCardPath(counter.Query)
Expand Down Expand Up @@ -94,8 +94,38 @@ func NewReader(config Config) (*Reader, error) {
return r, nil
}

// RefreshCounterPaths will recheck for any new instances and add them to the counter list
func (r *Reader) RefreshCounterPaths() error {
for _, counter := range r.config.CounterConfig {
if !strings.Contains(counter.Query, "*") {
continue
}
childQueries, err := r.query.ExpandWildCardPath(counter.Query)
if err == nil && len(childQueries) >= 1 && !strings.Contains(childQueries[0], "*") {
for _, v := range childQueries {
if err := r.query.AddCounter(v, counter, len(childQueries) > 1); err != nil {
r.query.Close()
return errors.Wrapf(err, `failed to add counter (query="%v")`, counter.Query)
}
r.instanceLabel[v] = counter.InstanceLabel
r.measurement[v] = counter.MeasurementLabel
}
// Some counters, such as rate counters, require two counter values in order to compute a displayable value. In this case we must call PdhCollectQueryData twice before calling PdhGetFormattedCounterValue.
// For more information, see Collecting Performance Data (https://docs.microsoft.com/en-us/windows/desktop/PerfCtrs/collecting-performance-data).
if err := r.query.CollectData(); err != nil {
return errors.Wrap(err, "failed querying counter values")
}
}
}
return nil
}

// Read executes a query and returns those values in an event.
func (r *Reader) Read() ([]mb.Event, error) {
//if r.config.IgnoreNECounters && len(r.query.counters) == 0 {
// return nil, nil
//}

if err := r.query.CollectData(); err != nil {
return nil, errors.Wrap(err, "failed querying counter values")
}
Expand All @@ -119,7 +149,7 @@ func (r *Reader) Read() ([]mb.Event, error) {
}

var eventKey string
if r.groupMeasurements && val.Err == nil {
if r.config.GroupMeasurements && val.Err == nil {
// Send measurements with the same instance label as part of the same event
eventKey = val.Instance
} else {
Expand Down

0 comments on commit b8d25c5

Please sign in to comment.