app/vlselect: handle vmui at /select/vmui path instead of /vmui

This simplifies routing at auth proxies such as vmauth to vlselect component,
which serves VMUI - just route all the requests, which start with /select/, to vlselect.
This commit is contained in:
Aliaksandr Valialkin 2023-06-21 19:52:48 -07:00
parent 33e4d51636
commit 4b10432435
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
5 changed files with 24 additions and 17 deletions

View file

@ -78,7 +78,7 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool {
fmt.Fprintf(w, "See docs at <a href='https://docs.victoriametrics.com/VictoriaLogs/'>https://docs.victoriametrics.com/VictoriaLogs/</a></br>") fmt.Fprintf(w, "See docs at <a href='https://docs.victoriametrics.com/VictoriaLogs/'>https://docs.victoriametrics.com/VictoriaLogs/</a></br>")
fmt.Fprintf(w, "Useful endpoints:</br>") fmt.Fprintf(w, "Useful endpoints:</br>")
httpserver.WriteAPIHelp(w, [][2]string{ httpserver.WriteAPIHelp(w, [][2]string{
{"vmui", "Web UI for VictoriaLogs"}, {"select/vmui", "Web UI for VictoriaLogs"},
{"metrics", "available service metrics"}, {"metrics", "available service metrics"},
{"flags", "command-line flags"}, {"flags", "command-line flags"},
}) })

View file

@ -20,6 +20,7 @@ func Stop() {
func RequestHandler(w http.ResponseWriter, r *http.Request) bool { func RequestHandler(w http.ResponseWriter, r *http.Request) bool {
path := r.URL.Path path := r.URL.Path
if !strings.HasPrefix(path, "/insert/") { if !strings.HasPrefix(path, "/insert/") {
// Skip requests, which do not start with /insert/, since these aren't our requests.
return false return false
} }
path = strings.TrimPrefix(path, "/insert") path = strings.TrimPrefix(path, "/insert")

View file

@ -71,10 +71,29 @@ var vmuiFileServer = http.FileServer(http.FS(vmuiFiles))
// RequestHandler handles select requests for VictoriaLogs // RequestHandler handles select requests for VictoriaLogs
func RequestHandler(w http.ResponseWriter, r *http.Request) bool { func RequestHandler(w http.ResponseWriter, r *http.Request) bool {
path := r.URL.Path path := r.URL.Path
if !strings.HasPrefix(path, "/select/") {
// Skip requests, which do not start with /select/, since these aren't our requests.
return false
}
path = strings.TrimPrefix(path, "/select") path = strings.TrimPrefix(path, "/select")
path = strings.ReplaceAll(path, "//", "/") path = strings.ReplaceAll(path, "//", "/")
// Limit the number of concurrent queries. if path == "/vmui" {
// VMUI access via incomplete url without `/` in the end. Redirect to complete url.
// Use relative redirect, since the hostname and path prefix may be incorrect if VictoriaMetrics
// is hidden behind vmauth or similar proxy.
_ = r.ParseForm()
newURL := "vmui/?" + r.Form.Encode()
httpserver.Redirect(w, newURL)
return true
}
if strings.HasPrefix(path, "/vmui/") {
r.URL.Path = path
vmuiFileServer.ServeHTTP(w, r)
return true
}
// Limit the number of concurrent queries, which can consume big amounts of CPU.
startTime := time.Now() startTime := time.Now()
stopCh := r.Context().Done() stopCh := r.Context().Done()
select { select {
@ -115,24 +134,11 @@ func RequestHandler(w http.ResponseWriter, r *http.Request) bool {
} }
switch { switch {
case path == "/vmui":
// VMUI access via incomplete url without `/` in the end. Redirect to complete url.
// Use relative redirect, since, since the hostname and path prefix may be incorrect if VictoriaMetrics
// is hidden behind vmauth or similar proxy.
_ = r.ParseForm()
path = strings.TrimPrefix(path, "/")
newURL := path + "/?" + r.Form.Encode()
httpserver.Redirect(w, newURL)
return true
case path == "/logsql/query": case path == "/logsql/query":
logsqlQueryRequests.Inc() logsqlQueryRequests.Inc()
httpserver.EnableCORS(w, r) httpserver.EnableCORS(w, r)
logsql.ProcessQueryRequest(w, r, stopCh) logsql.ProcessQueryRequest(w, r, stopCh)
return true return true
case strings.HasPrefix(path, "/vmui/"):
r.URL.Path = path
vmuiFileServer.ServeHTTP(w, r)
return true
default: default:
return false return false
} }

View file

@ -338,7 +338,7 @@ func selectHandler(qt *querytracer.Tracer, startTime time.Time, w http.ResponseW
} }
if p.Suffix == "vmui" || p.Suffix == "graph" || p.Suffix == "prometheus/vmui" || p.Suffix == "prometheus/graph" { if p.Suffix == "vmui" || p.Suffix == "graph" || p.Suffix == "prometheus/vmui" || p.Suffix == "prometheus/graph" {
// VMUI access via incomplete url without `/` in the end. Redirect to complete url. // VMUI access via incomplete url without `/` in the end. Redirect to complete url.
// Use relative redirect, since, since the hostname and path prefix may be incorrect if VictoriaMetrics // Use relative redirect, since the hostname and path prefix may be incorrect if VictoriaMetrics
// is hidden behind vmauth or similar proxy. // is hidden behind vmauth or similar proxy.
_ = r.ParseForm() _ = r.ParseForm()
suffix := strings.Replace(p.Suffix, "prometheus/", "../prometheus/", 1) suffix := strings.Replace(p.Suffix, "prometheus/", "../prometheus/", 1)

View file

@ -60,7 +60,7 @@ with `vl_http_requests_total{path="/select/logsql/query"}` metric.
## Web UI ## Web UI
VictoriaLogs provides a simple Web UI for logs [querying](https://docs.victoriametrics.com/VictoriaLogs/LogsQL.html) and exploration VictoriaLogs provides a simple Web UI for logs [querying](https://docs.victoriametrics.com/VictoriaLogs/LogsQL.html) and exploration
at `http://localhost:9428/vmui`. The UI allows exploring query results: at `http://localhost:9428/select/vmui`. The UI allows exploring query results:
<img src="vmui.png" width="800" /> <img src="vmui.png" width="800" />