From f51bc07d977cce47e293193573d72b317da2d45c Mon Sep 17 00:00:00 2001 From: Roman Khavronenko Date: Wed, 6 Jul 2022 10:47:51 +0200 Subject: [PATCH] vmselect: allow proxying requests to vmalert (#2833) The change allows to proxy requests with prefix `/vmalert` to the vmalert component if `-vmalert.proxyURL` is set. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2825 and https://github.com/VictoriaMetrics/VictoriaMetrics/pull/2831 Signed-off-by: hagen1778 --- README.md | 16 +++++++++++- app/vmselect/main.go | 46 +++++++++++++++++++++++---------- docs/CHANGELOG.md | 1 + docs/Cluster-VictoriaMetrics.md | 16 +++++++++++- 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 10ac50464a..49cfe6c22c 100644 --- a/README.md +++ b/README.md @@ -252,6 +252,9 @@ See [trobuleshooting docs](https://docs.victoriametrics.com/Troubleshooting.html Note that the `delete_series` handler should be used only in exceptional cases such as deletion of accidentally ingested incorrect time series. It shouldn't be used on a regular basis, since it carries non-zero overhead. +- URL for accessing [vmalert's](https://docs.victoriametrics.com/vmalert.html) UI: `http://:8481/select//prometheus/vmalert/home`. + This URL works only when `-vmalert.proxyURL` flag is set. See more about vmalert [here](#vmalert). + - `vmstorage` nodes provide the following HTTP endpoints on `8482` port: - `/internal/force_merge` - initiate [forced compactions](https://docs.victoriametrics.com/#forced-merge) on the given `vmstorage` node. - `/snapshot/create` - create [instant snapshot](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282), @@ -464,6 +467,17 @@ curl http://0.0.0.0:8480/debug/pprof/heap > mem.pprof +## vmalert + +vmselect is capable of proxying requests to [vmalert](https://docs.victoriametrics.com/vmalert.html) +when `-vmalert.proxyURL` flag is set. Use this feature for the following cases: +* for proxying requests from [Grafana Alerting UI](https://grafana.com/docs/grafana/latest/alerting/); +* for accessing vmalert's UI through vmselect's Web interface. + +For accessing vmalert's UI through vmselect configure `-vmalert.proxyURL` flag and visit +`http://:8481/select//prometheus/vmalert/home` link. + + ## Community and contributions We are open to third-party pull requests provided they follow the [KISS design principle](https://en.wikipedia.org/wiki/KISS_principle): @@ -817,7 +831,7 @@ Below is the output for `/path/to/vmselect -help`: -version Show VictoriaMetrics version -vmalert.proxyURL string - Optional URL for proxying alerting API requests from Grafana. For example, if -vmalert.proxyURL is set to http://vmalert:8880 , then requests to /api/v1/rules are proxied to http://vmalert:8880/api/v1/rules + Optional URL for proxying requests to vmalert. For example, if -vmalert.proxyURL=http://vmalert:8880 , then alerting API requests such as /api/v1/rules from Grafana will be proxied to http://vmalert:8880/api/v1/rules -vmstorageDialTimeout duration Timeout for establishing RPC connections from vmselect to vmstorage (default 5s) ``` diff --git a/app/vmselect/main.go b/app/vmselect/main.go index d08ae988a0..c5da940e98 100644 --- a/app/vmselect/main.go +++ b/app/vmselect/main.go @@ -44,7 +44,7 @@ var ( "equal to -dedup.minScrapeInterval > 0. See https://docs.victoriametrics.com/#deduplication for details") resetCacheAuthKey = flag.String("search.resetCacheAuthKey", "", "Optional authKey for resetting rollup cache via /internal/resetRollupResultCache call") logSlowQueryDuration = flag.Duration("search.logSlowQueryDuration", 5*time.Second, "Log queries with execution time exceeding this value. Zero disables slow query logging") - vmalertProxyURL = flag.String("vmalert.proxyURL", "", "Optional URL for proxying alerting API requests from Grafana. For example, if -vmalert.proxyURL is set to http://vmalert:8880 , then requests to /api/v1/rules are proxied to http://vmalert:8880/api/v1/rules") + vmalertProxyURL = flag.String("vmalert.proxyURL", "", "Optional URL for proxying requests to vmalert. For example, if -vmalert.proxyURL=http://vmalert:8880 , then alerting API requests such as /api/v1/rules from Grafana will be proxied to http://vmalert:8880/api/v1/rules") storageNodes = flagutil.NewArray("storageNode", "Comma-separated addresses of vmstorage nodes; usage: -storageNode=vmstorage-host1,...,vmstorage-hostN") ) @@ -320,6 +320,18 @@ func selectHandler(qt *querytracer.Tracer, startTime time.Time, w http.ResponseW return true } + if strings.HasPrefix(p.Suffix, "prometheus/vmalert") { + vmalertRequests.Inc() + if len(*vmalertProxyURL) == 0 { + w.WriteHeader(http.StatusBadRequest) + w.Header().Set("Content-Type", "application/json") + fmt.Fprintf(w, "%s", `{"status":"error","msg":"for accessing vmalert flag "-vmalert.proxyURL" must be configured"}`) + return true + } + proxyVMAlertRequests(w, r, p.Suffix) + return true + } + switch p.Suffix { case "prometheus/api/v1/query": queryRequests.Inc() @@ -506,14 +518,24 @@ func selectHandler(qt *querytracer.Tracer, startTime time.Time, w http.ResponseW } return true case "prometheus/api/v1/rules", "prometheus/rules": - // Return dumb placeholder for https://prometheus.io/docs/prometheus/latest/querying/api/#rules rulesRequests.Inc() - mayProxyVMAlertRequests(w, r, p.Suffix, `{"status":"success","data":{"groups":[]}}`) + if len(*vmalertProxyURL) > 0 { + proxyVMAlertRequests(w, r, p.Suffix) + return true + } + // Return dumb placeholder for https://prometheus.io/docs/prometheus/latest/querying/api/#rules + w.Header().Set("Content-Type", "application/json") + fmt.Fprint(w, `{"status":"success","data":{"groups":[]}}`) return true case "prometheus/api/v1/alerts", "prometheus/alerts": - // Return dumb placeholder for https://prometheus.io/docs/prometheus/latest/querying/api/#alerts alertsRequests.Inc() - mayProxyVMAlertRequests(w, r, p.Suffix, `{"status":"success","data":{"alerts":[]}}`) + if len(*vmalertProxyURL) > 0 { + proxyVMAlertRequests(w, r, p.Suffix) + return true + } + // Return dumb placeholder for https://prometheus.io/docs/prometheus/latest/querying/api/#alerts + w.Header().Set("Content-Type", "application/json") + fmt.Fprint(w, `{"status":"success","data":{"alerts":[]}}`) return true case "prometheus/api/v1/metadata": // Return dumb placeholder for https://prometheus.io/docs/prometheus/latest/querying/api/#querying-metric-metadata @@ -660,8 +682,10 @@ var ( graphiteFunctionsRequests = metrics.NewCounter(`vm_http_requests_total{path="/select/{}/graphite/functions"}`) - rulesRequests = metrics.NewCounter(`vm_http_requests_total{path="/select/{}/prometheus/api/v1/rules"}`) - alertsRequests = metrics.NewCounter(`vm_http_requests_total{path="/select/{}/prometheus/api/v1/alerts"}`) + vmalertRequests = metrics.NewCounter(`vm_http_requests_total{path="/select/{}/prometheus/vmalert"}`) + rulesRequests = metrics.NewCounter(`vm_http_requests_total{path="/select/{}/prometheus/api/v1/rules"}`) + alertsRequests = metrics.NewCounter(`vm_http_requests_total{path="/select/{}/prometheus/api/v1/alerts"}`) + metadataRequests = metrics.NewCounter(`vm_http_requests_total{path="/select/{}/prometheus/api/v1/metadata"}`) buildInfoRequests = metrics.NewCounter(`vm_http_requests_total{path="/select/{}/prometheus/api/v1/buildinfo"}`) queryExemplarsRequests = metrics.NewCounter(`vm_http_requests_total{path="/select/{}/prometheus/api/v1/query_exemplars"}`) @@ -679,13 +703,7 @@ See the docs at https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html . flagutil.Usage(s) } -func mayProxyVMAlertRequests(w http.ResponseWriter, r *http.Request, path, stubResponse string) { - if len(*vmalertProxyURL) == 0 { - // Return dumb placeholder for https://prometheus.io/docs/prometheus/latest/querying/api/#rules - w.Header().Set("Content-Type", "application/json") - fmt.Fprintf(w, "%s", stubResponse) - return - } +func proxyVMAlertRequests(w http.ResponseWriter, r *http.Request, path string) { defer func() { err := recover() if err == nil || err == http.ErrAbortHandler { diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2148d77ba8..90bcbcfd9f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -18,6 +18,7 @@ The following tip changes can be tested by building VictoriaMetrics components f **Update notes:** this release introduces backwards-incompatible changes to `vm_partial_results_total` metric by changing its labels to be consistent with `vm_requests_total` metric. If you use alerting rules or Grafana dashboards, which rely on this metric, then they must be updated. The official dashboards for VictoriaMetrics don't use this metric. +* FEATURE: [vmselect](https://docs.victoriametrics.com/#vmselect): allow accessing [vmalert's](https://docs.victoriametrics.com/vmalert.html) UI when `-vmalert.proxyURL` command-line flag is set. See more [here](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#vmalert) * FEATURE: add `-search.setLookbackToStep` command-line flag, which enables InfluxDB-like gap filling during querying. See [these docs](https://docs.victoriametrics.com/guides/migrate-from-influx.html) for details. * FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add an UI for [query tracing](https://docs.victoriametrics.com/#query-tracing). It can be enabled by clicking `enable query tracing` checkbox and re-running the query. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2703). * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add `-remoteWrite.headers` command-line option for specifying optional HTTP headers to send to the configured `-remoteWrite.url`. For example, `-remoteWrite.headers='Foo:Bar^^Baz:x'` would send `Foo: Bar` and `Baz: x` HTTP headers with every request to `-remoteWrite.url`. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2805). diff --git a/docs/Cluster-VictoriaMetrics.md b/docs/Cluster-VictoriaMetrics.md index 03d7dfa7f8..19841de855 100644 --- a/docs/Cluster-VictoriaMetrics.md +++ b/docs/Cluster-VictoriaMetrics.md @@ -256,6 +256,9 @@ See [trobuleshooting docs](https://docs.victoriametrics.com/Troubleshooting.html Note that the `delete_series` handler should be used only in exceptional cases such as deletion of accidentally ingested incorrect time series. It shouldn't be used on a regular basis, since it carries non-zero overhead. +- URL for accessing [vmalert's](https://docs.victoriametrics.com/vmalert.html) UI: `http://:8481/select//prometheus/vmalert/home`. + This URL works only when `-vmalert.proxyURL` flag is set. See more about vmalert [here](#vmalert). + - `vmstorage` nodes provide the following HTTP endpoints on `8482` port: - `/internal/force_merge` - initiate [forced compactions](https://docs.victoriametrics.com/#forced-merge) on the given `vmstorage` node. - `/snapshot/create` - create [instant snapshot](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282), @@ -468,6 +471,17 @@ curl http://0.0.0.0:8480/debug/pprof/heap > mem.pprof +## vmalert + +vmselect is capable of proxying requests to [vmalert](https://docs.victoriametrics.com/vmalert.html) +when `-vmalert.proxyURL` flag is set. Use this feature for the following cases: +* for proxying requests from [Grafana Alerting UI](https://grafana.com/docs/grafana/latest/alerting/); +* for accessing vmalert's UI through vmselect's Web interface. + +For accessing vmalert's UI through vmselect configure `-vmalert.proxyURL` flag and visit +`http://:8481/select//prometheus/vmalert/home` link. + + ## Community and contributions We are open to third-party pull requests provided they follow the [KISS design principle](https://en.wikipedia.org/wiki/KISS_principle): @@ -821,7 +835,7 @@ Below is the output for `/path/to/vmselect -help`: -version Show VictoriaMetrics version -vmalert.proxyURL string - Optional URL for proxying alerting API requests from Grafana. For example, if -vmalert.proxyURL is set to http://vmalert:8880 , then requests to /api/v1/rules are proxied to http://vmalert:8880/api/v1/rules + Optional URL for proxying requests to vmalert. For example, if -vmalert.proxyURL=http://vmalert:8880 , then alerting API requests such as /api/v1/rules from Grafana will be proxied to http://vmalert:8880/api/v1/rules -vmstorageDialTimeout duration Timeout for establishing RPC connections from vmselect to vmstorage (default 5s) ```