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

Feature request for histogram-like type that keeps raw durations by bucket size #81

Open
arnikola opened this issue Jul 11, 2018 · 0 comments

Comments

@arnikola
Copy link

Recently came across a use case which is difficult to represent with native Tally types. I had a function that dealt with many different cardinalities of data, and wanted to capture metrics by bucket size, similar to a histogram.

While this worked for raw count, I was looking for some way to capture the duration by the same buckets, which is currently not possible.

Below is the workaround I used to achieve this in case my explanation is hard to follow

type bucketMetric struct {
	threshold int
	timing    tally.Timer
}

func newBucketMetric(threshold int, value string, scope tally.Scope) *bucketMetric {
	return &bucketMetric{
		threshold: threshold,
		timing:    scope.Timer("timing"),
	}
}

type bucketMetrics struct {
	countHistogram  tally.Histogram
	durationMetrics []*bucketMetric
}

func newBucketMetrics(metricType string, scope tally.Scope) bucketMetrics {
	buckets := tally.ValueBuckets([]float64{50, 200, 1000, 5000, 10000, math.MaxInt32})

	return bucketMetrics{
		countHistogram: scope.Histogram("count", buckets),
		durationMetrics: []*bucketMetric{
			newBucketMetric(0, "0", scope),
			newBucketMetric(50, "50", scope),
			newBucketMetric(200, "200", scope),
			newBucketMetric(1000, "1000", scope),
			newBucketMetric(5000, "5000", scope),
			newBucketMetric(10000, "10000", scope),
			newBucketMetric(int(math.MaxInt32), "max", scope),
		},
	}
}

func (bm bucketMetrics) record(cardinality int, duration time.Duration) {
	// Record count on the general bucketMetrics histogram
	bm.countHistogram.RecordValue(float64(cardinality))

	for _, m := range bm.durationMetrics {
		if cardinality <= m.threshold {
			m.timing.Record(duration)
			return
		}
	}
}
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

No branches or pull requests

1 participant