Add global config option for always_scrape_classic_histograms

Addresses https://github.com/prometheus/prometheus/issues/16371
This will help with migrating to native histograms with `convert_classic_histograms_to_nhcb` since users may still need to keep the classic histograms during a migration

Signed-off-by: chardch <otwordsne@gmail.com>
This commit is contained in:
chardch 2025-04-17 13:09:11 -07:00
parent c15140f863
commit a1c157aaef
9 changed files with 145 additions and 35 deletions

View File

@ -169,6 +169,7 @@ var (
// changes to DefaultNativeHistogramScrapeProtocols. // changes to DefaultNativeHistogramScrapeProtocols.
ScrapeProtocols: DefaultScrapeProtocols, ScrapeProtocols: DefaultScrapeProtocols,
ConvertClassicHistogramsToNHCB: false, ConvertClassicHistogramsToNHCB: false,
AlwaysScrapeClassicHistograms: false,
} }
DefaultRuntimeConfig = RuntimeConfig{ DefaultRuntimeConfig = RuntimeConfig{
@ -178,14 +179,13 @@ var (
// DefaultScrapeConfig is the default scrape configuration. // DefaultScrapeConfig is the default scrape configuration.
DefaultScrapeConfig = ScrapeConfig{ DefaultScrapeConfig = ScrapeConfig{
// ScrapeTimeout, ScrapeInterval and ScrapeProtocols default to the configured globals. // ScrapeTimeout, ScrapeInterval, ScrapeProtocols, AlwaysScrapeClassicHistograms, and ConvertClassicHistogramsToNHCB default to the configured globals.
AlwaysScrapeClassicHistograms: false, MetricsPath: "/metrics",
MetricsPath: "/metrics", Scheme: "http",
Scheme: "http", HonorLabels: false,
HonorLabels: false, HonorTimestamps: true,
HonorTimestamps: true, HTTPClientConfig: config.DefaultHTTPClientConfig,
HTTPClientConfig: config.DefaultHTTPClientConfig, EnableCompression: true,
EnableCompression: true,
} }
// DefaultAlertmanagerConfig is the default alertmanager configuration. // DefaultAlertmanagerConfig is the default alertmanager configuration.
@ -489,6 +489,8 @@ type GlobalConfig struct {
MetricNameEscapingScheme string `yaml:"metric_name_escaping_scheme,omitempty"` MetricNameEscapingScheme string `yaml:"metric_name_escaping_scheme,omitempty"`
// Whether to convert all scraped classic histograms into native histograms with custom buckets. // Whether to convert all scraped classic histograms into native histograms with custom buckets.
ConvertClassicHistogramsToNHCB bool `yaml:"convert_classic_histograms_to_nhcb,omitempty"` ConvertClassicHistogramsToNHCB bool `yaml:"convert_classic_histograms_to_nhcb,omitempty"`
// Whether to scrape a classic histogram, even if it is also exposed as a native histogram.
AlwaysScrapeClassicHistograms bool `yaml:"always_scrape_classic_histograms,omitempty"`
} }
// ScrapeProtocol represents supported protocol for scraping metrics. // ScrapeProtocol represents supported protocol for scraping metrics.
@ -645,7 +647,8 @@ func (c *GlobalConfig) isZero() bool {
c.QueryLogFile == "" && c.QueryLogFile == "" &&
c.ScrapeFailureLogFile == "" && c.ScrapeFailureLogFile == "" &&
c.ScrapeProtocols == nil && c.ScrapeProtocols == nil &&
!c.ConvertClassicHistogramsToNHCB !c.ConvertClassicHistogramsToNHCB &&
!c.AlwaysScrapeClassicHistograms
} }
// RuntimeConfig configures the values for the process behavior. // RuntimeConfig configures the values for the process behavior.
@ -690,7 +693,7 @@ type ScrapeConfig struct {
// OpenMetricsText1.0.0, PrometheusText1.0.0, PrometheusText0.0.4. // OpenMetricsText1.0.0, PrometheusText1.0.0, PrometheusText0.0.4.
ScrapeFallbackProtocol ScrapeProtocol `yaml:"fallback_scrape_protocol,omitempty"` ScrapeFallbackProtocol ScrapeProtocol `yaml:"fallback_scrape_protocol,omitempty"`
// Whether to scrape a classic histogram, even if it is also exposed as a native histogram. // Whether to scrape a classic histogram, even if it is also exposed as a native histogram.
AlwaysScrapeClassicHistograms bool `yaml:"always_scrape_classic_histograms,omitempty"` AlwaysScrapeClassicHistograms *bool `yaml:"always_scrape_classic_histograms,omitempty"`
// Whether to convert all scraped classic histograms into a native histogram with custom buckets. // Whether to convert all scraped classic histograms into a native histogram with custom buckets.
ConvertClassicHistogramsToNHCB *bool `yaml:"convert_classic_histograms_to_nhcb,omitempty"` ConvertClassicHistogramsToNHCB *bool `yaml:"convert_classic_histograms_to_nhcb,omitempty"`
// File to which scrape failures are logged. // File to which scrape failures are logged.
@ -904,6 +907,11 @@ func (c *ScrapeConfig) Validate(globalConfig GlobalConfig) error {
c.ConvertClassicHistogramsToNHCB = &global c.ConvertClassicHistogramsToNHCB = &global
} }
if c.AlwaysScrapeClassicHistograms == nil {
global := globalConfig.AlwaysScrapeClassicHistograms
c.AlwaysScrapeClassicHistograms = &global
}
return nil return nil
} }
@ -931,6 +939,11 @@ func (c *ScrapeConfig) ConvertClassicHistogramsToNHCBEnabled() bool {
return c.ConvertClassicHistogramsToNHCB != nil && *c.ConvertClassicHistogramsToNHCB return c.ConvertClassicHistogramsToNHCB != nil && *c.ConvertClassicHistogramsToNHCB
} }
// AlwaysScrapeClassicHistogramsEnabled returns whether to always scrape classic histograms.
func (c *ScrapeConfig) AlwaysScrapeClassicHistogramsEnabled() bool {
return c.AlwaysScrapeClassicHistograms != nil && *c.AlwaysScrapeClassicHistograms
}
// StorageConfig configures runtime reloadable configuration options. // StorageConfig configures runtime reloadable configuration options.
type StorageConfig struct { type StorageConfig struct {
TSDBConfig *TSDBConfig `yaml:"tsdb,omitempty"` TSDBConfig *TSDBConfig `yaml:"tsdb,omitempty"`

View File

@ -102,6 +102,7 @@ var expectedConf = &Config{
LabelNameLengthLimit: globLabelNameLengthLimit, LabelNameLengthLimit: globLabelNameLengthLimit,
LabelValueLengthLimit: globLabelValueLengthLimit, LabelValueLengthLimit: globLabelValueLengthLimit,
ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols, ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols,
AlwaysScrapeClassicHistograms: false,
ConvertClassicHistogramsToNHCB: false, ConvertClassicHistogramsToNHCB: false,
}, },
@ -223,6 +224,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: "testdata/fail_prom.log", ScrapeFailureLogFile: "testdata/fail_prom.log",
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -339,6 +341,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.HTTPClientConfig{ HTTPClientConfig: config.HTTPClientConfig{
@ -440,6 +443,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -499,6 +503,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: "/metrics", MetricsPath: "/metrics",
@ -536,6 +541,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -579,6 +585,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -622,6 +629,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -655,6 +663,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -696,6 +705,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -734,6 +744,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -779,6 +790,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -814,6 +826,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -852,6 +865,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -883,6 +897,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -917,6 +932,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: "/federate", MetricsPath: "/federate",
@ -951,6 +967,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -985,6 +1002,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1016,6 +1034,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1055,6 +1074,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1093,6 +1113,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1128,6 +1149,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1162,6 +1184,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1200,6 +1223,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1241,6 +1265,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1301,6 +1326,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1332,6 +1358,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.DefaultHTTPClientConfig, HTTPClientConfig: config.DefaultHTTPClientConfig,
@ -1374,6 +1401,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.DefaultHTTPClientConfig, HTTPClientConfig: config.DefaultHTTPClientConfig,
@ -1422,6 +1450,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1461,6 +1490,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.DefaultHTTPClientConfig, HTTPClientConfig: config.DefaultHTTPClientConfig,
@ -1495,6 +1525,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1531,6 +1562,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile, ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -2353,13 +2385,23 @@ func TestEmptyGlobalBlock(t *testing.T) {
require.Equal(t, exp, *c) require.Equal(t, exp, *c)
} }
// ScrapeConfigOptions contains options for creating a scrape config.
type ScrapeConfigOptions struct {
JobName string
ScrapeInterval model.Duration
ScrapeTimeout model.Duration
AlwaysScrapeClassicHistograms bool
ConvertClassicHistToNHCB bool
}
func TestGetScrapeConfigs(t *testing.T) { func TestGetScrapeConfigs(t *testing.T) {
sc := func(jobName string, scrapeInterval, scrapeTimeout model.Duration, convertClassicHistToNHCB bool) *ScrapeConfig { // Helper function to create a scrape config with the given options.
sc := func(opts ScrapeConfigOptions) *ScrapeConfig {
return &ScrapeConfig{ return &ScrapeConfig{
JobName: jobName, JobName: opts.JobName,
HonorTimestamps: true, HonorTimestamps: true,
ScrapeInterval: scrapeInterval, ScrapeInterval: opts.ScrapeInterval,
ScrapeTimeout: scrapeTimeout, ScrapeTimeout: opts.ScrapeTimeout,
ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols, ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
@ -2380,7 +2422,8 @@ func TestGetScrapeConfigs(t *testing.T) {
}, },
}, },
}, },
ConvertClassicHistogramsToNHCB: boolPtr(convertClassicHistToNHCB), AlwaysScrapeClassicHistograms: boolPtr(opts.AlwaysScrapeClassicHistograms),
ConvertClassicHistogramsToNHCB: boolPtr(opts.ConvertClassicHistToNHCB),
} }
} }
@ -2393,20 +2436,20 @@ func TestGetScrapeConfigs(t *testing.T) {
{ {
name: "An included config file should be a valid global config.", name: "An included config file should be a valid global config.",
configFile: "testdata/scrape_config_files.good.yml", configFile: "testdata/scrape_config_files.good.yml",
expectedResult: []*ScrapeConfig{sc("prometheus", model.Duration(60*time.Second), model.Duration(10*time.Second), false)}, expectedResult: []*ScrapeConfig{sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: false})},
}, },
{ {
name: "A global config that only include a scrape config file.", name: "A global config that only include a scrape config file.",
configFile: "testdata/scrape_config_files_only.good.yml", configFile: "testdata/scrape_config_files_only.good.yml",
expectedResult: []*ScrapeConfig{sc("prometheus", model.Duration(60*time.Second), model.Duration(10*time.Second), false)}, expectedResult: []*ScrapeConfig{sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: false})},
}, },
{ {
name: "A global config that combine scrape config files and scrape configs.", name: "A global config that combine scrape config files and scrape configs.",
configFile: "testdata/scrape_config_files_combined.good.yml", configFile: "testdata/scrape_config_files_combined.good.yml",
expectedResult: []*ScrapeConfig{ expectedResult: []*ScrapeConfig{
sc("node", model.Duration(60*time.Second), model.Duration(10*time.Second), false), sc(ScrapeConfigOptions{JobName: "node", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: false}),
sc("prometheus", model.Duration(60*time.Second), model.Duration(10*time.Second), false), sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: false}),
sc("alertmanager", model.Duration(60*time.Second), model.Duration(10*time.Second), false), sc(ScrapeConfigOptions{JobName: "alertmanager", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: false}),
}, },
}, },
{ {
@ -2422,6 +2465,7 @@ func TestGetScrapeConfigs(t *testing.T) {
ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols, ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -2458,6 +2502,7 @@ func TestGetScrapeConfigs(t *testing.T) {
ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols, ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols,
MetricNameValidationScheme: UTF8ValidationConfig, MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8, MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false), ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.HTTPClientConfig{ HTTPClientConfig: config.HTTPClientConfig{
@ -2509,17 +2554,37 @@ func TestGetScrapeConfigs(t *testing.T) {
{ {
name: "A global config that enables convert classic histograms to nhcb.", name: "A global config that enables convert classic histograms to nhcb.",
configFile: "testdata/global_convert_classic_hist_to_nhcb.good.yml", configFile: "testdata/global_convert_classic_hist_to_nhcb.good.yml",
expectedResult: []*ScrapeConfig{sc("prometheus", model.Duration(60*time.Second), model.Duration(10*time.Second), true)}, expectedResult: []*ScrapeConfig{sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: true})},
}, },
{ {
name: "A global config that enables convert classic histograms to nhcb and scrape config that disables the conversion", name: "A global config that enables convert classic histograms to nhcb and scrape config that disables the conversion",
configFile: "testdata/local_disable_convert_classic_hist_to_nhcb.good.yml", configFile: "testdata/local_disable_convert_classic_hist_to_nhcb.good.yml",
expectedResult: []*ScrapeConfig{sc("prometheus", model.Duration(60*time.Second), model.Duration(10*time.Second), false)}, expectedResult: []*ScrapeConfig{sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: false})},
}, },
{ {
name: "A global config that disables convert classic histograms to nhcb and scrape config that enables the conversion", name: "A global config that disables convert classic histograms to nhcb and scrape config that enables the conversion",
configFile: "testdata/local_convert_classic_hist_to_nhcb.good.yml", configFile: "testdata/local_convert_classic_hist_to_nhcb.good.yml",
expectedResult: []*ScrapeConfig{sc("prometheus", model.Duration(60*time.Second), model.Duration(10*time.Second), true)}, expectedResult: []*ScrapeConfig{sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: true})},
},
{
name: "A global config that enables always scrape classic histograms",
configFile: "testdata/global_enable_always_scrape_classic_hist.good.yml",
expectedResult: []*ScrapeConfig{sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: true, ConvertClassicHistToNHCB: false})},
},
{
name: "A global config that disables always scrape classic histograms",
configFile: "testdata/global_disable_always_scrape_classic_hist.good.yml",
expectedResult: []*ScrapeConfig{sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: false})},
},
{
name: "A global config that disables always scrape classic histograms and scrape config that enables it",
configFile: "testdata/local_enable_always_scrape_classic_hist.good.yml",
expectedResult: []*ScrapeConfig{sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: true, ConvertClassicHistToNHCB: false})},
},
{
name: "A global config that enables always scrape classic histograms and scrape config that disables it",
configFile: "testdata/local_disable_always_scrape_classic_hist.good.yml",
expectedResult: []*ScrapeConfig{sc(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: false})},
}, },
} }

