Prometheus support parse exemplars from native histogram (#13488)
scrape: support parsing exemplars from native histogram --------- Signed-off-by: Ziqi Zhao <zhaoziqi9146@gmail.com> Signed-off-by: Björn Rabenstein <github@rabenste.in> Co-authored-by: Björn Rabenstein <github@rabenste.in>
This commit is contained in:
parent
ff6c83269c
commit
a93859a52f
|
@ -56,6 +56,8 @@ type ProtobufParser struct {
|
|||
fieldPos int
|
||||
fieldsDone bool // true if no more fields of a Summary or (legacy) Histogram to be processed.
|
||||
redoClassic bool // true after parsing a native histogram if we need to parse it again as a classic histogram.
|
||||
// exemplarPos is the position within the exemplars slice of a native histogram.
|
||||
exemplarPos int
|
||||
|
||||
// exemplarReturned is set to true each time an exemplar has been
|
||||
// returned, and set back to false upon each Next() call.
|
||||
|
@ -304,8 +306,9 @@ func (p *ProtobufParser) Metric(l *labels.Labels) string {
|
|||
|
||||
// Exemplar writes the exemplar of the current sample into the passed
|
||||
// exemplar. It returns if an exemplar exists or not. In case of a native
|
||||
// histogram, the legacy bucket section is still used for exemplars. To ingest
|
||||
// all exemplars, call the Exemplar method repeatedly until it returns false.
|
||||
// histogram, the exemplars in the native histogram will be returned.
|
||||
// If this field is empty, the classic bucket section is still used for exemplars.
|
||||
// To ingest all exemplars, call the Exemplar method repeatedly until it returns false.
|
||||
func (p *ProtobufParser) Exemplar(ex *exemplar.Exemplar) bool {
|
||||
if p.exemplarReturned && p.state == EntrySeries {
|
||||
// We only ever return one exemplar per (non-native-histogram) series.
|
||||
|
@ -317,28 +320,42 @@ func (p *ProtobufParser) Exemplar(ex *exemplar.Exemplar) bool {
|
|||
case dto.MetricType_COUNTER:
|
||||
exProto = m.GetCounter().GetExemplar()
|
||||
case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM:
|
||||
bb := m.GetHistogram().GetBucket()
|
||||
isClassic := p.state == EntrySeries
|
||||
if p.fieldPos < 0 {
|
||||
if isClassic {
|
||||
return false // At _count or _sum.
|
||||
if !isClassic && len(m.GetHistogram().GetExemplars()) > 0 {
|
||||
exs := m.GetHistogram().GetExemplars()
|
||||
for p.exemplarPos < len(exs) {
|
||||
exProto = exs[p.exemplarPos]
|
||||
p.exemplarPos++
|
||||
if exProto != nil && exProto.GetTimestamp() != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
p.fieldPos = 0 // Start at 1st bucket for native histograms.
|
||||
}
|
||||
for p.fieldPos < len(bb) {
|
||||
exProto = bb[p.fieldPos].GetExemplar()
|
||||
if isClassic {
|
||||
break
|
||||
if exProto != nil && exProto.GetTimestamp() == nil {
|
||||
return false
|
||||
}
|
||||
p.fieldPos++
|
||||
// We deliberately drop exemplars with no timestamp only for native histograms.
|
||||
if exProto != nil && (isClassic || exProto.GetTimestamp() != nil) {
|
||||
break // Found a classic histogram exemplar or a native histogram exemplar with a timestamp.
|
||||
} else {
|
||||
bb := m.GetHistogram().GetBucket()
|
||||
if p.fieldPos < 0 {
|
||||
if isClassic {
|
||||
return false // At _count or _sum.
|
||||
}
|
||||
p.fieldPos = 0 // Start at 1st bucket for native histograms.
|
||||
}
|
||||
for p.fieldPos < len(bb) {
|
||||
exProto = bb[p.fieldPos].GetExemplar()
|
||||
if isClassic {
|
||||
break
|
||||
}
|
||||
p.fieldPos++
|
||||
// We deliberately drop exemplars with no timestamp only for native histograms.
|
||||
if exProto != nil && (isClassic || exProto.GetTimestamp() != nil) {
|
||||
break // Found a classic histogram exemplar or a native histogram exemplar with a timestamp.
|
||||
}
|
||||
}
|
||||
// If the last exemplar for native histograms has no timestamp, ignore it.
|
||||
if !isClassic && exProto.GetTimestamp() == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// If the last exemplar for native histograms has no timestamp, ignore it.
|
||||
if !isClassic && exProto.GetTimestamp() == nil {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
return false
|
||||
|
|
|
@ -596,6 +596,105 @@ metric: <
|
|||
>
|
||||
>
|
||||
|
||||
`,
|
||||
`name: "test_histogram_with_native_histogram_exemplars"
|
||||
help: "A histogram with native histogram exemplars."
|
||||
type: HISTOGRAM
|
||||
metric: <
|
||||
histogram: <
|
||||
sample_count: 175
|
||||
sample_sum: 0.0008280461746287094
|
||||
bucket: <
|
||||
cumulative_count: 2
|
||||
upper_bound: -0.0004899999999999998
|
||||
>
|
||||
bucket: <
|
||||
cumulative_count: 4
|
||||
upper_bound: -0.0003899999999999998
|
||||
exemplar: <
|
||||
label: <
|
||||
name: "dummyID"
|
||||
value: "59727"
|
||||
>
|
||||
value: -0.00039
|
||||
timestamp: <
|
||||
seconds: 1625851155
|
||||
nanos: 146848499
|
||||
>
|
||||
>
|
||||
>
|
||||
bucket: <
|
||||
cumulative_count: 16
|
||||
upper_bound: -0.0002899999999999998
|
||||
exemplar: <
|
||||
label: <
|
||||
name: "dummyID"
|
||||
value: "5617"
|
||||
>
|
||||
value: -0.00029
|
||||
>
|
||||
>
|
||||
schema: 3
|
||||
zero_threshold: 2.938735877055719e-39
|
||||
zero_count: 2
|
||||
negative_span: <
|
||||
offset: -162
|
||||
length: 1
|
||||
>
|
||||
negative_span: <
|
||||
offset: 23
|
||||
length: 4
|
||||
>
|
||||
negative_delta: 1
|
||||
negative_delta: 3
|
||||
negative_delta: -2
|
||||
negative_delta: -1
|
||||
negative_delta: 1
|
||||
positive_span: <
|
||||
offset: -161
|
||||
length: 1
|
||||
>
|
||||
positive_span: <
|
||||
offset: 8
|
||||
length: 3
|
||||
>
|
||||
positive_delta: 1
|
||||
positive_delta: 2
|
||||
positive_delta: -1
|
||||
positive_delta: -1
|
||||
exemplars: <
|
||||
label: <
|
||||
name: "dummyID"
|
||||
value: "59780"
|
||||
>
|
||||
value: -0.00039
|
||||
timestamp: <
|
||||
seconds: 1625851155
|
||||
nanos: 146848499
|
||||
>
|
||||
>
|
||||
exemplars: <
|
||||
label: <
|
||||
name: "dummyID"
|
||||
value: "5617"
|
||||
>
|
||||
value: -0.00029
|
||||
>
|
||||
exemplars: <
|
||||
label: <
|
||||
name: "dummyID"
|
||||
value: "59772"
|
||||
>
|
||||
value: -0.00052
|
||||
timestamp: <
|
||||
seconds: 1625851160
|
||||
nanos: 156848499
|
||||
>
|
||||
>
|
||||
>
|
||||
timestamp_ms: 1234568
|
||||
>
|
||||
|
||||
`,
|
||||
}
|
||||
|
||||
|
@ -1141,6 +1240,42 @@ func TestProtobufParse(t *testing.T) {
|
|||
"__name__", "test_gaugehistogram_with_createdtimestamp",
|
||||
),
|
||||
},
|
||||
{
|
||||
m: "test_histogram_with_native_histogram_exemplars",
|
||||
help: "A histogram with native histogram exemplars.",
|
||||
},
|
||||
{
|
||||
m: "test_histogram_with_native_histogram_exemplars",
|
||||
typ: model.MetricTypeHistogram,
|
||||
},
|
||||
{
|
||||
m: "test_histogram_with_native_histogram_exemplars",
|
||||
t: 1234568,
|
||||
shs: &histogram.Histogram{
|
||||
Count: 175,
|
||||
ZeroCount: 2,
|
||||
Sum: 0.0008280461746287094,
|
||||
ZeroThreshold: 2.938735877055719e-39,
|
||||
Schema: 3,
|
||||
PositiveSpans: []histogram.Span{
|
||||
{Offset: -161, Length: 1},
|
||||
{Offset: 8, Length: 3},
|
||||
},
|
||||
NegativeSpans: []histogram.Span{
|
||||
{Offset: -162, Length: 1},
|
||||
{Offset: 23, Length: 4},
|
||||
},
|
||||
PositiveBuckets: []int64{1, 2, -1, -1},
|
||||
NegativeBuckets: []int64{1, 3, -2, -1, 1},
|
||||
},
|
||||
lset: labels.FromStrings(
|
||||
"__name__", "test_histogram_with_native_histogram_exemplars",
|
||||
),
|
||||
e: []exemplar.Exemplar{
|
||||
{Labels: labels.FromStrings("dummyID", "59780"), Value: -0.00039, HasTs: true, Ts: 1625851155146},
|
||||
{Labels: labels.FromStrings("dummyID", "59772"), Value: -0.00052, HasTs: true, Ts: 1625851160156},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1959,6 +2094,100 @@ func TestProtobufParse(t *testing.T) {
|
|||
"__name__", "test_gaugehistogram_with_createdtimestamp",
|
||||
),
|
||||
},
|
||||
{ // 94
|
||||
m: "test_histogram_with_native_histogram_exemplars",
|
||||
help: "A histogram with native histogram exemplars.",
|
||||
},
|
||||
{ // 95
|
||||
m: "test_histogram_with_native_histogram_exemplars",
|
||||
typ: model.MetricTypeHistogram,
|
||||
},
|
||||
{ // 96
|
||||
m: "test_histogram_with_native_histogram_exemplars",
|
||||
t: 1234568,
|
||||
shs: &histogram.Histogram{
|
||||
Count: 175,
|
||||
ZeroCount: 2,
|
||||
Sum: 0.0008280461746287094,
|
||||
ZeroThreshold: 2.938735877055719e-39,
|
||||
Schema: 3,
|
||||
PositiveSpans: []histogram.Span{
|
||||
{Offset: -161, Length: 1},
|
||||
{Offset: 8, Length: 3},
|
||||
},
|
||||
NegativeSpans: []histogram.Span{
|
||||
{Offset: -162, Length: 1},
|
||||
{Offset: 23, Length: 4},
|
||||
},
|
||||
PositiveBuckets: []int64{1, 2, -1, -1},
|
||||
NegativeBuckets: []int64{1, 3, -2, -1, 1},
|
||||
},
|
||||
lset: labels.FromStrings(
|
||||
"__name__", "test_histogram_with_native_histogram_exemplars",
|
||||
),
|
||||
e: []exemplar.Exemplar{
|
||||
{Labels: labels.FromStrings("dummyID", "59780"), Value: -0.00039, HasTs: true, Ts: 1625851155146},
|
||||
{Labels: labels.FromStrings("dummyID", "59772"), Value: -0.00052, HasTs: true, Ts: 1625851160156},
|
||||
},
|
||||
},
|
||||
{ // 97
|
||||
m: "test_histogram_with_native_histogram_exemplars_count",
|
||||
t: 1234568,
|
||||
v: 175,
|
||||
lset: labels.FromStrings(
|
||||
"__name__", "test_histogram_with_native_histogram_exemplars_count",
|
||||
),
|
||||
},
|
||||
{ // 98
|
||||
m: "test_histogram_with_native_histogram_exemplars_sum",
|
||||
t: 1234568,
|
||||
v: 0.0008280461746287094,
|
||||
lset: labels.FromStrings(
|
||||
"__name__", "test_histogram_with_native_histogram_exemplars_sum",
|
||||
),
|
||||
},
|
||||
{ // 99
|
||||
m: "test_histogram_with_native_histogram_exemplars_bucket\xffle\xff-0.0004899999999999998",
|
||||
t: 1234568,
|
||||
v: 2,
|
||||
lset: labels.FromStrings(
|
||||
"__name__", "test_histogram_with_native_histogram_exemplars_bucket",
|
||||
"le", "-0.0004899999999999998",
|
||||
),
|
||||
},
|
||||
{ // 100
|
||||
m: "test_histogram_with_native_histogram_exemplars_bucket\xffle\xff-0.0003899999999999998",
|
||||
t: 1234568,
|
||||
v: 4,
|
||||
lset: labels.FromStrings(
|
||||
"__name__", "test_histogram_with_native_histogram_exemplars_bucket",
|
||||
"le", "-0.0003899999999999998",
|
||||
),
|
||||
e: []exemplar.Exemplar{
|
||||
{Labels: labels.FromStrings("dummyID", "59727"), Value: -0.00039, HasTs: true, Ts: 1625851155146},
|
||||
},
|
||||
},
|
||||
{ // 101
|
||||
m: "test_histogram_with_native_histogram_exemplars_bucket\xffle\xff-0.0002899999999999998",
|
||||
t: 1234568,
|
||||
v: 16,
|
||||
lset: labels.FromStrings(
|
||||
"__name__", "test_histogram_with_native_histogram_exemplars_bucket",
|
||||
"le", "-0.0002899999999999998",
|
||||
),
|
||||
e: []exemplar.Exemplar{
|
||||
{Labels: labels.FromStrings("dummyID", "5617"), Value: -0.00029, HasTs: false},
|
||||
},
|
||||
},
|
||||
{ // 102
|
||||
m: "test_histogram_with_native_histogram_exemplars_bucket\xffle\xff+Inf",
|
||||
t: 1234568,
|
||||
v: 175,
|
||||
lset: labels.FromStrings(
|
||||
"__name__", "test_histogram_with_native_histogram_exemplars_bucket",
|
||||
"le", "+Inf",
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue