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 (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
|
||||
|
@ -85,7 +86,10 @@ func extractCounter(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error
|
|||
continue
|
||||
}
|
||||
|
||||
sample := new(model.Sample)
|
||||
sample := &model.Sample{
|
||||
Metric: model.Metric{},
|
||||
Value: model.SampleValue(m.Counter.GetValue()),
|
||||
}
|
||||
samples = append(samples, sample)
|
||||
|
||||
if m.TimestampMs != nil {
|
||||
|
@ -93,16 +97,12 @@ func extractCounter(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error
|
|||
} else {
|
||||
sample.Timestamp = o.Timestamp
|
||||
}
|
||||
sample.Metric = model.Metric{}
|
||||
metric := sample.Metric
|
||||
|
||||
metric := sample.Metric
|
||||
for _, p := range m.Label {
|
||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
|
||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||
|
||||
sample.Value = model.SampleValue(m.Counter.GetValue())
|
||||
}
|
||||
|
||||
return out.Ingest(samples)
|
||||
|
@ -116,7 +116,10 @@ func extractGauge(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error {
|
|||
continue
|
||||
}
|
||||
|
||||
sample := new(model.Sample)
|
||||
sample := &model.Sample{
|
||||
Metric: model.Metric{},
|
||||
Value: model.SampleValue(m.Gauge.GetValue()),
|
||||
}
|
||||
samples = append(samples, sample)
|
||||
|
||||
if m.TimestampMs != nil {
|
||||
|
@ -124,16 +127,12 @@ func extractGauge(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error {
|
|||
} else {
|
||||
sample.Timestamp = o.Timestamp
|
||||
}
|
||||
sample.Metric = model.Metric{}
|
||||
metric := sample.Metric
|
||||
|
||||
metric := sample.Metric
|
||||
for _, p := range m.Label {
|
||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
|
||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||
|
||||
sample.Value = model.SampleValue(m.Gauge.GetValue())
|
||||
}
|
||||
|
||||
return out.Ingest(samples)
|
||||
|
@ -153,48 +152,50 @@ func extractSummary(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error
|
|||
}
|
||||
|
||||
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)
|
||||
|
||||
sample.Timestamp = timestamp
|
||||
sample.Metric = model.Metric{}
|
||||
metric := sample.Metric
|
||||
|
||||
for _, p := range m.Label {
|
||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
// BUG(matt): Update other names to "quantile".
|
||||
metric[model.LabelName("quantile")] = model.LabelValue(fmt.Sprint(q.GetQuantile()))
|
||||
|
||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||
|
||||
sample.Value = model.SampleValue(q.GetValue())
|
||||
}
|
||||
|
||||
if m.Summary.SampleSum != nil {
|
||||
sum := new(model.Sample)
|
||||
sum.Timestamp = timestamp
|
||||
metric := model.Metric{}
|
||||
sum := &model.Sample{
|
||||
Metric: model.Metric{},
|
||||
Value: model.SampleValue(m.Summary.GetSampleSum()),
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
samples = append(samples, sum)
|
||||
|
||||
metric := sum.Metric
|
||||
for _, p := range m.Label {
|
||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
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 {
|
||||
count := new(model.Sample)
|
||||
count.Timestamp = timestamp
|
||||
metric := model.Metric{}
|
||||
count := &model.Sample{
|
||||
Metric: model.Metric{},
|
||||
Value: model.SampleValue(m.Summary.GetSampleCount()),
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
samples = append(samples, count)
|
||||
|
||||
metric := count.Metric
|
||||
for _, p := range m.Label {
|
||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
sample := new(model.Sample)
|
||||
sample := &model.Sample{
|
||||
Metric: model.Metric{},
|
||||
Value: model.SampleValue(m.Untyped.GetValue()),
|
||||
}
|
||||
samples = append(samples, sample)
|
||||
|
||||
if m.TimestampMs != nil {
|
||||
|
@ -217,16 +221,12 @@ func extractUntyped(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error
|
|||
} else {
|
||||
sample.Timestamp = o.Timestamp
|
||||
}
|
||||
sample.Metric = model.Metric{}
|
||||
metric := sample.Metric
|
||||
|
||||
metric := sample.Metric
|
||||
for _, p := range m.Label {
|
||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
|
||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName())
|
||||
|
||||
sample.Value = model.SampleValue(m.Untyped.GetValue())
|
||||
}
|
||||
|
||||
return out.Ingest(samples)
|
||||
|
@ -245,49 +245,72 @@ func extractHistogram(out Ingester, o *ProcessOptions, f *dto.MetricFamily) erro
|
|||
timestamp = model.TimestampFromUnixNano(*m.TimestampMs * 1000000)
|
||||
}
|
||||
|
||||
infSeen := false
|
||||
|
||||
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)
|
||||
|
||||
sample.Timestamp = timestamp
|
||||
sample.Metric = model.Metric{}
|
||||
metric := sample.Metric
|
||||
|
||||
for _, p := range m.Label {
|
||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
metric[model.LabelName("le")] = model.LabelValue(fmt.Sprint(q.GetUpperBound()))
|
||||
|
||||
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 {
|
||||
sum := new(model.Sample)
|
||||
sum.Timestamp = timestamp
|
||||
metric := model.Metric{}
|
||||
sum := &model.Sample{
|
||||
Metric: model.Metric{},
|
||||
Value: model.SampleValue(m.Histogram.GetSampleSum()),
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
samples = append(samples, sum)
|
||||
|
||||
metric := sum.Metric
|
||||
for _, p := range m.Label {
|
||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
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 {
|
||||
count := new(model.Sample)
|
||||
count.Timestamp = timestamp
|
||||
metric := model.Metric{}
|
||||
count := &model.Sample{
|
||||
Metric: model.Metric{},
|
||||
Value: model.SampleValue(m.Histogram.GetSampleCount()),
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
samples = append(samples, count)
|
||||
|
||||
metric := count.Metric
|
||||
for _, p := range m.Label {
|
||||
metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
|
||||
}
|
||||
metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count")
|
||||
count.Metric = metric
|
||||
count.Value = model.SampleValue(m.Histogram.GetSampleCount())
|
||||
samples = append(samples, count)
|
||||
|
||||
if !infSeen {
|
||||
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"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
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,
|
||||
)
|
||||
}
|
||||
infSeen := false
|
||||
for _, q := range metric.Histogram.Bucket {
|
||||
n, err = writeSample(
|
||||
name+"_bucket", metric,
|
||||
|
@ -156,7 +158,21 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
|||
if err != nil {
|
||||
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(
|
||||
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_sum 1.7560473e+06
|
||||
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