View File

@ -0,0 +1,6 @@
global:
always_scrape_classic_histograms: false
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:8080']

View File

@ -0,0 +1,6 @@
global:
always_scrape_classic_histograms: true
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:8080']

View File

@ -0,0 +1,7 @@
global:
always_scrape_classic_histograms: true
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:8080']
always_scrape_classic_histograms: false

View File

@ -0,0 +1,7 @@
global:
always_scrape_classic_histograms: false
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:8080']
always_scrape_classic_histograms: true

View File

@ -144,6 +144,11 @@ global:
# histograms with custom buckets. # histograms with custom buckets.
[ convert_classic_histograms_to_nhcb <bool> | default = false] [ convert_classic_histograms_to_nhcb <bool> | default = false]
# Specifies whether to scrape a classic histogram, even if it is also exposed as a native
# histogram (has no effect without --enable-feature=native-histograms).
[ always_scrape_classic_histograms: <boolean> | default = false ]
runtime: runtime:
# Configure the Go garbage collector GOGC parameter # Configure the Go garbage collector GOGC parameter
# See: https://tip.golang.org/doc/gc-guide#GOGC # See: https://tip.golang.org/doc/gc-guide#GOGC
@ -244,7 +249,8 @@ job_name: <job_name>
# Whether to scrape a classic histogram, even if it is also exposed as a native # Whether to scrape a classic histogram, even if it is also exposed as a native
# histogram (has no effect without --enable-feature=native-histograms). # histogram (has no effect without --enable-feature=native-histograms).
[ always_scrape_classic_histograms: <boolean> | default = false ] [ always_scrape_classic_histograms: <boolean> |
default = <global.always_scrape_classic_hisotgrams> ]
# The HTTP resource path on which to fetch metrics from targets. # The HTTP resource path on which to fetch metrics from targets.
[ metrics_path: <path> | default = /metrics ] [ metrics_path: <path> | default = /metrics ]

