mirror of
https://github.com/prometheus/prometheus.git
synced 2025-08-06 06:07:11 +02:00
Merge ab09521a69
into 25aee26a57
This commit is contained in:
commit
3945b525e1
@ -297,6 +297,9 @@ func (c *flagConfig) setFeatureListOptions(logger *slog.Logger) error {
|
||||
case "use-uncached-io":
|
||||
c.tsdb.UseUncachedIO = true
|
||||
logger.Info("Experimental Uncached IO is enabled.")
|
||||
case "otel-suffix":
|
||||
c.scrape.EnableOtelSuffix = true
|
||||
logger.Info("Experimental otel suffix is enabled.")
|
||||
default:
|
||||
logger.Warn("Unknown option for --enable-feature", "option", o)
|
||||
}
|
||||
|
@ -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, st)
|
||||
return NewProtobufParser(b, true, false, false, st)
|
||||
}
|
||||
case "omtext":
|
||||
newParserFn = func(b []byte, st *labels.SymbolTable) Parser {
|
||||
@ -275,7 +275,7 @@ func BenchmarkCreatedTimestampPromProto(b *testing.B) {
|
||||
data := createTestProtoBuf(b).Bytes()
|
||||
|
||||
st := labels.NewSymbolTable()
|
||||
p := NewProtobufParser(data, true, false, st)
|
||||
p := NewProtobufParser(data, true, false, false, st)
|
||||
|
||||
found := false
|
||||
Inner:
|
||||
|
@ -130,7 +130,7 @@ func extractMediaType(contentType, fallbackType string) (string, error) {
|
||||
// An error may also be returned if fallbackType had to be used or there was some
|
||||
// other error parsing the supplied Content-Type.
|
||||
// If the returned parser is nil then the scrape must fail.
|
||||
func New(b []byte, contentType, fallbackType string, parseClassicHistograms, skipOMCTSeries, enableTypeAndUnitLabels bool, st *labels.SymbolTable) (Parser, error) {
|
||||
func New(b []byte, contentType, fallbackType string, parseClassicHistograms, skipOMCTSeries, enableTypeAndUnitLabels bool, enableOtelSuffix bool, st *labels.SymbolTable) (Parser, error) {
|
||||
mediaType, err := extractMediaType(contentType, fallbackType)
|
||||
// err may be nil or something we want to warn about.
|
||||
|
||||
@ -139,9 +139,10 @@ func New(b []byte, contentType, fallbackType string, parseClassicHistograms, ski
|
||||
return NewOpenMetricsParser(b, st, func(o *openMetricsParserOptions) {
|
||||
o.skipCTSeries = skipOMCTSeries
|
||||
o.enableTypeAndUnitLabels = enableTypeAndUnitLabels
|
||||
o.enableOtelSuffix = enableOtelSuffix
|
||||
}), err
|
||||
case "application/vnd.google.protobuf":
|
||||
return NewProtobufParser(b, parseClassicHistograms, enableTypeAndUnitLabels, st), err
|
||||
return NewProtobufParser(b, parseClassicHistograms, enableTypeAndUnitLabels, enableOtelSuffix, st), err
|
||||
case "text/plain":
|
||||
return NewPromParser(b, st, enableTypeAndUnitLabels), err
|
||||
default:
|
||||
|
@ -168,7 +168,7 @@ func TestNewParser(t *testing.T) {
|
||||
|
||||
fallbackProtoMediaType := tt.fallbackScrapeProtocol.HeaderMediaType()
|
||||
|
||||
p, err := New([]byte{}, tt.contentType, fallbackProtoMediaType, false, false, false, labels.NewSymbolTable())
|
||||
p, err := New([]byte{}, tt.contentType, fallbackProtoMediaType, false, false, false, false, labels.NewSymbolTable())
|
||||
tt.validateParser(t, p)
|
||||
if tt.err == "" {
|
||||
require.NoError(t, err)
|
||||
|
@ -598,7 +598,7 @@ func TestNHCBParser_NoNHCBWhenExponential(t *testing.T) {
|
||||
func() (string, parserFactory, []int, parserOptions) {
|
||||
factory := func(keepClassic bool) Parser {
|
||||
inputBuf := createTestProtoBufHistogram(t)
|
||||
return NewProtobufParser(inputBuf.Bytes(), keepClassic, false, labels.NewSymbolTable())
|
||||
return NewProtobufParser(inputBuf.Bytes(), keepClassic, false, false, labels.NewSymbolTable())
|
||||
}
|
||||
return "ProtoBuf", factory, []int{1, 2, 3}, parserOptions{useUTF8sep: true, hasCreatedTimeStamp: true}
|
||||
},
|
||||
@ -1121,7 +1121,7 @@ metric: <
|
||||
},
|
||||
}
|
||||
|
||||
p := NewProtobufParser(buf.Bytes(), false, false, labels.NewSymbolTable())
|
||||
p := NewProtobufParser(buf.Bytes(), false, false, false, labels.NewSymbolTable())
|
||||
p = NewNHCBParser(p, labels.NewSymbolTable(), false)
|
||||
got := testParse(t, p)
|
||||
requireEntries(t, exp, got)
|
||||
|
@ -112,11 +112,13 @@ type OpenMetricsParser struct {
|
||||
visitedMFName []byte
|
||||
skipCTSeries bool
|
||||
enableTypeAndUnitLabels bool
|
||||
enableOtelSuffix bool
|
||||
}
|
||||
|
||||
type openMetricsParserOptions struct {
|
||||
skipCTSeries bool
|
||||
enableTypeAndUnitLabels bool
|
||||
enableOtelSuffix bool
|
||||
}
|
||||
|
||||
type OpenMetricsOption func(*openMetricsParserOptions)
|
||||
@ -155,6 +157,7 @@ func NewOpenMetricsParser(b []byte, st *labels.SymbolTable, opts ...OpenMetricsO
|
||||
builder: labels.NewScratchBuilderWithSymbolTable(st, 16),
|
||||
skipCTSeries: options.skipCTSeries,
|
||||
enableTypeAndUnitLabels: options.enableTypeAndUnitLabels,
|
||||
enableOtelSuffix: options.enableOtelSuffix,
|
||||
}
|
||||
|
||||
return parser
|
||||
@ -524,7 +527,7 @@ func (p *OpenMetricsParser) Next() (Entry, error) {
|
||||
case tUnit:
|
||||
p.unit = string(p.text)
|
||||
m := yoloString(p.l.b[p.offsets[0]:p.offsets[1]])
|
||||
if len(p.unit) > 0 {
|
||||
if len(p.unit) > 0 && !p.enableOtelSuffix {
|
||||
if !strings.HasSuffix(m, p.unit) || len(m) < len(p.unit)+1 || p.l.b[p.offsets[1]-len(p.unit)-1] != '_' {
|
||||
return EntryInvalid, fmt.Errorf("unit %q not a suffix of metric %q", p.unit, m)
|
||||
}
|
||||
|
@ -80,10 +80,12 @@ type ProtobufParser struct {
|
||||
// native histogram.
|
||||
parseClassicHistograms bool
|
||||
enableTypeAndUnitLabels bool
|
||||
|
||||
enableOtelSuffix bool
|
||||
}
|
||||
|
||||
// NewProtobufParser returns a parser for the payload in the byte slice.
|
||||
func NewProtobufParser(b []byte, parseClassicHistograms, enableTypeAndUnitLabels bool, st *labels.SymbolTable) Parser {
|
||||
func NewProtobufParser(b []byte, parseClassicHistograms, enableTypeAndUnitLabels bool, enableOtelSuffix bool, st *labels.SymbolTable) Parser {
|
||||
return &ProtobufParser{
|
||||
dec: dto.NewMetricStreamingDecoder(b),
|
||||
entryBytes: &bytes.Buffer{},
|
||||
@ -92,6 +94,7 @@ func NewProtobufParser(b []byte, parseClassicHistograms, enableTypeAndUnitLabels
|
||||
state: EntryInvalid,
|
||||
parseClassicHistograms: parseClassicHistograms,
|
||||
enableTypeAndUnitLabels: enableTypeAndUnitLabels,
|
||||
enableOtelSuffix: enableOtelSuffix,
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,7 +449,7 @@ func (p *ProtobufParser) Next() (Entry, error) {
|
||||
return EntryInvalid, fmt.Errorf("unknown metric type for metric %q: %s", name, p.dec.GetType())
|
||||
}
|
||||
unit := p.dec.GetUnit()
|
||||
if len(unit) > 0 {
|
||||
if len(unit) > 0 && !p.enableOtelSuffix {
|
||||
if p.dec.GetType() == dto.MetricType_COUNTER && strings.HasSuffix(name, "_total") {
|
||||
if !strings.HasSuffix(name[:len(name)-6], unit) || len(name)-6 < len(unit)+1 || name[len(name)-6-len(unit)-1] != '_' {
|
||||
return EntryInvalid, fmt.Errorf("unit %q not a suffix of counter %q", unit, name)
|
||||
@ -609,12 +612,20 @@ func (p *ProtobufParser) getMagicName() string {
|
||||
return p.dec.GetName()
|
||||
}
|
||||
if p.fieldPos == -2 {
|
||||
return p.dec.GetName() + "_count"
|
||||
if p.enableOtelSuffix {
|
||||
return p.dec.GetName() + ".count"
|
||||
} else {
|
||||
return p.dec.GetName() + "_count"
|
||||
}
|
||||
}
|
||||
if p.fieldPos == -1 {
|
||||
return p.dec.GetName() + "_sum"
|
||||
if p.enableOtelSuffix {
|
||||
return p.dec.GetName() + ".sum"
|
||||
} else {
|
||||
return p.dec.GetName() + "_sum"
|
||||
}
|
||||
}
|
||||
if t == dto.MetricType_HISTOGRAM || t == dto.MetricType_GAUGE_HISTOGRAM {
|
||||
if !p.enableOtelSuffix && (t == dto.MetricType_HISTOGRAM || t == dto.MetricType_GAUGE_HISTOGRAM) {
|
||||
return p.dec.GetName() + "_bucket"
|
||||
}
|
||||
return p.dec.GetName()
|
||||
|
@ -833,7 +833,7 @@ func TestProtobufParse(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "parseClassicHistograms=false/enableTypeAndUnitLabels=false",
|
||||
parser: NewProtobufParser(inputBuf.Bytes(), false, false, labels.NewSymbolTable()),
|
||||
parser: NewProtobufParser(inputBuf.Bytes(), false, false, false, labels.NewSymbolTable()),
|
||||
expected: []parsedEntry{
|
||||
{
|
||||
m: "go_build_info",
|
||||
@ -1468,7 +1468,7 @@ func TestProtobufParse(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "parseClassicHistograms=false/enableTypeAndUnitLabels=true",
|
||||
parser: NewProtobufParser(inputBuf.Bytes(), false, true, labels.NewSymbolTable()),
|
||||
parser: NewProtobufParser(inputBuf.Bytes(), false, true, false, labels.NewSymbolTable()),
|
||||
expected: []parsedEntry{
|
||||
{
|
||||
m: "go_build_info",
|
||||
@ -2140,7 +2140,7 @@ func TestProtobufParse(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "parseClassicHistograms=true/enableTypeAndUnitLabels=false",
|
||||
parser: NewProtobufParser(inputBuf.Bytes(), true, false, labels.NewSymbolTable()),
|
||||
parser: NewProtobufParser(inputBuf.Bytes(), true, false, false, labels.NewSymbolTable()),
|
||||
expected: []parsedEntry{
|
||||
{
|
||||
m: "go_build_info",
|
||||
|
@ -61,7 +61,7 @@ const (
|
||||
var symbolTable = labels.NewSymbolTable()
|
||||
|
||||
func fuzzParseMetricWithContentType(in []byte, contentType string) int {
|
||||
p, warning := textparse.New(in, contentType, "", false, false, false, symbolTable)
|
||||
p, warning := textparse.New(in, contentType, "", false, false, false, false, symbolTable)
|
||||
if p == nil || warning != nil {
|
||||
// An invalid content type is being passed, which should not happen
|
||||
// in this context.
|
||||
|
@ -92,6 +92,9 @@ type Options struct {
|
||||
// EnableTypeAndUnitLabels
|
||||
EnableTypeAndUnitLabels bool
|
||||
|
||||
// Allows metric names not to be suffixed with their unit and use dots for magic suffix (e.g. ".sum").
|
||||
EnableOtelSuffix bool
|
||||
|
||||
// Optional HTTP client options to use when scraping.
|
||||
HTTPClientOptions []config_util.HTTPClientOption
|
||||
|
||||
|
@ -211,6 +211,7 @@ func newScrapePool(cfg *config.ScrapeConfig, app storage.Appendable, offsetSeed
|
||||
options.EnableNativeHistogramsIngestion,
|
||||
options.EnableCreatedTimestampZeroIngestion,
|
||||
options.EnableTypeAndUnitLabels,
|
||||
options.EnableOtelSuffix,
|
||||
options.ExtraMetrics,
|
||||
options.AppendMetadata,
|
||||
opts.target,
|
||||
@ -933,6 +934,7 @@ type scrapeLoop struct {
|
||||
enableNativeHistogramIngestion bool
|
||||
enableCTZeroIngestion bool
|
||||
enableTypeAndUnitLabels bool
|
||||
enableOtelSuffix bool
|
||||
|
||||
appender func(ctx context.Context) storage.Appender
|
||||
symbolTable *labels.SymbolTable
|
||||
@ -1241,6 +1243,7 @@ func newScrapeLoop(ctx context.Context,
|
||||
enableNativeHistogramIngestion bool,
|
||||
enableCTZeroIngestion bool,
|
||||
enableTypeAndUnitLabels bool,
|
||||
enableOtelSuffix bool,
|
||||
reportExtraMetrics bool,
|
||||
appendMetadataToWAL bool,
|
||||
target *Target,
|
||||
@ -1299,6 +1302,7 @@ func newScrapeLoop(ctx context.Context,
|
||||
enableNativeHistogramIngestion: enableNativeHistogramIngestion,
|
||||
enableCTZeroIngestion: enableCTZeroIngestion,
|
||||
enableTypeAndUnitLabels: enableTypeAndUnitLabels,
|
||||
enableOtelSuffix: enableOtelSuffix,
|
||||
reportExtraMetrics: reportExtraMetrics,
|
||||
appendMetadataToWAL: appendMetadataToWAL,
|
||||
metrics: metrics,
|
||||
@ -1625,7 +1629,7 @@ func (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string,
|
||||
return
|
||||
}
|
||||
|
||||
p, err := textparse.New(b, contentType, sl.fallbackScrapeProtocol, sl.alwaysScrapeClassicHist, sl.enableCTZeroIngestion, sl.enableTypeAndUnitLabels, sl.symbolTable)
|
||||
p, err := textparse.New(b, contentType, sl.fallbackScrapeProtocol, sl.alwaysScrapeClassicHist, sl.enableCTZeroIngestion, sl.enableTypeAndUnitLabels, sl.enableOtelSuffix, sl.symbolTable)
|
||||
if p == nil {
|
||||
sl.l.Error(
|
||||
"Failed to determine correct type of scrape target.",
|
||||
|
@ -986,6 +986,7 @@ func newBasicScrapeLoopWithFallback(t testing.TB, ctx context.Context, scraper s
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
nil,
|
||||
false,
|
||||
@ -1135,6 +1136,7 @@ func TestScrapeLoopRun(t *testing.T) {
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
nil,
|
||||
false,
|
||||
scrapeMetrics,
|
||||
@ -1284,6 +1286,7 @@ func TestScrapeLoopMetadata(t *testing.T) {
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
nil,
|
||||
false,
|
||||
scrapeMetrics,
|
||||
@ -2011,7 +2014,7 @@ func TestScrapeLoopAppendCacheEntryButErrNotFound(t *testing.T) {
|
||||
fakeRef := storage.SeriesRef(1)
|
||||
expValue := float64(1)
|
||||
metric := []byte(`metric{n="1"} 1`)
|
||||
p, warning := textparse.New(metric, "text/plain", "", false, false, false, labels.NewSymbolTable())
|
||||
p, warning := textparse.New(metric, "text/plain", "", false, false, false, false, labels.NewSymbolTable())
|
||||
require.NotNil(t, p)
|
||||
require.NoError(t, warning)
|
||||
|
||||
|
@ -392,7 +392,7 @@ func TestFederationWithNativeHistograms(t *testing.T) {
|
||||
require.Equal(t, http.StatusOK, res.Code)
|
||||
body, err := io.ReadAll(res.Body)
|
||||
require.NoError(t, err)
|
||||
p := textparse.NewProtobufParser(body, false, false, labels.NewSymbolTable())
|
||||
p := textparse.NewProtobufParser(body, false, false, false, labels.NewSymbolTable())
|
||||
var actVec promql.Vector
|
||||
metricFamilies := 0
|
||||
l := labels.Labels{}
|
||||
|
Loading…
Reference in New Issue
Block a user