diff --git a/config/config.go b/config/config.go index 09c79b3501..1ef638bb88 100644 --- a/config/config.go +++ b/config/config.go @@ -169,6 +169,7 @@ var ( // changes to DefaultNativeHistogramScrapeProtocols. ScrapeProtocols: DefaultScrapeProtocols, ConvertClassicHistogramsToNHCB: false, + AlwaysScrapeClassicHistograms: false, } DefaultRuntimeConfig = RuntimeConfig{ @@ -178,14 +179,13 @@ var ( // DefaultScrapeConfig is the default scrape configuration. DefaultScrapeConfig = ScrapeConfig{ - // ScrapeTimeout, ScrapeInterval and ScrapeProtocols default to the configured globals. - AlwaysScrapeClassicHistograms: false, - MetricsPath: "/metrics", - Scheme: "http", - HonorLabels: false, - HonorTimestamps: true, - HTTPClientConfig: config.DefaultHTTPClientConfig, - EnableCompression: true, + // ScrapeTimeout, ScrapeInterval, ScrapeProtocols, AlwaysScrapeClassicHistograms, and ConvertClassicHistogramsToNHCB default to the configured globals. + MetricsPath: "/metrics", + Scheme: "http", + HonorLabels: false, + HonorTimestamps: true, + HTTPClientConfig: config.DefaultHTTPClientConfig, + EnableCompression: true, } // DefaultAlertmanagerConfig is the default alertmanager configuration. @@ -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"` diff --git a/config/config_test.go b/config/config_test.go index 6d59c7220d..379c171fd0 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -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})}, }, } diff --git a/config/testdata/global_disable_always_scrape_classic_hist.good.yml b/config/testdata/global_disable_always_scrape_classic_hist.good.yml new file mode 100644 index 0000000000..de28f1357a --- /dev/null +++ b/config/testdata/global_disable_always_scrape_classic_hist.good.yml @@ -0,0 +1,6 @@ +global: + always_scrape_classic_histograms: false +scrape_configs: + - job_name: prometheus + static_configs: + - targets: ['localhost:8080'] diff --git a/config/testdata/global_enable_always_scrape_classic_hist.good.yml b/config/testdata/global_enable_always_scrape_classic_hist.good.yml new file mode 100644 index 0000000000..d42cf69cb6 --- /dev/null +++ b/config/testdata/global_enable_always_scrape_classic_hist.good.yml @@ -0,0 +1,6 @@ +global: + always_scrape_classic_histograms: true +scrape_configs: + - job_name: prometheus + static_configs: + - targets: ['localhost:8080'] diff --git a/config/testdata/local_disable_always_scrape_classic_hist.good.yml b/config/testdata/local_disable_always_scrape_classic_hist.good.yml new file mode 100644 index 0000000000..9e668340dc --- /dev/null +++ b/config/testdata/local_disable_always_scrape_classic_hist.good.yml @@ -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 diff --git a/config/testdata/local_enable_always_scrape_classic_hist.good.yml b/config/testdata/local_enable_always_scrape_classic_hist.good.yml new file mode 100644 index 0000000000..165be07754 --- /dev/null +++ b/config/testdata/local_enable_always_scrape_classic_hist.good.yml @@ -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 diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index aa92b40fd8..e701356506 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -144,6 +144,11 @@ global: # histograms with custom buckets. [ convert_classic_histograms_to_nhcb | 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: | 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: # 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: | default = false ] +[ always_scrape_classic_histograms: | +default = ] # The HTTP resource path on which to fetch metrics from targets. [ metrics_path: | default = /metrics ] diff --git a/scrape/scrape.go b/scrape/scrape.go index 704726bf41..1c4b5c565d 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -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() ) diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index 3ddb767356..8cf84a4aec 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -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