View File

@ -366,7 +366,7 @@ func (sp *scrapePool) restartLoops(reuseCache bool) {
trackTimestampsStaleness = sp.config.TrackTimestampsStaleness trackTimestampsStaleness = sp.config.TrackTimestampsStaleness
mrc = sp.config.MetricRelabelConfigs mrc = sp.config.MetricRelabelConfigs
fallbackScrapeProtocol = sp.config.ScrapeFallbackProtocol.HeaderMediaType() fallbackScrapeProtocol = sp.config.ScrapeFallbackProtocol.HeaderMediaType()
alwaysScrapeClassicHist = sp.config.AlwaysScrapeClassicHistograms alwaysScrapeClassicHist = sp.config.AlwaysScrapeClassicHistogramsEnabled()
convertClassicHistToNHCB = sp.config.ConvertClassicHistogramsToNHCBEnabled() convertClassicHistToNHCB = sp.config.ConvertClassicHistogramsToNHCBEnabled()
) )
@ -522,7 +522,7 @@ func (sp *scrapePool) sync(targets []*Target) {
trackTimestampsStaleness = sp.config.TrackTimestampsStaleness trackTimestampsStaleness = sp.config.TrackTimestampsStaleness
mrc = sp.config.MetricRelabelConfigs mrc = sp.config.MetricRelabelConfigs
fallbackScrapeProtocol = sp.config.ScrapeFallbackProtocol.HeaderMediaType() fallbackScrapeProtocol = sp.config.ScrapeFallbackProtocol.HeaderMediaType()
alwaysScrapeClassicHist = sp.config.AlwaysScrapeClassicHistograms alwaysScrapeClassicHist = sp.config.AlwaysScrapeClassicHistogramsEnabled()
convertClassicHistToNHCB = sp.config.ConvertClassicHistogramsToNHCBEnabled() convertClassicHistToNHCB = sp.config.ConvertClassicHistogramsToNHCBEnabled()
) )

View File

@ -4635,26 +4635,26 @@ metric: <
fals := false fals := false
for metricsTextName, metricsText := range metricsTexts { for metricsTextName, metricsText := range metricsTexts {
for name, tc := range map[string]struct { for name, tc := range map[string]struct {
alwaysScrapeClassicHistograms bool alwaysScrapeClassicHistograms *bool
convertClassicHistToNHCB *bool convertClassicHistToNHCB *bool
}{ }{
"convert with scrape": { "convert with scrape": {
alwaysScrapeClassicHistograms: true, alwaysScrapeClassicHistograms: &tru,
convertClassicHistToNHCB: &tru, convertClassicHistToNHCB: &tru,
}, },
"convert without scrape": { "convert without scrape": {
alwaysScrapeClassicHistograms: false, alwaysScrapeClassicHistograms: &fals,
convertClassicHistToNHCB: &tru, convertClassicHistToNHCB: &tru,
}, },
"scrape without convert": { "scrape without convert": {
alwaysScrapeClassicHistograms: true, alwaysScrapeClassicHistograms: &tru,
convertClassicHistToNHCB: &fals, convertClassicHistToNHCB: &fals,
}, },
"scrape with nil convert": { "scrape with nil convert": {
alwaysScrapeClassicHistograms: true, alwaysScrapeClassicHistograms: &tru,
}, },
"neither scrape nor convert": { "neither scrape nor convert": {
alwaysScrapeClassicHistograms: false, alwaysScrapeClassicHistograms: &fals,
convertClassicHistToNHCB: &fals, convertClassicHistToNHCB: &fals,
}, },
} { } {
@ -4664,7 +4664,7 @@ metric: <
expectedNativeHistCount = 1 expectedNativeHistCount = 1
expectCustomBuckets = false expectCustomBuckets = false
expectedClassicHistCount = 0 expectedClassicHistCount = 0
if metricsText.hasClassic && tc.alwaysScrapeClassicHistograms { if metricsText.hasClassic && tc.alwaysScrapeClassicHistograms != nil && *tc.alwaysScrapeClassicHistograms {
expectedClassicHistCount = 1 expectedClassicHistCount = 1
} }
} else if metricsText.hasClassic { } else if metricsText.hasClassic {
@ -4672,11 +4672,11 @@ metric: <
case tc.convertClassicHistToNHCB == nil || !*tc.convertClassicHistToNHCB: case tc.convertClassicHistToNHCB == nil || !*tc.convertClassicHistToNHCB:
expectedClassicHistCount = 1 expectedClassicHistCount = 1
expectedNativeHistCount = 0 expectedNativeHistCount = 0
case tc.alwaysScrapeClassicHistograms && *tc.convertClassicHistToNHCB: case tc.alwaysScrapeClassicHistograms != nil && *tc.alwaysScrapeClassicHistograms && *tc.convertClassicHistToNHCB:
expectedClassicHistCount = 1 expectedClassicHistCount = 1
expectedNativeHistCount = 1 expectedNativeHistCount = 1
expectCustomBuckets = true expectCustomBuckets = true
case !tc.alwaysScrapeClassicHistograms && *tc.convertClassicHistToNHCB: case (tc.alwaysScrapeClassicHistograms == nil || !*tc.alwaysScrapeClassicHistograms) && *tc.convertClassicHistToNHCB:
expectedClassicHistCount = 0 expectedClassicHistCount = 0
expectedNativeHistCount = 1 expectedNativeHistCount = 1
expectCustomBuckets = true expectCustomBuckets = true