Add support for optionally missing +Inf bucket in protobuf.
Also, clean up style issues in metricfamilyprocessor.go.
This commit is contained in:
parent
a7c56882af
commit
b37ca982a9
|
@ -16,6 +16,7 @@ package extraction
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"math"
|
||||||
|
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
|
|
||||||
|
@ -85,7 +86,10 @@ func extractCounter(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
sample := new(model.Sample)
|
sample := &model.Sample{
|
||||||
|
Metric: model.Metric{},
|
||||||
|
Value: model.SampleValue(m.Counter.GetValue()),
|
||||||
|
}
|
||||||
samples = append(samples, sample)
|
samples = append(samples, sample)
|
||||||
|
|
||||||
if m.TimestampMs != nil {
|
if m.TimestampMs != nil {
|
||||||
|
@ -93,16 +97,12 @@ func extractCounter(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error
|
||||||
} else {
|
} else {
|
||||||
sample.Timestamp = o.Timestamp
|
sample.Timestamp = o.Timestamp
|
||||||
}
|
}
|
||||||
sample.Metric = model.Metric{}
|
|
||||||
metric := sample.Metric
|
|
||||||
|
|
||||||
|
metric := sample.Metric
|
||||||
for _, p := range m.Label {
|
for _, p := range m.Label {
|
||||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||||
|
|
||||||
sample.Value = model.SampleValue(m.Counter.GetValue())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.Ingest(samples)
|
return out.Ingest(samples)
|
||||||
|
@ -116,7 +116,10 @@ func extractGauge(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
sample := new(model.Sample)
|
sample := &model.Sample{
|
||||||
|
Metric: model.Metric{},
|
||||||
|
Value: model.SampleValue(m.Gauge.GetValue()),
|
||||||
|
}
|
||||||
samples = append(samples, sample)
|
samples = append(samples, sample)
|
||||||
|
|
||||||
if m.TimestampMs != nil {
|
if m.TimestampMs != nil {
|
||||||
|
@ -124,16 +127,12 @@ func extractGauge(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error {
|
||||||
} else {
|
} else {
|
||||||
sample.Timestamp = o.Timestamp
|
sample.Timestamp = o.Timestamp
|
||||||
}
|
}
|
||||||
sample.Metric = model.Metric{}
|
|
||||||
metric := sample.Metric
|
|
||||||
|
|
||||||
|
metric := sample.Metric
|
||||||
for _, p := range m.Label {
|
for _, p := range m.Label {
|
||||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||||
|
|
||||||
sample.Value = model.SampleValue(m.Gauge.GetValue())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.Ingest(samples)
|
return out.Ingest(samples)
|
||||||
|
@ -153,48 +152,50 @@ func extractSummary(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, q := range m.Summary.Quantile {
|
for _, q := range m.Summary.Quantile {
|
||||||
sample := new(model.Sample)
|
sample := &model.Sample{
|
||||||
|
Metric: model.Metric{},
|
||||||
|
Value: model.SampleValue(q.GetValue()),
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
samples = append(samples, sample)
|
samples = append(samples, sample)
|
||||||
|
|
||||||
sample.Timestamp = timestamp
|
|
||||||
sample.Metric = model.Metric{}
|
|
||||||
metric := sample.Metric
|
metric := sample.Metric
|
||||||
|
|
||||||
for _, p := range m.Label {
|
for _, p := range m.Label {
|
||||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
}
|
}
|
||||||
// BUG(matt): Update other names to "quantile".
|
// BUG(matt): Update other names to "quantile".
|
||||||
metric[model.LabelName("quantile")] = model.LabelValue(fmt.Sprint(q.GetQuantile()))
|
metric[model.LabelName("quantile")] = model.LabelValue(fmt.Sprint(q.GetQuantile()))
|
||||||
|
|
||||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||||
|
|
||||||
sample.Value = model.SampleValue(q.GetValue())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.Summary.SampleSum != nil {
|
if m.Summary.SampleSum != nil {
|
||||||
sum := new(model.Sample)
|
sum := &model.Sample{
|
||||||
sum.Timestamp = timestamp
|
Metric: model.Metric{},
|
||||||
metric := model.Metric{}
|
Value: model.SampleValue(m.Summary.GetSampleSum()),
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
|
samples = append(samples, sum)
|
||||||
|
|
||||||
|
metric := sum.Metric
|
||||||
for _, p := range m.Label {
|
for _, p := range m.Label {
|
||||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
}
|
}
|
||||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum")
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum")
|
||||||
sum.Metric = metric
|
|
||||||
sum.Value = model.SampleValue(m.Summary.GetSampleSum())
|
|
||||||
samples = append(samples, sum)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.Summary.SampleCount != nil {
|
if m.Summary.SampleCount != nil {
|
||||||
count := new(model.Sample)
|
count := &model.Sample{
|
||||||
count.Timestamp = timestamp
|
Metric: model.Metric{},
|
||||||
metric := model.Metric{}
|
Value: model.SampleValue(m.Summary.GetSampleCount()),
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
|
samples = append(samples, count)
|
||||||
|
|
||||||
|
metric := count.Metric
|
||||||
for _, p := range m.Label {
|
for _, p := range m.Label {
|
||||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
}
|
}
|
||||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count")
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count")
|
||||||
count.Metric = metric
|
|
||||||
count.Value = model.SampleValue(m.Summary.GetSampleCount())
|
|
||||||
samples = append(samples, count)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +210,10 @@ func extractUntyped(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
sample := new(model.Sample)
|
sample := &model.Sample{
|
||||||
|
Metric: model.Metric{},
|
||||||
|
Value: model.SampleValue(m.Untyped.GetValue()),
|
||||||
|
}
|
||||||
samples = append(samples, sample)
|
samples = append(samples, sample)
|
||||||
|
|
||||||
if m.TimestampMs != nil {
|
if m.TimestampMs != nil {
|
||||||
|
@ -217,16 +221,12 @@ func extractUntyped(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error
|
||||||
} else {
|
} else {
|
||||||
sample.Timestamp = o.Timestamp
|
sample.Timestamp = o.Timestamp
|
||||||
}
|
}
|
||||||
sample.Metric = model.Metric{}
|
|
||||||
metric := sample.Metric
|
|
||||||
|
|
||||||
|
metric := sample.Metric
|
||||||
for _, p := range m.Label {
|
for _, p := range m.Label {
|
||||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||||
|
|
||||||
sample.Value = model.SampleValue(m.Untyped.GetValue())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.Ingest(samples)
|
return out.Ingest(samples)
|
||||||
|
@ -245,49 +245,72 @@ func extractHistogram(out Ingester, o *ProcessOptions, f *dto.MetricFamily) erro
|
||||||
timestamp = model.TimestampFromUnixNano(*m.TimestampMs * 1000000)
|
timestamp = model.TimestampFromUnixNano(*m.TimestampMs * 1000000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
infSeen := false
|
||||||
|
|
||||||
for _, q := range m.Histogram.Bucket {
|
for _, q := range m.Histogram.Bucket {
|
||||||
sample := new(model.Sample)
|
sample := &model.Sample{
|
||||||
|
Metric: model.Metric{},
|
||||||
|
Value: model.SampleValue(q.GetCumulativeCount()),
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
samples = append(samples, sample)
|
samples = append(samples, sample)
|
||||||
|
|
||||||
sample.Timestamp = timestamp
|
|
||||||
sample.Metric = model.Metric{}
|
|
||||||
metric := sample.Metric
|
metric := sample.Metric
|
||||||
|
|
||||||
for _, p := range m.Label {
|
for _, p := range m.Label {
|
||||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
}
|
}
|
||||||
metric[model.LabelName("le")] = model.LabelValue(fmt.Sprint(q.GetUpperBound()))
|
metric[model.LabelName("le")] = model.LabelValue(fmt.Sprint(q.GetUpperBound()))
|
||||||
|
|
||||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket")
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket")
|
||||||
|
|
||||||
sample.Value = model.SampleValue(q.GetCumulativeCount())
|
if math.IsInf(q.GetUpperBound(), +1) {
|
||||||
|
infSeen = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO: If +Inf bucket is missing, add it.
|
|
||||||
|
|
||||||
if m.Histogram.SampleSum != nil {
|
if m.Histogram.SampleSum != nil {
|
||||||
sum := new(model.Sample)
|
sum := &model.Sample{
|
||||||
sum.Timestamp = timestamp
|
Metric: model.Metric{},
|
||||||
metric := model.Metric{}
|
Value: model.SampleValue(m.Histogram.GetSampleSum()),
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
|
samples = append(samples, sum)
|
||||||
|
|
||||||
|
metric := sum.Metric
|
||||||
for _, p := range m.Label {
|
for _, p := range m.Label {
|
||||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
}
|
}
|
||||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum")
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum")
|
||||||
sum.Metric = metric
|
|
||||||
sum.Value = model.SampleValue(m.Histogram.GetSampleSum())
|
|
||||||
samples = append(samples, sum)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.Histogram.SampleCount != nil {
|
if m.Histogram.SampleCount != nil {
|
||||||
count := new(model.Sample)
|
count := &model.Sample{
|
||||||
count.Timestamp = timestamp
|
Metric: model.Metric{},
|
||||||
metric := model.Metric{}
|
Value: model.SampleValue(m.Histogram.GetSampleCount()),
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
|
samples = append(samples, count)
|
||||||
|
|
||||||
|
metric := count.Metric
|
||||||
for _, p := range m.Label {
|
for _, p := range m.Label {
|
||||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
}
|
}
|
||||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count")
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count")
|
||||||
count.Metric = metric
|
|
||||||
count.Value = model.SampleValue(m.Histogram.GetSampleCount())
|
if !infSeen {
|
||||||
samples = append(samples, count)
|
infBucket := &model.Sample{
|
||||||
|
Metric: model.Metric{},
|
||||||
|
Value: count.Value,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
|
samples = append(samples, infBucket)
|
||||||
|
|
||||||
|
metric := infBucket.Metric
|
||||||
|
for _, p := range m.Label {
|
||||||
|
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||||
|
}
|
||||||
|
metric[model.LabelName("le")] = model.LabelValue("+Inf")
|
||||||
|
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
|
@ -145,6 +146,7 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
||||||
"expected summary in metric %s", metric,
|
"expected summary in metric %s", metric,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
infSeen := false
|
||||||
for _, q := range metric.Histogram.Bucket {
|
for _, q := range metric.Histogram.Bucket {
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name+"_bucket", metric,
|
name+"_bucket", metric,
|
||||||
|
@ -156,7 +158,21 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
// TODO: Add +inf bucket if it's missing.
|
if math.IsInf(q.GetUpperBound(), +1) {
|
||||||
|
infSeen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !infSeen {
|
||||||
|
n, err = writeSample(
|
||||||
|
name+"_bucket", metric,
|
||||||
|
"le", "+Inf",
|
||||||
|
float64(metric.Histogram.GetSampleCount()),
|
||||||
|
out,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
written += n
|
||||||
}
|
}
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name+"_sum", metric, "", "",
|
name+"_sum", metric, "", "",
|
||||||
|
|
|
@ -267,6 +267,50 @@ request_duration_microseconds_bucket{le="172.8"} 1524
|
||||||
request_duration_microseconds_bucket{le="+Inf"} 2693
|
request_duration_microseconds_bucket{le="+Inf"} 2693
|
||||||
request_duration_microseconds_sum 1.7560473e+06
|
request_duration_microseconds_sum 1.7560473e+06
|
||||||
request_duration_microseconds_count 2693
|
request_duration_microseconds_count 2693
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
// 5: Histogram with missing +Inf bucket.
|
||||||
|
{
|
||||||
|
in: &dto.MetricFamily{
|
||||||
|
Name: proto.String("request_duration_microseconds"),
|
||||||
|
Help: proto.String("The response latency."),
|
||||||
|
Type: dto.MetricType_HISTOGRAM.Enum(),
|
||||||
|
Metric: []*dto.Metric{
|
||||||
|
&dto.Metric{
|
||||||
|
Histogram: &dto.Histogram{
|
||||||
|
SampleCount: proto.Uint64(2693),
|
||||||
|
SampleSum: proto.Float64(1756047.3),
|
||||||
|
Bucket: []*dto.Bucket{
|
||||||
|
&dto.Bucket{
|
||||||
|
UpperBound: proto.Float64(100),
|
||||||
|
CumulativeCount: proto.Uint64(123),
|
||||||
|
},
|
||||||
|
&dto.Bucket{
|
||||||
|
UpperBound: proto.Float64(120),
|
||||||
|
CumulativeCount: proto.Uint64(412),
|
||||||
|
},
|
||||||
|
&dto.Bucket{
|
||||||
|
UpperBound: proto.Float64(144),
|
||||||
|
CumulativeCount: proto.Uint64(592),
|
||||||
|
},
|
||||||
|
&dto.Bucket{
|
||||||
|
UpperBound: proto.Float64(172.8),
|
||||||
|
CumulativeCount: proto.Uint64(1524),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
out: `# HELP request_duration_microseconds The response latency.
|
||||||
|
# TYPE request_duration_microseconds histogram
|
||||||
|
request_duration_microseconds_bucket{le="100"} 123
|
||||||
|
request_duration_microseconds_bucket{le="120"} 412
|
||||||
|
request_duration_microseconds_bucket{le="144"} 592
|
||||||
|
request_duration_microseconds_bucket{le="172.8"} 1524
|
||||||
|
request_duration_microseconds_bucket{le="+Inf"} 2693
|
||||||
|
request_duration_microseconds_sum 1.7560473e+06
|
||||||
|
request_duration_microseconds_count 2693
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue