Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perfmon metricset output format option #3976

Merged
merged 12 commits into from May 4, 2017

Conversation

martinscholz83
Copy link
Contributor

This PR adds the a new config option format for the perfmon metricset. Possible values are float, uint64 and uint32. The default value is float. My first approach was to set the format for all counters. But i think to define it on counter level gives the user more flexibility.

@elasticmachine
Copy link
Collaborator

Jenkins standing by to test this. If you aren't a maintainer, you can ignore this comment. Someone with commit access, please review this and clear it for Jenkins to run.

1 similar comment
@elasticmachine
Copy link
Collaborator

Jenkins standing by to test this. If you aren't a maintainer, you can ignore this comment. Someone with commit access, please review this and clear it for Jenkins to run.

// PdhFmtLong returns data as a long integer.
PdhFmtLong = C.PDH_FMT_LONG
PdhFmtLong PdhCounterFormat = C.PDH_FMT_LONG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like other formatters below also should have the same PdhCounterFormat type applied.

}, nil
}

func (q *Query) AddCounter(counterPath string) error {
func (q *Query) AddCounter(counterPath string, format string) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From an API perspective I would not allow a free-form string for format. I would declare an enum for the allowed format types. And then inside of the function reject unknown format enum values with an error.

@@ -3,15 +3,20 @@
package perfmon

import (
"strings"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the newline between stdlib imports and sort them.

@@ -37,6 +42,18 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
return nil, err
}

for _, value := range config.CounterConfig {
form := strings.ToLower(value.Format)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a switch here.

switch strings.ToLower(value.Format) {
case "":
  // use float
case "float", "uint32", "uint64":
default:
  // error
}

@@ -8,6 +8,8 @@ performance counters.

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 an specific counter. Possible values are
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes sense to expose the intricacies of uint32 vs uint64 because JSON doesn't make any distinction between these types. Maybe just offer float and long (and long uses uint64 under the hood).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: should say "for a specific counter"

switch format {
case "float":
q.counters[counterPath].format = PdhFmtDouble
case "uint64":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't these actually be called int64 and int32? I didn't see any mention that the values are unsigned in the docs (possibly I missed it). And you do cast to int64 and int32 later in the code.

@@ -18,7 +18,7 @@ func TestQuery(t *testing.T) {
}
defer q.Close()

err = q.AddCounter(processorTimeCounter)
err = q.AddCounter(processorTimeCounter, "float")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need some additional test cases for the new formats.

@@ -118,20 +133,28 @@ func (q *Query) Execute() error {
}

type Value struct {
Num float64
Num interface{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a user perspective I'm not really liking that I have to type assert Num to get interpret the value. Maybe in a separate PR we could improve the API for Query. One option would be to have separate FloatValues() and Int64Values() methods that return map[string]FloatValue and map[string]Int64Value respectively.

@martinscholz83
Copy link
Contributor Author

Hi @andrewkroh. I have changed the format option you proposed. Now there are only long and float option. And some other small changes.

@andrewkroh
Copy link
Member

jenkins, test it

type Format int

const (
FLOAT Format = iota
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably call these FloatFormat and LongFormat since the names are rather generic. Constants should use upper-camel-case (I usually ignore this rule for constants brought over from C code).

@andrewkroh
Copy link
Member

There is a merge conflict that needs resolved.

@@ -8,6 +8,8 @@ performance counters.

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 an specific counter. Possible values are
`float`, and `long`. If nothing is selected the default value is `float`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: should say float and long (no comma)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dedemorton, many thanks!!

@@ -8,6 +8,8 @@ performance counters.

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 an specific counter. Possible values are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: should say "for a specific counter"

case "float", "long":
default:
err := fmt.Errorf("format '%s' for counter '%s' are not valid", value.Format, value.Alias)
return nil, errors.Wrap(err, "initialization failed")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use errors.Errorf() here.

@andrewkroh andrewkroh merged commit fdcfdd4 into elastic:master May 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants