-
Notifications
You must be signed in to change notification settings - Fork 34
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
Add first class support for Histograms #63
Conversation
Signed-off-by: Gary Brown <gary@brownuk.com>
Codecov Report
@@ Coverage Diff @@
## master #63 +/- ##
======================================
Coverage 100% 100%
======================================
Files 25 26 +1
Lines 711 890 +179
======================================
+ Hits 711 890 +179
Continue to review full report at Codecov.
|
@yurishkuro Currently just adds Histogram alongside Timer - although your suggestion in #62 to replace Timer, was wondering whether would be better to leave Timer as-is - to minimise breaking changes, but also because the |
metrics/factory.go
Outdated
Help string | ||
Buckets []float64 | ||
} | ||
|
||
// Factory creates new metrics | ||
type Factory interface { | ||
Counter(metric Options) Counter | ||
Timer(metric Options) Timer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my main question is: do we want to keep the Timer() as a function in the interface, or move it to a static helper function that will be based on the histogram?
Pros: This is what already happens in most implementations, so we could just do it once.
Cons: in some metrics backends timers are 1st class citizens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your call 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the only change I would propose is having the Timer() function take options struct that includes buckets (probably expressed as []time.Duration
rather than []float64
).
I am ok with leaving times in the interface. |
@yurishkuro Ok will work on the test coverage and fixing the failing test. Let me know if there are other areas that need addressing. |
Signed-off-by: Gary Brown <gary@brownuk.com>
Signed-off-by: Gary Brown <gary@brownuk.com>
@yurishkuro Updated to use TimerOptions and fixed coverage. Let me know if there is anything else. |
metrics/expvar/factory.go
Outdated
return xkit.NewTimer(f.factory.Histogram(name)) | ||
} | ||
|
||
func (f *factory) Histogram(name string, help string, buckets []float64) metrics.Histogram { | ||
return xkit.NewHistogram(f.factory.Histogram(name)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe a TODO to respect the buckets? Doesn't gokit allow buckets for histograms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added. #66
metrics/factory.go
Outdated
import ( | ||
"time" | ||
) | ||
|
||
// NSOptions defines the name and tags map associated with a metric |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/with a metric/with a factory namespace/ ?
metrics/histogram.go
Outdated
@@ -0,0 +1,28 @@ | |||
// Copyright (c) 2018 Uber Technologies, Inc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Jaeger Authors
metrics/histogram.go
Outdated
|
||
package metrics | ||
|
||
// Histogram represents a histogram metric types. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that keeps track of a distribution of values.
@@ -47,6 +48,7 @@ func InitOrError(m interface{}, factory Factory, globalTags map[string]string) e | |||
counterPtrType := reflect.TypeOf((*Counter)(nil)).Elem() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we should fix #64 while at it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think InitOrError should be renamed to Init()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
metrics/prometheus/factory.go
Outdated
func asFloatBuckets(buckets []time.Duration) []float64 { | ||
data := make([]float64, len(buckets)) | ||
for i := range data { | ||
data[i] = float64(buckets[i]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't Prometheus client expects double(1.0) == 1sec
? Do we need:
data[i] = float64(buckets[i]) / float64(time.Second)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly for Timer (duration) buckets - but for Histogram this is just a list of floats,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but this function is used for Timer buckets, is it not? Since it accepts []time.Duration
. I think you need to divide this by time.Second, since this is what the Record function of the timer does:
jaeger-lib/metrics/prometheus/factory.go
Lines 214 to 216 in 3fa9aa0
func (t *timer) Record(v time.Duration) { | |
t.histogram.Observe(float64(v.Nanoseconds()) / float64(time.Second/time.Nanosecond)) | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep sorry - not sure what I was thinking.
@@ -48,14 +48,22 @@ func (f *factory) Gauge(options metrics.Options) metrics.Gauge { | |||
return NewGauge(scope.Gauge(options.Name)) | |||
} | |||
|
|||
func (f *factory) Timer(options metrics.Options) metrics.Timer { | |||
func (f *factory) Timer(options metrics.TimerOptions) metrics.Timer { | |||
scope := f.tally | |||
if len(options.Tags) > 0 { | |||
scope = scope.Tagged(options.Tags) | |||
} | |||
return NewTimer(scope.Timer(options.Name)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, I thought tally supported buckets for timers. At least let's have a TODO, since we're dropping the buckets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, Timer doesn't, but the tally.Histogram suports a DurationBucket - so depends if we want to switch underlying representation? Will mark as TODO for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signed-off-by: Gary Brown <gary@brownuk.com>
Updated. |
@yurishkuro Ready for another review. |
@yurishkuro Anything further required on this one? |
metrics/metrics.go
Outdated
b, err := strconv.ParseFloat(bucket, 64) | ||
if err != nil { | ||
return fmt.Errorf( | ||
"Field [%s]: Bucket [%s] could not be converted to float64 in 'buckets' stirng [%s]", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: stirng
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Signed-off-by: Gary Brown <gary@brownuk.com>
@yurishkuro updated. |
🎉 |
Resolves #62
Signed-off-by: Gary Brown gary@brownuk.com