From aeedfe2fe22961a9bb868704c572949a669af125 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 12 Oct 2021 16:23:42 +0300 Subject: [PATCH] app/vmagent: expose -promscrape.config contents at /config page as Prometheus does See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1695 --- app/vmagent/main.go | 8 ++++++++ docs/CHANGELOG.md | 1 + lib/promscrape/config.go | 6 +++--- lib/promscrape/scraper.go | 18 ++++++++++++++++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/app/vmagent/main.go b/app/vmagent/main.go index 7b2e02acef..f86e3b85e5 100644 --- a/app/vmagent/main.go +++ b/app/vmagent/main.go @@ -159,6 +159,7 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool { httpserver.WriteAPIHelp(w, [][2]string{ {"/targets", "discovered targets list"}, {"/api/v1/targets", "advanced information about discovered targets in JSON format"}, + {"/config", "-promscrape.config contents"}, {"/metrics", "available service metrics"}, {"/-/reload", "reload configuration"}, }) @@ -259,6 +260,11 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool { promscrapeTargetsRequests.Inc() promscrape.WriteHumanReadableTargetsStatus(w, r) return true + case "/config": + promscrapeConfigRequests.Inc() + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + promscrape.WriteConfigData(w) + return true case "/api/v1/targets": promscrapeAPIV1TargetsRequests.Inc() w.Header().Set("Content-Type", "application/json; charset=utf-8") @@ -427,6 +433,8 @@ var ( promscrapeTargetsRequests = metrics.NewCounter(`vmagent_http_requests_total{path="/targets"}`) promscrapeAPIV1TargetsRequests = metrics.NewCounter(`vmagent_http_requests_total{path="/api/v1/targets"}`) + promscrapeConfigRequests = metrics.NewCounter(`vmagent_http_requests_total{path="/config"}`) + promscrapeConfigReloadRequests = metrics.NewCounter(`vmagent_http_requests_total{path="/-/reload"}`) ) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8c114af2a3..be4e7eceb4 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,6 +6,7 @@ sort: 15 ## tip +* FEATURE: vmagent: expose `-promscrape.config` contents at `/config` page as Prometheus does. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1695). * FEATURE: add trigonometric functions, which are going to be added in [Prometheus 2.31](https://github.com/prometheus/prometheus/pull/9239): [acosh](https://docs.victoriametrics.com/MetricsQL.html#acosh), [asinh](https://docs.victoriametrics.com/MetricsQL.html#asinh), [atan](https://docs.victoriametrics.com/MetricsQL.html#atan), [atanh](https://docs.victoriametrics.com/MetricsQL.html#atanh), [cosh](https://docs.victoriametrics.com/MetricsQL.html#cosh), [deg](https://docs.victoriametrics.com/MetricsQL.html#deg), [rad](https://docs.victoriametrics.com/MetricsQL.html#rad), [sinh](https://docs.victoriametrics.com/MetricsQL.html#sinh), [tan](https://docs.victoriametrics.com/MetricsQL.html#tan), [tanh](https://docs.victoriametrics.com/MetricsQL.html#tanh). Also add `atan2` binary operator. See [this pull request](https://github.com/prometheus/prometheus/pull/9248). * FEATURE: consistently return the same set of time series from [limitk](https://docs.victoriametrics.com/MetricsQL.html#limitk) function. This improves the usability of periodically refreshed graphs. diff --git a/lib/promscrape/config.go b/lib/promscrape/config.go index 84e2df522f..dbbbeaf24b 100644 --- a/lib/promscrape/config.go +++ b/lib/promscrape/config.go @@ -58,8 +58,8 @@ var ( // Config represents essential parts from Prometheus config defined at https://prometheus.io/docs/prometheus/latest/configuration/configuration/ type Config struct { Global GlobalConfig `yaml:"global,omitempty"` - ScrapeConfigs []ScrapeConfig `yaml:"scrape_configs"` - ScrapeConfigFiles []string `yaml:"scrape_config_files"` + ScrapeConfigs []ScrapeConfig `yaml:"scrape_configs,omitempty"` + ScrapeConfigFiles []string `yaml:"scrape_config_files,omitempty"` // This is set to the directory from where the config has been loaded. baseDir string @@ -121,7 +121,7 @@ type ScrapeConfig struct { MetricsPath string `yaml:"metrics_path,omitempty"` HonorLabels bool `yaml:"honor_labels,omitempty"` HonorTimestamps bool `yaml:"honor_timestamps,omitempty"` - FollowRedirects *bool `yaml:"follow_redirects"` // omitempty isn't set, since the default value for this flag is true. + FollowRedirects *bool `yaml:"follow_redirects,omitempty"` Scheme string `yaml:"scheme,omitempty"` Params map[string][]string `yaml:"params,omitempty"` HTTPClientConfig promauth.HTTPClientConfig `yaml:",inline"` diff --git a/lib/promscrape/scraper.go b/lib/promscrape/scraper.go index fcd781ed9e..02a2c9b0bf 100644 --- a/lib/promscrape/scraper.go +++ b/lib/promscrape/scraper.go @@ -4,6 +4,7 @@ import ( "bytes" "flag" "fmt" + "io" "sync" "sync/atomic" "time" @@ -70,8 +71,22 @@ var ( // PendingScrapeConfigs - zero value means, that // all scrapeConfigs are inited and ready for work. PendingScrapeConfigs int32 + + // configData contains -promscrape.config data + configData atomic.Value ) +// WriteConfigData writes -promscrape.config contents to w +func WriteConfigData(w io.Writer) { + v := configData.Load() + if v == nil { + // Nothing to write to w + return + } + b := v.(*[]byte) + w.Write(*b) +} + func runScraper(configFile string, pushData func(wr *prompbmarshal.WriteRequest), globalStopCh <-chan struct{}) { if configFile == "" { // Nothing to scrape. @@ -89,6 +104,7 @@ func runScraper(configFile string, pushData func(wr *prompbmarshal.WriteRequest) logger.Fatalf("cannot read %q: %s", configFile, err) } data := cfg.marshal() + configData.Store(&data) cfg.mustStart() scs := newScrapeConfigs(pushData) @@ -132,6 +148,7 @@ func runScraper(configFile string, pushData func(wr *prompbmarshal.WriteRequest) cfgNew.mustStart() cfg = cfgNew data = dataNew + configData.Store(&data) case <-tickerCh: cfgNew, err := loadConfig(configFile) if err != nil { @@ -147,6 +164,7 @@ func runScraper(configFile string, pushData func(wr *prompbmarshal.WriteRequest) cfgNew.mustStart() cfg = cfgNew data = dataNew + configData.Store(&data) case <-globalStopCh: cfg.mustStop() logger.Infof("stopping Prometheus scrapers")