Skip to content

Commit

Permalink
Add instance_name config option
Browse files Browse the repository at this point in the history
  • Loading branch information
martinscholz83 committed Jul 12, 2017
1 parent c43b2fd commit ede619f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 20 deletions.
5 changes: 5 additions & 0 deletions metricbeat/module/windows/perfmon/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ You must configure queries for the Windows performance counters that you wish
to collect. The example below collects processor time and disk writes.
With `format` you can set the output format for a specific counter. Possible values are
`float` and `long`. If nothing is selected the default value is `float`.
There is also an optional/required option `instance_name`.
You have to set this in two cases. First if you want to name your instance other then it is computed. e.g `Total` instead of `_Total`.
And second if you specify a counter which has no instance, for example: `\TCPIP Performance Diagnostics\IPv4 NBLs/sec indicated without prevalidation`.
Then this option is required. For wildcard queries this option is needles.

[source,yaml]
----
Expand All @@ -18,6 +22,7 @@ With `format` you can set the output format for a specific counter. Possible val
period: 10s
perfmon.counters:
- instance_label: "processor.name"
instance_name: "Total"
measurement_label: "processor.time.total.pct"
query: '\Processor Information(_Total)\% Processor Time'
- instance_label: "diskio.name"
Expand Down
42 changes: 26 additions & 16 deletions metricbeat/module/windows/perfmon/pdh_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,9 @@ func PdhCloseQuery(query PdhQueryHandle) error {
}

type Counter struct {
handle PdhCounterHandle
format PdhCounterFormat
handle PdhCounterHandle
format PdhCounterFormat
instanceName *string
}

type Counters map[string]*Counter
Expand Down Expand Up @@ -193,7 +194,7 @@ func NewQuery(dataSource string) (*Query, error) {
}, nil
}

func (q *Query) AddCounter(counterPath string, format Format) error {
func (q *Query) AddCounter(counterPath string, format Format, instanceName *string) error {
if _, found := q.counters[counterPath]; found {
return errors.New("counter already added")
}
Expand All @@ -204,6 +205,7 @@ func (q *Query) AddCounter(counterPath string, format Format) error {
}

q.counters[counterPath] = &Counter{handle: h}
q.counters[counterPath].instanceName = instanceName
switch format {
case FloatFlormat:
q.counters[counterPath].format = PdhFmtDouble
Expand Down Expand Up @@ -255,9 +257,17 @@ func (q *Query) Values() (map[string][]Value, error) {
continue
}

re := regexp.MustCompile("\\((.*)\\)")
match := re.FindStringSubmatch(path)
name := match[1]
var name string
if counter.instanceName != nil {
name = *counter.instanceName
} else {
re := regexp.MustCompile("\\((.*)\\)")
match := re.FindStringSubmatch(path)
if cap(match) <= 0 {
return nil, errors.New("Your query doesn't contain an instance name. In this case you have to define one per `instance_name`")
}
name = match[1]
}

switch counter.format {
case PdhFmtDouble:
Expand All @@ -277,10 +287,10 @@ func (q *Query) Close() error {
}

type PerfmonReader struct {
query *Query // PDH Query
instance map[string]string // Mapping of counter path to key used in output.
measurement map[string]string
executed bool // Indicates if the query has been executed.
query *Query // PDH Query
instanceLabel map[string]string // Mapping of counter path to key used in output.
measurement map[string]string
executed bool // Indicates if the query has been executed.
}

func NewPerfmonReader(config []CounterConfig) (*PerfmonReader, error) {
Expand All @@ -290,9 +300,9 @@ func NewPerfmonReader(config []CounterConfig) (*PerfmonReader, error) {
}

r := &PerfmonReader{
query: query,
instance: map[string]string{},
measurement: map[string]string{},
query: query,
instanceLabel: map[string]string{},
measurement: map[string]string{},
}

for _, counter := range config {
Expand All @@ -303,12 +313,12 @@ func NewPerfmonReader(config []CounterConfig) (*PerfmonReader, error) {
case "long":
format = LongFormat
}
if err := query.AddCounter(counter.Query, format); err != nil {
if err := query.AddCounter(counter.Query, format, counter.InstanceName); err != nil {
query.Close()
return nil, err
}

r.instance[counter.Query] = counter.InstanceLabel
r.instanceLabel[counter.Query] = counter.InstanceLabel
r.measurement[counter.Query] = counter.MeasurementLabel

}
Expand All @@ -334,7 +344,7 @@ func (r *PerfmonReader) Read() ([]common.MapStr, error) {
for counterPath, counter := range values {
for _, val := range counter {
ev := common.MapStr{}
instanceKey := r.instance[counterPath]
instanceKey := r.instanceLabel[counterPath]
ev.Put(instanceKey, val.Instance)
measurementKey := r.measurement[counterPath]
ev.Put(measurementKey, val.Measurement)
Expand Down
9 changes: 5 additions & 4 deletions metricbeat/module/windows/perfmon/perfmon.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import (
)

type CounterConfig struct {
InstanceLabel string `config:"instance_label" validate:"required"`
MeasurementLabel string `config:"measurement_label" validate:"required"`
Query string `config:"query" validate:"required"`
Format string `config:"format"`
InstanceLabel string `config:"instance_label" validate:"required"`
InstanceName *string `config:"instance_name"`
MeasurementLabel string `config:"measurement_label" validate:"required"`
Query string `config:"query" validate:"required"`
Format string `config:"format"`
}

func init() {
Expand Down

0 comments on commit ede619f

Please sign in to comment.