VictoriaMetrics/lib/httpserver/path.go
Nikolay 33f40f4a5f
app/vminsert: allows parsing tenant id from labels (#3009)
* app/vminsert: allows parsing tenant id from labels
it should help mitigate issues with vmagent's multiTenant mode, which works incorrectly at heavy load
and it cannot handle more then 100 different tenants.
This functional hidden with flag and do not change vminsert default behaviour
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2970

* Update docs/Cluster-VictoriaMetrics.md

Co-authored-by: Roman Khavronenko <roman@victoriametrics.com>

* wip

* app/vminsert/netstorage: clean remaining labels in order to free up GC

* docs/Cluster-VictoriaMetrics.md: typo fix

* wip

* wip

Co-authored-by: Roman Khavronenko <roman@victoriametrics.com>
Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
2022-09-30 18:35:53 +03:00

67 lines
1.8 KiB
Go

package httpserver
import (
"fmt"
"strings"
)
// Path contains the following path structure:
// /{prefix}/{authToken}/{suffix}
//
// It is compatible with SaaS version.
type Path struct {
Prefix string
AuthToken string
Suffix string
}
// ParsePath parses the given path.
func ParsePath(path string) (*Path, error) {
// The path must have the following form:
// /{prefix}/{authToken}/{suffix}
//
// - prefix must contain `select`, `insert` or `delete`.
// - authToken contains `accountID[:projectID]`, where projectID is optional.
// authToken may also contain `multitenant` string. In this case the accountID and projectID
// are obtained from vm_account_id and vm_project_id labels of the ingested samples.
// - suffix contains arbitrary suffix.
//
// prefix must be used for the routing to the appropriate service
// in the cluster - either vminsert or vmselect.
s := skipPrefixSlashes(path)
n := strings.IndexByte(s, '/')
if n < 0 {
return nil, fmt.Errorf("cannot find {prefix} in %q; expecting /{prefix}/{authToken}/{suffix} format", path)
}
prefix := s[:n]
s = skipPrefixSlashes(s[n+1:])
n = strings.IndexByte(s, '/')
if n < 0 {
return nil, fmt.Errorf("cannot find {authToken} in %q; expecting /{prefix}/{authToken}/{suffix} format", path)
}
authToken := s[:n]
s = skipPrefixSlashes(s[n+1:])
// Substitute double slashes with single slashes in the path, since such slashes
// may appear due improper copy-pasting of the url.
suffix := strings.Replace(s, "//", "/", -1)
p := &Path{
Prefix: prefix,
AuthToken: authToken,
Suffix: suffix,
}
return p, nil
}
// skipPrefixSlashes remove double slashes which may appear due
// improper copy-pasting of the url
func skipPrefixSlashes(s string) string {
for len(s) > 0 && s[0] == '/' {
s = s[1:]
}
return s
}