diff --git a/prom2json.go b/prom2json.go index 35d1155c..c0d99699 100644 --- a/prom2json.go +++ b/prom2json.go @@ -112,7 +112,6 @@ func makeHistogram(m *dto.Metric) Histogram { hist := Histogram{ Labels: makeLabels(m), TimestampMs: makeTimestamp(m), - Count: fmt.Sprint(dtoH.GetSampleCount()), Sum: fmt.Sprint(dtoH.GetSampleSum()), } // A native histogram is marked by at least one span. @@ -121,11 +120,18 @@ func makeHistogram(m *dto.Metric) Histogram { if h == nil { // float histogram hist.Buckets = histogram.BucketsAsJson[float64](histogram.GetAPIFloatBuckets(fh)) + hist.Count = fmt.Sprint(fh.Count) } else { hist.Buckets = histogram.BucketsAsJson[uint64](histogram.GetAPIBuckets(h)) + hist.Count = fmt.Sprint(h.Count) } } else { hist.Buckets = makeBuckets(m) + if count := dtoH.GetSampleCountFloat(); count > 0 { + hist.Count = fmt.Sprint(count) + } else { + hist.Count = fmt.Sprint(dtoH.GetSampleCount()) + } } return hist } @@ -156,7 +162,11 @@ func makeQuantiles(m *dto.Metric) map[string]string { func makeBuckets(m *dto.Metric) map[string]string { result := map[string]string{} for _, b := range m.GetHistogram().Bucket { - result[fmt.Sprint(b.GetUpperBound())] = fmt.Sprint(b.GetCumulativeCount()) + if count := b.GetCumulativeCountFloat(); count > 0 { + result[fmt.Sprint(b.GetUpperBound())] = fmt.Sprint(count) + } else { + result[fmt.Sprint(b.GetUpperBound())] = fmt.Sprint(b.GetCumulativeCount()) + } } return result } diff --git a/prom2json_test.go b/prom2json_test.go index f45ee62d..aa2d443c 100644 --- a/prom2json_test.go +++ b/prom2json_test.go @@ -212,6 +212,51 @@ var tcs = []testCase{ }, }, }, + testCase{ + name: "test float histograms", + mFamily: &dto.MetricFamily{ + Name: strPtr("histogram1"), + Type: metricTypePtr(dto.MetricType_HISTOGRAM), + Metric: []*dto.Metric{ + &dto.Metric{ + // Test summary with NaN + Label: []*dto.LabelPair{ + createLabelPair("tag1", "abc"), + createLabelPair("tag2", "def"), + }, + Histogram: &dto.Histogram{ + SampleCountFloat: floatPtr(1), + SampleSum: floatPtr(2), + Bucket: []*dto.Bucket{ + createFloatBucket(250000, 3), + createFloatBucket(500000, 4), + createFloatBucket(1e+06, 5), + }, + }, + }, + }, + }, + output: &Family{ + Name: "histogram1", + Help: "", + Type: "HISTOGRAM", + Metrics: []interface{}{ + Histogram{ + Labels: map[string]string{ + "tag1": "abc", + "tag2": "def", + }, + Buckets: map[string]string{ + "250000": "3", + "500000": "4", + "1e+06": "5", + }, + Count: "1", + Sum: "2", + }, + }, + }, + }, testCase{ name: "test native histograms", mFamily: &dto.MetricFamily{ @@ -279,6 +324,73 @@ var tcs = []testCase{ }, }, }, + testCase{ + name: "test native float histograms", + mFamily: &dto.MetricFamily{ + Name: strPtr("histogram2"), + Type: metricTypePtr(dto.MetricType_HISTOGRAM), + Metric: []*dto.Metric{ + &dto.Metric{ + // Test summary with NaN + Label: []*dto.LabelPair{ + createLabelPair("tag1", "abc"), + createLabelPair("tag2", "def"), + }, + Histogram: &dto.Histogram{ + SampleCountFloat: floatPtr(10), + SampleSum: floatPtr(123.45), + Schema: int32Ptr(1), + PositiveSpan: []*dto.BucketSpan{ + createBucketSpan(0, 3), + createBucketSpan(1, 1), + }, + PositiveCount: []float64{1, 3, 6, 10}, + }, + }, + }, + }, + output: &Family{ + Name: "histogram2", + Help: "", + Type: "HISTOGRAM", + Metrics: []interface{}{ + Histogram{ + Labels: map[string]string{ + "tag1": "abc", + "tag2": "def", + }, + Buckets: [][]interface{}{ + { + uint64(0), + "0.7071067811865475", + "1", + "1", + }, + { + uint64(0), + "1", + "1.414213562373095", + "3", + }, + { + uint64(0), + "1.414213562373095", + "2", + "6", + }, + { + uint64(0), + "2.82842712474619", + "4", + "10", + }, + }, + Count: "10", + Sum: "123.45", + }, + }, + }, + }, } func TestConvertToMetricFamily(t *testing.T) { @@ -336,6 +448,13 @@ func createBucket(bound float64, count uint64) *dto.Bucket { } } +func createFloatBucket(bound float64, count float64) *dto.Bucket { + return &dto.Bucket{ + UpperBound: &bound, + CumulativeCountFloat: &count, + } +} + func createBucketSpan(offset int32, length uint32) *dto.BucketSpan { return &dto.BucketSpan{ Offset: &offset,