mirror of
https://github.com/prometheus/prometheus
synced 2025-01-13 18:33:34 +00:00
histogram: Expose #12305
Native histograms without a zero threshold aren't federated properly. This adds a test to prove the specific failure mode, which is that histograms with a zero threshold of zero are federated as classic histograms. The underlying reason is that the protobuf parser identifies a native histogram by detecting a zero bucket or by detecting integer buckets. Therefore, a float histogram with a zero threshold of zero and an unpopulated zero bucket falls through the cracks (no integer buckets, no zero bucket). This commit also addse a test case for the latter. Signed-off-by: beorn7 <beorn@grafana.com>
This commit is contained in:
parent
0a48f93111
commit
2ea8df4734
@ -463,6 +463,24 @@ metric: <
|
|||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
|
||||||
|
`,
|
||||||
|
`name: "test_float_histogram_with_zerothreshold_zero"
|
||||||
|
help: "Test float histogram with a zero threshold of zero."
|
||||||
|
type: HISTOGRAM
|
||||||
|
metric: <
|
||||||
|
histogram: <
|
||||||
|
sample_count_float: 5.0
|
||||||
|
sample_sum: 12.1
|
||||||
|
schema: 3
|
||||||
|
positive_span: <
|
||||||
|
offset: 8
|
||||||
|
length: 2
|
||||||
|
>
|
||||||
|
positive_count: 2.0
|
||||||
|
positive_count: 3.0
|
||||||
|
>
|
||||||
|
>
|
||||||
|
|
||||||
`,
|
`,
|
||||||
`name: "rpc_durations_seconds"
|
`name: "rpc_durations_seconds"
|
||||||
help: "RPC latency distributions."
|
help: "RPC latency distributions."
|
||||||
@ -850,6 +868,30 @@ func TestProtobufParse(t *testing.T) {
|
|||||||
"foo", "baz",
|
"foo", "baz",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
m: "test_float_histogram_with_zerothreshold_zero",
|
||||||
|
help: "Test float histogram with a zero threshold of zero.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
m: "test_float_histogram_with_zerothreshold_zero",
|
||||||
|
typ: MetricTypeHistogram,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
m: "test_float_histogram_with_zerothreshold_zero",
|
||||||
|
fhs: &histogram.FloatHistogram{
|
||||||
|
Count: 5.0,
|
||||||
|
Sum: 12.1,
|
||||||
|
Schema: 3,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 8, Length: 2},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{2.0, 3.0},
|
||||||
|
NegativeSpans: []histogram.Span{},
|
||||||
|
},
|
||||||
|
lset: labels.FromStrings(
|
||||||
|
"__name__", "test_float_histogram_with_zerothreshold_zero",
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
m: "rpc_durations_seconds",
|
m: "rpc_durations_seconds",
|
||||||
help: "RPC latency distributions.",
|
help: "RPC latency distributions.",
|
||||||
@ -1550,14 +1592,38 @@ func TestProtobufParse(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ // 67
|
{ // 67
|
||||||
|
m: "test_float_histogram_with_zerothreshold_zero",
|
||||||
|
help: "Test float histogram with a zero threshold of zero.",
|
||||||
|
},
|
||||||
|
{ // 68
|
||||||
|
m: "test_float_histogram_with_zerothreshold_zero",
|
||||||
|
typ: MetricTypeHistogram,
|
||||||
|
},
|
||||||
|
{ // 69
|
||||||
|
m: "test_float_histogram_with_zerothreshold_zero",
|
||||||
|
fhs: &histogram.FloatHistogram{
|
||||||
|
Count: 5.0,
|
||||||
|
Sum: 12.1,
|
||||||
|
Schema: 3,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 8, Length: 2},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{2.0, 3.0},
|
||||||
|
NegativeSpans: []histogram.Span{},
|
||||||
|
},
|
||||||
|
lset: labels.FromStrings(
|
||||||
|
"__name__", "test_float_histogram_with_zerothreshold_zero",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{ // 70
|
||||||
m: "rpc_durations_seconds",
|
m: "rpc_durations_seconds",
|
||||||
help: "RPC latency distributions.",
|
help: "RPC latency distributions.",
|
||||||
},
|
},
|
||||||
{ // 68
|
{ // 71
|
||||||
m: "rpc_durations_seconds",
|
m: "rpc_durations_seconds",
|
||||||
typ: MetricTypeSummary,
|
typ: MetricTypeSummary,
|
||||||
},
|
},
|
||||||
{ // 69
|
{ // 72
|
||||||
m: "rpc_durations_seconds_count\xffservice\xffexponential",
|
m: "rpc_durations_seconds_count\xffservice\xffexponential",
|
||||||
v: 262,
|
v: 262,
|
||||||
lset: labels.FromStrings(
|
lset: labels.FromStrings(
|
||||||
@ -1565,7 +1631,7 @@ func TestProtobufParse(t *testing.T) {
|
|||||||
"service", "exponential",
|
"service", "exponential",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ // 70
|
{ // 73
|
||||||
m: "rpc_durations_seconds_sum\xffservice\xffexponential",
|
m: "rpc_durations_seconds_sum\xffservice\xffexponential",
|
||||||
v: 0.00025551262820703587,
|
v: 0.00025551262820703587,
|
||||||
lset: labels.FromStrings(
|
lset: labels.FromStrings(
|
||||||
@ -1573,7 +1639,7 @@ func TestProtobufParse(t *testing.T) {
|
|||||||
"service", "exponential",
|
"service", "exponential",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ // 71
|
{ // 74
|
||||||
m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.5",
|
m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.5",
|
||||||
v: 6.442786329648548e-07,
|
v: 6.442786329648548e-07,
|
||||||
lset: labels.FromStrings(
|
lset: labels.FromStrings(
|
||||||
@ -1582,7 +1648,7 @@ func TestProtobufParse(t *testing.T) {
|
|||||||
"service", "exponential",
|
"service", "exponential",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ // 72
|
{ // 75
|
||||||
m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.9",
|
m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.9",
|
||||||
v: 1.9435742936658396e-06,
|
v: 1.9435742936658396e-06,
|
||||||
lset: labels.FromStrings(
|
lset: labels.FromStrings(
|
||||||
@ -1591,7 +1657,7 @@ func TestProtobufParse(t *testing.T) {
|
|||||||
"service", "exponential",
|
"service", "exponential",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ // 73
|
{ // 76
|
||||||
m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.99",
|
m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.99",
|
||||||
v: 4.0471608667037015e-06,
|
v: 4.0471608667037015e-06,
|
||||||
lset: labels.FromStrings(
|
lset: labels.FromStrings(
|
||||||
@ -1600,22 +1666,22 @@ func TestProtobufParse(t *testing.T) {
|
|||||||
"service", "exponential",
|
"service", "exponential",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ // 74
|
{ // 77
|
||||||
m: "without_quantiles",
|
m: "without_quantiles",
|
||||||
help: "A summary without quantiles.",
|
help: "A summary without quantiles.",
|
||||||
},
|
},
|
||||||
{ // 75
|
{ // 78
|
||||||
m: "without_quantiles",
|
m: "without_quantiles",
|
||||||
typ: MetricTypeSummary,
|
typ: MetricTypeSummary,
|
||||||
},
|
},
|
||||||
{ // 76
|
{ // 79
|
||||||
m: "without_quantiles_count",
|
m: "without_quantiles_count",
|
||||||
v: 42,
|
v: 42,
|
||||||
lset: labels.FromStrings(
|
lset: labels.FromStrings(
|
||||||
"__name__", "without_quantiles_count",
|
"__name__", "without_quantiles_count",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ // 77
|
{ // 80
|
||||||
m: "without_quantiles_sum",
|
m: "without_quantiles_sum",
|
||||||
v: 1.234,
|
v: 1.234,
|
||||||
lset: labels.FromStrings(
|
lset: labels.FromStrings(
|
||||||
|
@ -335,18 +335,41 @@ func TestFederationWithNativeHistograms(t *testing.T) {
|
|||||||
},
|
},
|
||||||
NegativeBuckets: []int64{1, 1, -1, 0},
|
NegativeBuckets: []int64{1, 1, -1, 0},
|
||||||
}
|
}
|
||||||
|
histWithoutZeroBucket := &histogram.Histogram{
|
||||||
|
Count: 20,
|
||||||
|
Sum: 99.23,
|
||||||
|
Schema: 1,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 2},
|
||||||
|
{Offset: 1, Length: 2},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []int64{2, 2, -2, 0},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 2},
|
||||||
|
{Offset: 1, Length: 2},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []int64{2, 2, -2, 0},
|
||||||
|
}
|
||||||
app := db.Appender(context.Background())
|
app := db.Appender(context.Background())
|
||||||
for i := 0; i < 6; i++ {
|
for i := 0; i < 6; i++ {
|
||||||
l := labels.FromStrings("__name__", "test_metric", "foo", fmt.Sprintf("%d", i))
|
l := labels.FromStrings("__name__", "test_metric", "foo", fmt.Sprintf("%d", i))
|
||||||
expL := labels.FromStrings("__name__", "test_metric", "instance", "", "foo", fmt.Sprintf("%d", i))
|
expL := labels.FromStrings("__name__", "test_metric", "instance", "", "foo", fmt.Sprintf("%d", i))
|
||||||
if i%3 == 0 {
|
switch i {
|
||||||
|
case 0, 3:
|
||||||
_, err = app.Append(0, l, 100*60*1000, float64(i*100))
|
_, err = app.Append(0, l, 100*60*1000, float64(i*100))
|
||||||
expVec = append(expVec, promql.Sample{
|
expVec = append(expVec, promql.Sample{
|
||||||
T: 100 * 60 * 1000,
|
T: 100 * 60 * 1000,
|
||||||
F: float64(i * 100),
|
F: float64(i * 100),
|
||||||
Metric: expL,
|
Metric: expL,
|
||||||
})
|
})
|
||||||
} else {
|
case 4:
|
||||||
|
_, err = app.AppendHistogram(0, l, 100*60*1000, histWithoutZeroBucket.Copy(), nil)
|
||||||
|
expVec = append(expVec, promql.Sample{
|
||||||
|
T: 100 * 60 * 1000,
|
||||||
|
H: histWithoutZeroBucket.ToFloat(),
|
||||||
|
Metric: expL,
|
||||||
|
})
|
||||||
|
default:
|
||||||
hist.ZeroCount++
|
hist.ZeroCount++
|
||||||
_, err = app.AppendHistogram(0, l, 100*60*1000, hist.Copy(), nil)
|
_, err = app.AppendHistogram(0, l, 100*60*1000, hist.Copy(), nil)
|
||||||
expVec = append(expVec, promql.Sample{
|
expVec = append(expVec, promql.Sample{
|
||||||
|
Loading…
Reference in New Issue
Block a user