Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions app/vlselect/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"flag"
"fmt"
"net/http"
nethttputil "net/http/httputil"
"net/url"
"strings"
"time"

Expand All @@ -28,6 +30,8 @@ var (

disableSelect = flag.Bool("select.disable", false, "Whether to disable /select/* HTTP endpoints")
disableInternal = flag.Bool("internalselect.disable", false, "Whether to disable /internal/select/* HTTP endpoints")

vmalertProxyURL = flag.String("vmalert.proxyURL", "", "Optional URL for proxying requests to vmalert")
)

func getDefaultMaxConcurrentRequests() int {
Expand All @@ -47,6 +51,7 @@ func getDefaultMaxConcurrentRequests() int {
// Init initializes vlselect
func Init() {
concurrencyLimitCh = make(chan struct{}, *maxConcurrentRequests)
initVMAlertProxy()
}

// Stop stops vlselect
Expand Down Expand Up @@ -267,6 +272,36 @@ func processSelectRequest(ctx context.Context, w http.ResponseWriter, r *http.Re
logsql.ProcessStreamsRequest(ctx, w, r)
logsqlStreamsDuration.UpdateDuration(startTime)
return true
case "/select/api/v1/notifiers":
notifiersRequests.Inc()
if len(*vmalertProxyURL) > 0 {
r.URL.Path = path[len("/select"):]
proxyVMAlertRequests(w, r)
return true
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"status":"success","data":{"notifiers":[]}}`)
return true
case "/select/api/v1/alerts":
alertsRequests.Inc()
if len(*vmalertProxyURL) > 0 {
r.URL.Path = path[len("/select"):]
proxyVMAlertRequests(w, r)
return true
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"status":"success","data":{"alerts":[]}}`)
return true
case "/select/api/v1/rules":
rulesRequests.Inc()
if len(*vmalertProxyURL) > 0 {
r.URL.Path = path[len("/select"):]
proxyVMAlertRequests(w, r)
return true
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"status":"success","data":{"rules":[]}}`)
return true
default:
return false
}
Expand All @@ -285,6 +320,39 @@ func getMaxQueryDuration(r *http.Request) time.Duration {
return d
}

func proxyVMAlertRequests(w http.ResponseWriter, r *http.Request) {
defer func() {
err := recover()
if err == nil || err == http.ErrAbortHandler {
// Suppress http.ErrAbortHandler panic.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1353
return
}
// Forward other panics to the caller.
panic(err)
}()
r.Host = vmalertProxyHost
vmalertProxy.ServeHTTP(w, r)
}

// initVMAlertProxy must be called after flag.Parse(), since it uses command-line flags.
func initVMAlertProxy() {
if len(*vmalertProxyURL) == 0 {
return
}
proxyURL, err := url.Parse(*vmalertProxyURL)
if err != nil {
logger.Fatalf("cannot parse -vmalert.proxyURL=%q: %s", *vmalertProxyURL, err)
}
vmalertProxyHost = proxyURL.Host
vmalertProxy = nethttputil.NewSingleHostReverseProxy(proxyURL)
}

var (
vmalertProxyHost string
vmalertProxy *nethttputil.ReverseProxy
)

var (
logsqlFacetsRequests = metrics.NewCounter(`vl_http_requests_total{path="/select/logsql/facets"}`)
logsqlFacetsDuration = metrics.NewSummary(`vl_http_request_duration_seconds{path="/select/logsql/facets"}`)
Expand Down Expand Up @@ -321,4 +389,8 @@ var (

// no need to track duration for tail requests, as they usually take long time
logsqlTailRequests = metrics.NewCounter(`vl_http_requests_total{path="/select/logsql/tail"}`)

rulesRequests = metrics.NewCounter(`vl_http_requests_total{path="/select/api/v1/rules"}`)
alertsRequests = metrics.NewCounter(`vl_http_requests_total{path="/select/api/v1/alerts"}`)
notifiersRequests = metrics.NewCounter(`vl_http_requests_total{path="/select/api/v1/notifiers"}`)
)
2 changes: 2 additions & 0 deletions docs/victorialogs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta

## tip

* FEATURE: proxy requests to `/api/v1/notifiers`, `/api/v1/alerts` and `/api/v1/rules` to VMAlert, when `-vmalert.proxyURL` flag is set. See [#8272](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/8272).

## [v1.24.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.24.0-victorialogs)

Released at 2025-06-20
Expand Down
12 changes: 12 additions & 0 deletions docs/victorialogs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,16 @@ rsync -avh --progress --delete <username>@<host>:<path-to-victorialogs-backup> <
It is also possible to use **the disk snapshot** in order to perform a backup. This feature could be provided by your operating system,
cloud provider, or third-party tools. Note that the snapshot must be **consistent** to ensure reliable backup.

## vmalert

VictoriaLogs is capable of proxying requests to [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/)
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 vmalerts UI through VictoriaLogs Web interface.

For accessing vmalerts UI through VictoriaLogs configure `-vmalert.proxyURL` flag and visit
`http://<victorialogs-addr>:9428/vmalert/` link.

## Multitenancy

VictoriaLogs supports multitenancy. A tenant is identified by `(AccountID, ProjectID)` pair, where `AccountID` and `ProjectID` are arbitrary 32-bit unsigned integers.
Expand Down Expand Up @@ -723,6 +733,8 @@ Pass `-help` to VictoriaLogs in order to see the list of supported command-line
Optional minimum TLS version to use for the corresponding -httpListenAddr if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
Supports an array of values separated by comma or specified via multiple flags.
Value can contain comma inside single-quoted or double-quoted string, {}, [] and () braces.
-vmalert.proxyURL string
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
-version
Show VictoriaMetrics version
```