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

metrics: add support for PCP #363

Merged
merged 10 commits into from
Oct 17, 2016
Merged

Conversation

suyash
Copy link
Contributor

@suyash suyash commented Sep 14, 2016

Based on the discussion in #354

This is basically the work in my repo except for the readme changes

I have not squashed the commits as GitHub allows squashing all commits into one at merge step, however if it is important, I can squash all changes and submit just one commit

Copy link
Member

@peterbourgon peterbourgon left a comment

Choose a reason for hiding this comment

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

Thanks very much! In general the comments need a lot of cleanup, and you should remove the panics. Also, the histogram needs a way to Observe in units of seconds (see comment on that method). But this is a good start! I think it won't be a lot of work to resolve.

import (
"github.com/go-kit/kit/metrics"
"github.com/performancecopilot/speed"
)
Copy link
Member

Choose a reason for hiding this comment

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

Please group imports according to the canonical style, that is,

import (
    // stdlib

    // third-party, not Go kit

    // Go kit 
)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

"github.com/performancecopilot/speed"
)

// Reporter encapsulates a speed client
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the method comments! Please use complete sentences, including proper punctuation and grammar, i.e.

// Reporter encapsulates a speed client.

func NewReporter(appname string) *Reporter {
c, err := speed.NewPCPClient(appname)
if err != nil {
panic(err)
Copy link
Member

Choose a reason for hiding this comment

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

Is that necessary? Can it return (*Reporter, error) instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

c *speed.PCPClient
}

// NewReporter creates a new reporter instance
Copy link
Member

Choose a reason for hiding this comment

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

  1. Please use proper punctuation, as above.
  2. Please describe a bit the meaning of the appname parameter, and the behavior if there is some error or misconfiguration.

return &Reporter{c}
}

// Start starts reporting currently registered metrics to the backend
Copy link
Member

Choose a reason for hiding this comment

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

  1. Please use proper punctuation (further comments of this type elided).
  2. What does "backend" mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

using 'PCP installation' instead of backend

// but that will mean this will need a mutex, to be safe
func (c *Counter) Add(delta float64) { c.c.Inc(int64(delta)) }

////////////////////////////////////////////////////////////////////////////////////////
Copy link
Member

Choose a reason for hiding this comment

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

Remove this separator.

