Phase out native histogram feature flag

The detailed plan for this is laid out in
https://github.com/prometheus/prometheus/issues/16572 .

This commit adds a global and local scrape config option
`scrape_native_histograms`, which has to be set to true to ingest
native histograms.

To ease the transition, the feature flag is changed to simply set the
default of `scrape_native_histograms` to true.

Further implications:

- The default scrape protocols now depend on the
  `scrape_native_histograms` setting.
- Everywhere else, histograms are now "on by default".

Documentation beyond the one for the feature flag and the scrape
config are deliberately left out. See
https://github.com/prometheus/prometheus/pull/17232 for that.

Signed-off-by: beorn7 <beorn@grafana.com>
This commit is contained in:
beorn7
2025-10-09 16:56:13 +02:00
parent 72960c076d
commit ad7d1aed99
33 changed files with 1857 additions and 339 deletions

View File

@@ -149,7 +149,7 @@ func benchParse(b *testing.B, data []byte, parser string) {
}
case "promproto":
newParserFn = func(b []byte, st *labels.SymbolTable) Parser {
return NewProtobufParser(b, true, false, false, st)
return NewProtobufParser(b, false, true, false, false, st)
}
case "omtext":
newParserFn = func(b []byte, st *labels.SymbolTable) Parser {
@@ -276,7 +276,7 @@ func BenchmarkCreatedTimestampPromProto(b *testing.B) {
data := createTestProtoBuf(b).Bytes()
st := labels.NewSymbolTable()
p := NewProtobufParser(data, true, false, false, st)
p := NewProtobufParser(data, false, true, false, false, st)
found := false
Inner:

View File

@@ -127,6 +127,17 @@ type ParserOptions struct {
// in the parsed metrics.
EnableTypeAndUnitLabels bool
// IgnoreNativeHistograms causes the parser to completely ignore all
// parts of native histograms, but to keep the ability to convert
// classic histograms to NHCB. This has the implication that even a
// histogram that has some native parts but not a single classic bucket
// will be parsed as a classic histogram (with only the +Inf bucket and
// count and sum). Setting this also allows converting a classic
// histogram that already has a native representation to an NHCB. This
// option has no effect on parsers for formats that do not support
// native histograms.
IgnoreNativeHistograms bool
// ConvertClassicHistogramsToNHCB enables conversion of classic histograms
// to native histogram custom buckets (NHCB) format.
ConvertClassicHistogramsToNHCB bool
@@ -168,7 +179,14 @@ func New(b []byte, contentType string, st *labels.SymbolTable, opts ParserOption
o.enableTypeAndUnitLabels = opts.EnableTypeAndUnitLabels
})
case "application/vnd.google.protobuf":
return NewProtobufParser(b, opts.KeepClassicOnClassicAndNativeHistograms, opts.ConvertClassicHistogramsToNHCB, opts.EnableTypeAndUnitLabels, st), err
return NewProtobufParser(
b,
opts.IgnoreNativeHistograms,
opts.KeepClassicOnClassicAndNativeHistograms,
opts.ConvertClassicHistogramsToNHCB,
opts.EnableTypeAndUnitLabels,
st,
), err
case "text/plain":
baseParser = NewPromParser(b, st, opts.EnableTypeAndUnitLabels)
default:

View File

@@ -77,6 +77,8 @@ type ProtobufParser struct {
// that we have to decode the next MetricDescriptor.
state Entry
// Whether to completely ignore any native parts of histograms.
ignoreNativeHistograms bool
// Whether to also parse a classic histogram that is also present as a
// native histogram.
parseClassicHistograms bool
@@ -93,7 +95,11 @@ type ProtobufParser struct {
}
// NewProtobufParser returns a parser for the payload in the byte slice.
func NewProtobufParser(b []byte, parseClassicHistograms, convertClassicHistogramsToNHCB, enableTypeAndUnitLabels bool, st *labels.SymbolTable) Parser {
func NewProtobufParser(
b []byte,
ignoreNativeHistograms, parseClassicHistograms, convertClassicHistogramsToNHCB, enableTypeAndUnitLabels bool,
st *labels.SymbolTable,
) Parser {
builder := labels.NewScratchBuilderWithSymbolTable(st, 16)
builder.SetUnsafeAdd(true)
return &ProtobufParser{
@@ -102,6 +108,7 @@ func NewProtobufParser(b []byte, parseClassicHistograms, convertClassicHistogram
builder: builder,
state: EntryInvalid,
ignoreNativeHistograms: ignoreNativeHistograms,
parseClassicHistograms: parseClassicHistograms,
enableTypeAndUnitLabels: enableTypeAndUnitLabels,
convertClassicHistogramsToNHCB: convertClassicHistogramsToNHCB,
@@ -196,7 +203,7 @@ func (p *ProtobufParser) Histogram() ([]byte, *int64, *histogram.Histogram, *his
h = p.dec.GetHistogram()
)
if !isNativeHistogram(h) {
if p.ignoreNativeHistograms || !isNativeHistogram(h) {
// This only happens if we have a classic histogram and
// we converted it to NHCB already in Next.
if *ts != 0 {
@@ -494,7 +501,7 @@ func (p *ProtobufParser) Next() (Entry, error) {
case EntryType:
t := p.dec.GetType()
if t == dto.MetricType_HISTOGRAM || t == dto.MetricType_GAUGE_HISTOGRAM {
if !isNativeHistogram(p.dec.GetHistogram()) {
if p.ignoreNativeHistograms || !isNativeHistogram(p.dec.GetHistogram()) {
p.state = EntrySeries
p.fieldPos = -3 // We have not returned anything, let p.Next() increment it to -2.
return p.Next()
@@ -515,7 +522,8 @@ func (p *ProtobufParser) Next() (Entry, error) {
t == dto.MetricType_GAUGE_HISTOGRAM {
// Non-trivial series (complex metrics, with magic suffixes).
isClassicHistogram := (t == dto.MetricType_HISTOGRAM || t == dto.MetricType_GAUGE_HISTOGRAM) && !isNativeHistogram(p.dec.GetHistogram())
isClassicHistogram := (t == dto.MetricType_HISTOGRAM || t == dto.MetricType_GAUGE_HISTOGRAM) &&
(p.ignoreNativeHistograms || !isNativeHistogram(p.dec.GetHistogram()))
skipSeries := p.convertClassicHistogramsToNHCB && isClassicHistogram && !p.parseClassicHistograms
// Did we iterate over all the classic representations fields?
@@ -591,10 +599,11 @@ func (p *ProtobufParser) Next() (Entry, error) {
return EntryInvalid, err
}
// If this is a metric family does not contain native
// histograms, it means we are here thanks to NHCB conversion.
// Return to classic histograms for the consistent flow.
if !isNativeHistogram(p.dec.GetHistogram()) {
// If this metric is not a native histograms or we are ignoring
// native histograms, it means we are here thanks to NHCB
// conversion. Return to classic histograms for the consistent
// flow.
if p.ignoreNativeHistograms || !isNativeHistogram(p.dec.GetHistogram()) {
return switchToClassic()
}

File diff suppressed because it is too large Load Diff