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.
ScrapeProtocols: DefaultScrapeProtocols,
ConvertClassicHistogramsToNHCB: false,
AlwaysScrapeClassicHistograms: false,
}
DefaultRuntimeConfig = RuntimeConfig{
@ -178,8 +179,7 @@ var (
// DefaultScrapeConfig is the default scrape configuration.
DefaultScrapeConfig = ScrapeConfig{
// ScrapeTimeout, ScrapeInterval and ScrapeProtocols default to the configured globals.
AlwaysScrapeClassicHistograms: false,
// ScrapeTimeout, ScrapeInterval, ScrapeProtocols, AlwaysScrapeClassicHistograms, and ConvertClassicHistogramsToNHCB default to the configured globals.
MetricsPath: "/metrics",
Scheme: "http",
HonorLabels: false,
@ -489,6 +489,8 @@ type GlobalConfig struct {
MetricNameEscapingScheme string `yaml:"metric_name_escaping_scheme,omitempty"`
// Whether to convert all scraped classic histograms into native histograms with custom buckets.
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.
@ -645,7 +647,8 @@ func (c *GlobalConfig) isZero() bool {
c.QueryLogFile == "" &&
c.ScrapeFailureLogFile == "" &&
c.ScrapeProtocols == nil &&
!c.ConvertClassicHistogramsToNHCB
!c.ConvertClassicHistogramsToNHCB &&
!c.AlwaysScrapeClassicHistograms
}
// RuntimeConfig configures the values for the process behavior.
@ -690,7 +693,7 @@ type ScrapeConfig struct {
// OpenMetricsText1.0.0, PrometheusText1.0.0, PrometheusText0.0.4.
ScrapeFallbackProtocol ScrapeProtocol `yaml:"fallback_scrape_protocol,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"`
AlwaysScrapeClassicHistograms *bool `yaml:"always_scrape_classic_histograms,omitempty"`
// Whether to convert all scraped classic histograms into a native histogram with custom buckets.
ConvertClassicHistogramsToNHCB *bool `yaml:"convert_classic_histograms_to_nhcb,omitempty"`
// File to which scrape failures are logged.
@ -904,6 +907,11 @@ func (c *ScrapeConfig) Validate(globalConfig GlobalConfig) error {
c.ConvertClassicHistogramsToNHCB = &global
}
if c.AlwaysScrapeClassicHistograms == nil {
global := globalConfig.AlwaysScrapeClassicHistograms
c.AlwaysScrapeClassicHistograms = &global
}
return nil
}
@ -931,6 +939,11 @@ func (c *ScrapeConfig) ConvertClassicHistogramsToNHCBEnabled() bool {
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.
type StorageConfig struct {
TSDBConfig *TSDBConfig `yaml:"tsdb,omitempty"`

View File

@ -102,6 +102,7 @@ var expectedConf = &Config{
LabelNameLengthLimit: globLabelNameLengthLimit,
LabelValueLengthLimit: globLabelValueLengthLimit,
ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols,
AlwaysScrapeClassicHistograms: false,
ConvertClassicHistogramsToNHCB: false,
},
@ -223,6 +224,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: "testdata/fail_prom.log",
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -339,6 +341,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.HTTPClientConfig{
@ -440,6 +443,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -499,6 +503,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: "/metrics",
@ -536,6 +541,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -579,6 +585,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -622,6 +629,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -655,6 +663,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -696,6 +705,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -734,6 +744,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -779,6 +790,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -814,6 +826,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -852,6 +865,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -883,6 +897,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -917,6 +932,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: "/federate",
@ -951,6 +967,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -985,6 +1002,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1016,6 +1034,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1055,6 +1074,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1093,6 +1113,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1128,6 +1149,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1162,6 +1184,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1200,6 +1223,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1241,6 +1265,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1301,6 +1326,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1332,6 +1358,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.DefaultHTTPClientConfig,
@ -1374,6 +1401,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.DefaultHTTPClientConfig,
@ -1422,6 +1450,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1461,6 +1490,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.DefaultHTTPClientConfig,
@ -1495,6 +1525,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -1531,6 +1562,7 @@ var expectedConf = &Config{
ScrapeFailureLogFile: globScrapeFailureLogFile,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -2353,13 +2385,23 @@ func TestEmptyGlobalBlock(t *testing.T) {
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) {
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{
JobName: jobName,
JobName: opts.JobName,
HonorTimestamps: true,
ScrapeInterval: scrapeInterval,
ScrapeTimeout: scrapeTimeout,
ScrapeInterval: opts.ScrapeInterval,
ScrapeTimeout: opts.ScrapeTimeout,
ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols,
MetricNameValidationScheme: UTF8ValidationConfig,
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.",
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.",
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.",
configFile: "testdata/scrape_config_files_combined.good.yml",
expectedResult: []*ScrapeConfig{
sc("node", model.Duration(60*time.Second), model.Duration(10*time.Second), false),
sc("prometheus", model.Duration(60*time.Second), model.Duration(10*time.Second), false),
sc("alertmanager", 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(ScrapeConfigOptions{JobName: "prometheus", ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), AlwaysScrapeClassicHistograms: false, ConvertClassicHistToNHCB: 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,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
MetricsPath: DefaultScrapeConfig.MetricsPath,
@ -2458,6 +2502,7 @@ func TestGetScrapeConfigs(t *testing.T) {
ScrapeProtocols: DefaultGlobalConfig.ScrapeProtocols,
MetricNameValidationScheme: UTF8ValidationConfig,
MetricNameEscapingScheme: model.AllowUTF8,
AlwaysScrapeClassicHistograms: boolPtr(false),
ConvertClassicHistogramsToNHCB: boolPtr(false),
HTTPClientConfig: config.HTTPClientConfig{
@ -2509,17 +2554,37 @@ func TestGetScrapeConfigs(t *testing.T) {
{
name: "A global config that enables convert classic histograms to nhcb.",
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",
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",
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.
[ 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:
# Configure the Go garbage collector GOGC parameter
# 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
# 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.
[ metrics_path: <path> | default = /metrics ]

View File

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

View File

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