func (r *Reporter) NewGauge(name string, desc ...string) *Gauge {
g, err := speed.NewPCPGauge(0, name, desc...)
if err != nil {
panic(err)
Copy link
Member

Choose a reason for hiding this comment

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

Same comment re: panic vs. returning an error.


// NewHistogram creates a new Histogram
// minimum observeable value is 0
// maximum observeable value is 3600000000
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 values be parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

func (r *Reporter) NewHistogram(name string, desc ...string) *Histogram {
h, err := speed.NewPCPHistogram(name, 0, 3600000000, 5, desc...)
if err != nil {
panic(err)
Copy link
Member

Choose a reason for hiding this comment

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

Similar comment re: panic vs. returning an error.

//
// this converts float64 value to int64, as the Histogram in speed
// is backed using codahale/hdrhistogram, which only observes int64 values
func (h *Histogram) Observe(value float64) { h.h.MustRecord(int64(value)) }
Copy link
Member

Choose a reason for hiding this comment

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

Simply converting to an int64 is going to be problematic, because it is idiomatic to Observe in a histogram in units of seconds, which typically are well less than 1. How should this be supported, do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The histogram implementation isn't native and simply wraps a PCP metric around codahale/hdrhistogram, which only records int64 (https://godoc.org/github.com/codahale/hdrhistogram#Histogram.RecordValue), which in turn is based on a java version, which itself records only long (http://hdrhistogram.github.io/HdrHistogram/JavaDoc/org/HdrHistogram/AbstractHistogram.html#recordValue(long)).

Raw PCP metrics allow setting a unit (https://github.com/performancecopilot/speed#singletonmetric), and I have shorted it to OneUnit at most places as it represents Count unit and most of the times we just want to count stuff. But I can provide a units parameter in histogram, similar to Timer (https://github.com/performancecopilot/speed#timer) so users can customize the unit to Milliseconds, Microseconds, Nanoseconds and report int64.

The other option is to replace the underlying histogram with another implementation. I like hdrhistogram for its ideas on precision and reduced memory footprint, but am open to ideas.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so the normal tests were taking 1.6s but tests with -race enabled were taking 29s on my local machine and 38s on travis, so did a small profile

screenshot from 2016-09-20 23 03 06

from what I can see, the iterator next method on hdrhistogram seems slow, or maybe I am doing something wrong

Copy link
Member

Choose a reason for hiding this comment

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

I'm fine with keeping HDRHistogram. I like the Unit idea, it should be settable at metric construction time. Testing with -race will always be much slower than otherwise; I wouldn't worry about profiling it.

@suyash
Copy link
Contributor Author

suyash commented Oct 6, 2016

@peterbourgon sorry for the late update on this

  • have added an additional unit parameter to the histogram construction, both here and to speed (https://godoc.org/github.com/performancecopilot/speed#NewPCPHistogram)
  • as you said I have added some more comments to all custom metric construction methods for speed
  • however, the test time for histogram is still a concern to me, mainly I want to understand why it would take that long with race enabled. The tests for speed only increase by ~1 second with race enabled. Still investigating that, as well as trying to study other histogram implementations, will update this thread once I finalize something.

// NewReporter creates a new Reporter instance.
// The first parameter is the application name and is used to create the speed client.
// Hence it should be a valid speed parameter name and should not contain spaces or the path separator
// for your operating system.
Copy link
Member

Choose a reason for hiding this comment

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

Please wrap this and all comment blocks at 80 columns.


// Add implements Counter.
// speed Counters only take int64.
// speed Gauges can take float64 and Add(float64) is implemented by metrics.Gauge.
Copy link
Member

Choose a reason for hiding this comment

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

Please fix the capitalization in this and all comment blocks, and clarify the behavior.

// Add implements Counter. Speed counters only take int64, so 
// the delta is converted to an int64 before observation.


// NewHistogram creates a new Histogram.
// minimum observeable value is 0.
// maximum observeable value is 3600000000.
Copy link
Member

@peterbourgon peterbourgon Oct 10, 2016

Choose a reason for hiding this comment

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

Please fix capitalization here, and wrap the comment block at 80 columns.

// Observe observes a value.
//
// this converts float64 value to int64, as the Histogram in speed
// is backed using codahale/hdrhistogram, which only observes int64 values.
Copy link
Member

Choose a reason for hiding this comment

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

Please mention something about the value being interpreted as the unit passed to the constructor.

@peterbourgon
Copy link
Member

Please don't waste time finding out why tests take longer to run with the race detector enabled. The race detector adds a lot of overhead by design.

@peterbourgon
Copy link
Member

With those final cleanups I've requested, I'm happy to merge. Thanks for taking the time!

@suyash
Copy link
Contributor Author

suyash commented Oct 13, 2016

@peterbourgon as requested I have updated the comment blocks to be a maximum of 80 columns in length.

Moreover, I have generated the godoc for the package on my fork, which can be seen at (https://godoc.org/github.com/suyash/kit/metrics/pcp).

I am using the package name in small characters everywhere (speed instead of Speed), because of the package name.

W.e.f the histogram test time issue, the final call is yours, even if I change something in speed, my goal will be to keep things 100% backwards compatible. Right now whenever I can find the time, I am trying to understand the underlying working of hdrhistogram. In case there arises a need for a change in anything in this package, I can always open another PR.

Thanks for being patient with me, with the code reviews. The generated godoc LGTM, please let me know if you need anything else. I am using atom to check the line width, and except for line 106, everything looks to be inside.

@peterbourgon
Copy link
Member

Thanks for all of the hard work. I'll make a few other minor cleanups post-merge but this is great. 💯

@peterbourgon peterbourgon merged commit e049844 into go-kit:master Oct 17, 2016
@suyash suyash deleted the pcp-go-kit-pr branch October 17, 2016 12:49
@suyash
Copy link
Contributor Author

suyash commented Oct 17, 2016

Thanks ✨, you forgot to close the issue, will close it manually.

jamesgist pushed a commit to jamesgist/kit that referenced this pull request Nov 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants