mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2026-06-28 21:18:23 +03:00
Compare commits
147 Commits
dependabot
...
v1.87.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23f0cc4a9b | ||
|
|
d487ff4ec5 | ||
|
|
1f66d5624d | ||
|
|
17febd84ac | ||
|
|
03728301e9 | ||
|
|
e2f6e351b3 | ||
|
|
4a338d32ce | ||
|
|
5be882cba1 | ||
|
|
8b636350f2 | ||
|
|
9d2fbc99ff | ||
|
|
df856aec6f | ||
|
|
d3ebce2c2f | ||
|
|
a3df6e8a36 | ||
|
|
f7f77307c6 | ||
|
|
b2854d145d | ||
|
|
08737f11e3 | ||
|
|
ab077ab41f | ||
|
|
2c5b260b42 | ||
|
|
9c0119a194 | ||
|
|
9c3f87fac2 | ||
|
|
eb8ee5aab6 | ||
|
|
e58ef6e27d | ||
|
|
01daa5ddb9 | ||
|
|
08b106822d | ||
|
|
a0752b20c7 | ||
|
|
b351f73984 | ||
|
|
4c211028af | ||
|
|
5dba522eaa | ||
|
|
63a793b506 | ||
|
|
0ee30dc00e | ||
|
|
8234741c51 | ||
|
|
26e5cf4160 | ||
|
|
2711770b10 | ||
|
|
041a6369e7 | ||
|
|
e7b3a338fe | ||
|
|
7487a8de1c | ||
|
|
7dc31ab080 | ||
|
|
74a92110bd | ||
|
|
6e02885431 | ||
|
|
e8448fe8fd | ||
|
|
a8835b443f | ||
|
|
e082c3dd27 | ||
|
|
bab0808a7f | ||
|
|
278c580055 | ||
|
|
4c1241d336 | ||
|
|
b3a3260b1d | ||
|
|
2783b99457 | ||
|
|
a0ece56649 | ||
|
|
1ae8912f0f | ||
|
|
26b9f41e08 | ||
|
|
a0d84278ce | ||
|
|
90ee6f174c | ||
|
|
78cd76d96a | ||
|
|
25b527f1e4 | ||
|
|
8febf3c5e6 | ||
|
|
470c82919e | ||
|
|
f4f6bb359e | ||
|
|
591fb53b58 | ||
|
|
fff051b889 | ||
|
|
e5e10988ed | ||
|
|
4c3e0d4411 | ||
|
|
e6d24e68f7 | ||
|
|
a50d63c376 | ||
|
|
89ec85c5db | ||
|
|
7cc7b4436f | ||
|
|
d09ba9f504 | ||
|
|
ab1d226485 | ||
|
|
c7a407368a | ||
|
|
56350eb1ce | ||
|
|
70d9a2e679 | ||
|
|
d324241707 | ||
|
|
112c9a8118 | ||
|
|
03ad293ba2 | ||
|
|
74c7c49335 | ||
|
|
68146a7a89 | ||
|
|
141f793051 | ||
|
|
17386dd7c0 | ||
|
|
5d8b7d1c2a | ||
|
|
8600cb21ed | ||
|
|
befef7f2b8 | ||
|
|
37bc95fe2d | ||
|
|
2191328b2b | ||
|
|
886087c4de | ||
|
|
973ebff145 | ||
|
|
17ff88edb5 | ||
|
|
5058a92bb1 | ||
|
|
a31b871845 | ||
|
|
baa9f0e573 | ||
|
|
9e3818ca27 | ||
|
|
fd1c69e4b7 | ||
|
|
b3ee33eb8e | ||
|
|
87769b36d1 | ||
|
|
81704549c4 | ||
|
|
dfb61ad46c | ||
|
|
0607800f05 | ||
|
|
575032bb68 | ||
|
|
744517829d | ||
|
|
a7079022ff | ||
|
|
36da3faf73 | ||
|
|
bc9bd614ee | ||
|
|
75791bcb77 | ||
|
|
83a8f87131 | ||
|
|
48ee15ac42 | ||
|
|
95f5d4780d | ||
|
|
568b5a7711 | ||
|
|
336c5947c8 | ||
|
|
68b49a900c | ||
|
|
7da72b040b | ||
|
|
d6b6cb56e5 | ||
|
|
a20c4804a0 | ||
|
|
16be82b959 | ||
|
|
d390277509 | ||
|
|
60ccaf670a | ||
|
|
88616346f1 | ||
|
|
9ef38946fd | ||
|
|
9480d609d1 | ||
|
|
481c928011 | ||
|
|
d42650d3a9 | ||
|
|
4e71914e3c | ||
|
|
0d836a51d7 | ||
|
|
d28ee6192d | ||
|
|
e6fa18bfd2 | ||
|
|
439f53fd3e | ||
|
|
fe4dae150d | ||
|
|
4c33716a60 | ||
|
|
47204d2f77 | ||
|
|
90319e69f9 | ||
|
|
cbdaafe541 | ||
|
|
d0ce874b13 | ||
|
|
619da7bfa5 | ||
|
|
dd6e7089a8 | ||
|
|
1dbf7a204c | ||
|
|
4c82081f57 | ||
|
|
69e7621ad5 | ||
|
|
00bc28626d | ||
|
|
b443b7e2ca | ||
|
|
e0a16874f6 | ||
|
|
62f40cb33b | ||
|
|
905f1839ef | ||
|
|
05ca0c16c7 | ||
|
|
0476f2a7ca | ||
|
|
d26b9d89e0 | ||
|
|
29f0a33500 | ||
|
|
af68892e68 | ||
|
|
0b91514a8f | ||
|
|
a96f0df64a | ||
|
|
af83ce33f0 |
2
.github/workflows/check-licenses.yml
vendored
2
.github/workflows/check-licenses.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@main
|
uses: actions/setup-go@main
|
||||||
with:
|
with:
|
||||||
go-version: 1.20.0
|
go-version: 1.21.0
|
||||||
id: go
|
id: go
|
||||||
- name: Code checkout
|
- name: Code checkout
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
|
|||||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -57,7 +57,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.20.0
|
go-version: 1.21.0
|
||||||
check-latest: true
|
check-latest: true
|
||||||
cache: true
|
cache: true
|
||||||
if: ${{ matrix.language == 'go' }}
|
if: ${{ matrix.language == 'go' }}
|
||||||
|
|||||||
6
.github/workflows/main.yml
vendored
6
.github/workflows/main.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.20.0
|
go-version: 1.21.0
|
||||||
check-latest: true
|
check-latest: true
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.20.0
|
go-version: 1.21.0
|
||||||
check-latest: true
|
check-latest: true
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ jobs:
|
|||||||
id: go
|
id: go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.20.0
|
go-version: 1.21.0
|
||||||
check-latest: true
|
check-latest: true
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/nightly-build.yml
vendored
2
.github/workflows/nightly-build.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@main
|
uses: actions/setup-go@main
|
||||||
with:
|
with:
|
||||||
go-version: 1.20.0
|
go-version: 1.21.0
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Setup docker scan
|
- name: Setup docker scan
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -169,6 +169,7 @@ vmutils-crossbuild: \
|
|||||||
vmutils-windows-amd64
|
vmutils-windows-amd64
|
||||||
|
|
||||||
publish-release:
|
publish-release:
|
||||||
|
rm -rf bin/*
|
||||||
git checkout $(TAG) && LATEST_TAG=stable $(MAKE) release publish && \
|
git checkout $(TAG) && LATEST_TAG=stable $(MAKE) release publish && \
|
||||||
git checkout $(TAG)-cluster && LATEST_TAG=cluster-stable $(MAKE) release publish && \
|
git checkout $(TAG)-cluster && LATEST_TAG=cluster-stable $(MAKE) release publish && \
|
||||||
git checkout $(TAG)-enterprise && LATEST_TAG=enterprise-stable $(MAKE) release publish && \
|
git checkout $(TAG)-enterprise && LATEST_TAG=enterprise-stable $(MAKE) release publish && \
|
||||||
@@ -380,7 +381,7 @@ golangci-lint: install-golangci-lint
|
|||||||
golangci-lint run
|
golangci-lint run
|
||||||
|
|
||||||
install-golangci-lint:
|
install-golangci-lint:
|
||||||
which golangci-lint || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.51.1
|
which golangci-lint || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.51.2
|
||||||
|
|
||||||
govulncheck: install-govulncheck
|
govulncheck: install-govulncheck
|
||||||
govulncheck ./...
|
govulncheck ./...
|
||||||
|
|||||||
@@ -2130,7 +2130,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
|
|||||||
|
|
||||||
```
|
```
|
||||||
-bigMergeConcurrency int
|
-bigMergeConcurrency int
|
||||||
The maximum number of CPU cores to use for big merges. Default value is used if set to 0
|
Deprecated: this flag does nothing. Please use -smallMergeConcurrency for controlling the concurrency of background merges. See https://docs.victoriametrics.com/#storage
|
||||||
-cacheExpireDuration duration
|
-cacheExpireDuration duration
|
||||||
Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
|
Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
|
||||||
-configAuthKey string
|
-configAuthKey string
|
||||||
@@ -2469,7 +2469,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
|
|||||||
-selfScrapeJob string
|
-selfScrapeJob string
|
||||||
Value for 'job' label, which is added to self-scraped metrics (default "victoria-metrics")
|
Value for 'job' label, which is added to self-scraped metrics (default "victoria-metrics")
|
||||||
-smallMergeConcurrency int
|
-smallMergeConcurrency int
|
||||||
The maximum number of CPU cores to use for small merges. Default value is used if set to 0
|
The maximum number of workers for background merges. See https://docs.victoriametrics.com/#storage . It isn't recommended tuning this flag in general case, since this may lead to uncontrolled increase in the number of parts and increased CPU usage during queries
|
||||||
-snapshotAuthKey string
|
-snapshotAuthKey string
|
||||||
authKey, which must be passed in query string to /snapshot* pages
|
authKey, which must be passed in query string to /snapshot* pages
|
||||||
-snapshotsMaxAge value
|
-snapshotsMaxAge value
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ import (
|
|||||||
var (
|
var (
|
||||||
httpListenAddr = flag.String("httpListenAddr", ":8428", "TCP address to listen for http connections. See also -httpListenAddr.useProxyProtocol")
|
httpListenAddr = flag.String("httpListenAddr", ":8428", "TCP address to listen for http connections. See also -httpListenAddr.useProxyProtocol")
|
||||||
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
||||||
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt")
|
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
||||||
|
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
||||||
minScrapeInterval = flag.Duration("dedup.minScrapeInterval", 0, "Leave only the last sample in every time series per each discrete interval "+
|
minScrapeInterval = flag.Duration("dedup.minScrapeInterval", 0, "Leave only the last sample in every time series per each discrete interval "+
|
||||||
"equal to -dedup.minScrapeInterval > 0. See https://docs.victoriametrics.com/#deduplication and https://docs.victoriametrics.com/#downsampling")
|
"equal to -dedup.minScrapeInterval > 0. See https://docs.victoriametrics.com/#deduplication and https://docs.victoriametrics.com/#downsampling")
|
||||||
dryRun = flag.Bool("dryRun", false, "Whether to check only -promscrape.config and then exit. "+
|
dryRun = flag.Bool("dryRun", false, "Whether to check only -promscrape.config and then exit. "+
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ var (
|
|||||||
"Set this flag to empty value in order to disable listening on any port. This mode may be useful for running multiple vmagent instances on the same server. "+
|
"Set this flag to empty value in order to disable listening on any port. This mode may be useful for running multiple vmagent instances on the same server. "+
|
||||||
"Note that /targets and /metrics pages aren't available if -httpListenAddr=''. See also -httpListenAddr.useProxyProtocol")
|
"Note that /targets and /metrics pages aren't available if -httpListenAddr=''. See also -httpListenAddr.useProxyProtocol")
|
||||||
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
||||||
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt")
|
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
||||||
|
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
||||||
influxListenAddr = flag.String("influxListenAddr", "", "TCP and UDP address to listen for InfluxDB line protocol data. Usually :8089 must be set. Doesn't work if empty. "+
|
influxListenAddr = flag.String("influxListenAddr", "", "TCP and UDP address to listen for InfluxDB line protocol data. Usually :8089 must be set. Doesn't work if empty. "+
|
||||||
"This flag isn't needed when ingesting data over HTTP - just send it to http://<vmagent>:8429/write . "+
|
"This flag isn't needed when ingesting data over HTTP - just send it to http://<vmagent>:8429/write . "+
|
||||||
"See also -influxListenAddr.useProxyProtocol")
|
"See also -influxListenAddr.useProxyProtocol")
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ func (rctx *relabelCtx) applyRelabeling(tss []prompbmarshal.TimeSeries, extraLab
|
|||||||
for j := range tmpLabels {
|
for j := range tmpLabels {
|
||||||
label := &tmpLabels[j]
|
label := &tmpLabels[j]
|
||||||
if label.Name == "__name__" {
|
if label.Name == "__name__" {
|
||||||
label.Value = promrelabel.SanitizeName(label.Value)
|
label.Value = promrelabel.SanitizeMetricName(label.Value)
|
||||||
} else {
|
} else {
|
||||||
label.Name = promrelabel.SanitizeName(label.Name)
|
label.Name = promrelabel.SanitizeLabelName(label.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -524,6 +524,11 @@ func newRemoteWriteCtx(argIdx int, at *auth.Token, remoteWriteURL *url.URL, maxI
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (rwctx *remoteWriteCtx) MustStop() {
|
func (rwctx *remoteWriteCtx) MustStop() {
|
||||||
|
// sas must be stopped before rwctx is closed
|
||||||
|
// because sas can write pending series to rwctx.pss if there are any
|
||||||
|
rwctx.sas.MustStop()
|
||||||
|
rwctx.sas = nil
|
||||||
|
|
||||||
for _, ps := range rwctx.pss {
|
for _, ps := range rwctx.pss {
|
||||||
ps.MustStop()
|
ps.MustStop()
|
||||||
}
|
}
|
||||||
@@ -532,8 +537,7 @@ func (rwctx *remoteWriteCtx) MustStop() {
|
|||||||
rwctx.fq.UnblockAllReaders()
|
rwctx.fq.UnblockAllReaders()
|
||||||
rwctx.c.MustStop()
|
rwctx.c.MustStop()
|
||||||
rwctx.c = nil
|
rwctx.c = nil
|
||||||
rwctx.sas.MustStop()
|
|
||||||
rwctx.sas = nil
|
|
||||||
rwctx.fq.MustClose()
|
rwctx.fq.MustClose()
|
||||||
rwctx.fq = nil
|
rwctx.fq = nil
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ test-vmalert:
|
|||||||
go test -v -race -cover ./app/vmalert/notifier
|
go test -v -race -cover ./app/vmalert/notifier
|
||||||
go test -v -race -cover ./app/vmalert/config
|
go test -v -race -cover ./app/vmalert/config
|
||||||
go test -v -race -cover ./app/vmalert/remotewrite
|
go test -v -race -cover ./app/vmalert/remotewrite
|
||||||
|
go test -v -race -cover ./app/vmalert/utils
|
||||||
|
|
||||||
run-vmalert: vmalert
|
run-vmalert: vmalert
|
||||||
./bin/vmalert -rule=app/vmalert/config/testdata/rules/rules2-good.rules \
|
./bin/vmalert -rule=app/vmalert/config/testdata/rules/rules2-good.rules \
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ func toDatasourceType(s string) datasourceType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VMStorage represents vmstorage entity with ability to read and write metrics
|
// VMStorage represents vmstorage entity with ability to read and write metrics
|
||||||
|
// WARN: when adding a new field, remember to update Clone() method.
|
||||||
type VMStorage struct {
|
type VMStorage struct {
|
||||||
c *http.Client
|
c *http.Client
|
||||||
authCfg *promauth.Config
|
authCfg *promauth.Config
|
||||||
@@ -53,29 +54,54 @@ type keyValue struct {
|
|||||||
|
|
||||||
// Clone makes clone of VMStorage, shares http client.
|
// Clone makes clone of VMStorage, shares http client.
|
||||||
func (s *VMStorage) Clone() *VMStorage {
|
func (s *VMStorage) Clone() *VMStorage {
|
||||||
return &VMStorage{
|
ns := &VMStorage{
|
||||||
c: s.c,
|
c: s.c,
|
||||||
authCfg: s.authCfg,
|
authCfg: s.authCfg,
|
||||||
datasourceURL: s.datasourceURL,
|
datasourceURL: s.datasourceURL,
|
||||||
|
appendTypePrefix: s.appendTypePrefix,
|
||||||
lookBack: s.lookBack,
|
lookBack: s.lookBack,
|
||||||
queryStep: s.queryStep,
|
queryStep: s.queryStep,
|
||||||
appendTypePrefix: s.appendTypePrefix,
|
|
||||||
dataSourceType: s.dataSourceType,
|
dataSourceType: s.dataSourceType,
|
||||||
|
evaluationInterval: s.evaluationInterval,
|
||||||
|
|
||||||
|
// init map so it can be populated below
|
||||||
|
extraParams: url.Values{},
|
||||||
|
|
||||||
|
debug: s.debug,
|
||||||
}
|
}
|
||||||
|
if len(s.extraHeaders) > 0 {
|
||||||
|
ns.extraHeaders = make([]keyValue, len(s.extraHeaders))
|
||||||
|
copy(ns.extraHeaders, s.extraHeaders)
|
||||||
|
}
|
||||||
|
for k, v := range s.extraParams {
|
||||||
|
ns.extraParams[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return ns
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyParams - changes given querier params.
|
// ApplyParams - changes given querier params.
|
||||||
func (s *VMStorage) ApplyParams(params QuerierParams) *VMStorage {
|
func (s *VMStorage) ApplyParams(params QuerierParams) *VMStorage {
|
||||||
s.dataSourceType = toDatasourceType(params.DataSourceType)
|
s.dataSourceType = toDatasourceType(params.DataSourceType)
|
||||||
s.evaluationInterval = params.EvaluationInterval
|
s.evaluationInterval = params.EvaluationInterval
|
||||||
s.extraParams = params.QueryParams
|
if params.QueryParams != nil {
|
||||||
s.debug = params.Debug
|
if s.extraParams == nil {
|
||||||
|
s.extraParams = url.Values{}
|
||||||
|
}
|
||||||
|
for k, vl := range params.QueryParams {
|
||||||
|
for _, v := range vl { // custom query params are prior to default ones
|
||||||
|
s.extraParams.Set(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if params.Headers != nil {
|
if params.Headers != nil {
|
||||||
for key, value := range params.Headers {
|
for key, value := range params.Headers {
|
||||||
kv := keyValue{key: key, value: value}
|
kv := keyValue{key: key, value: value}
|
||||||
s.extraHeaders = append(s.extraHeaders, kv)
|
s.extraHeaders = append(s.extraHeaders, kv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s.debug = params.Debug
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +120,7 @@ func NewVMStorage(baseURL string, authCfg *promauth.Config, lookBack time.Durati
|
|||||||
lookBack: lookBack,
|
lookBack: lookBack,
|
||||||
queryStep: queryStep,
|
queryStep: queryStep,
|
||||||
dataSourceType: datasourcePrometheus,
|
dataSourceType: datasourcePrometheus,
|
||||||
|
extraParams: url.Values{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -279,6 +279,9 @@ func TestRequestParams(t *testing.T) {
|
|||||||
}
|
}
|
||||||
query := "up"
|
query := "up"
|
||||||
timestamp := time.Date(2001, 2, 3, 4, 5, 6, 0, time.UTC)
|
timestamp := time.Date(2001, 2, 3, 4, 5, 6, 0, time.UTC)
|
||||||
|
storage := VMStorage{
|
||||||
|
extraParams: url.Values{"round_digits": {"10"}},
|
||||||
|
}
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
queryRange bool
|
queryRange bool
|
||||||
@@ -475,6 +478,17 @@ func TestRequestParams(t *testing.T) {
|
|||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
checkEqualString(t, exp, r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"custom params overrides the original params",
|
||||||
|
false,
|
||||||
|
storage.Clone().ApplyParams(QuerierParams{
|
||||||
|
QueryParams: url.Values{"round_digits": {"2"}},
|
||||||
|
}),
|
||||||
|
func(t *testing.T, r *http.Request) {
|
||||||
|
exp := fmt.Sprintf("query=%s&round_digits=2&time=%d", query, timestamp.Unix())
|
||||||
|
checkEqualString(t, exp, r.URL.RawQuery)
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"graphite extra params",
|
"graphite extra params",
|
||||||
false,
|
false,
|
||||||
|
|||||||
@@ -323,11 +323,17 @@ func (g *Group) start(ctx context.Context, nts func() []notifier.Notifier, rw *r
|
|||||||
g.Interval = ng.Interval
|
g.Interval = ng.Interval
|
||||||
t.Stop()
|
t.Stop()
|
||||||
t = time.NewTicker(g.Interval)
|
t = time.NewTicker(g.Interval)
|
||||||
|
evalTS = time.Now()
|
||||||
}
|
}
|
||||||
g.mu.Unlock()
|
g.mu.Unlock()
|
||||||
logger.Infof("group %q re-started; interval=%v; concurrency=%d", g.Name, g.Interval, g.Concurrency)
|
logger.Infof("group %q re-started; interval=%v; concurrency=%d", g.Name, g.Interval, g.Concurrency)
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
missed := (time.Since(evalTS) / g.Interval) - 1
|
missed := (time.Since(evalTS) / g.Interval) - 1
|
||||||
|
if missed < 0 {
|
||||||
|
// missed can become < 0 due to irregular delays during evaluation
|
||||||
|
// which can result in time.Since(evalTS) < g.Interval
|
||||||
|
missed = 0
|
||||||
|
}
|
||||||
if missed > 0 {
|
if missed > 0 {
|
||||||
g.metrics.iterationMissed.Inc()
|
g.metrics.iterationMissed.Inc()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ absolute path to all .tpl files in root.`)
|
|||||||
|
|
||||||
httpListenAddr = flag.String("httpListenAddr", ":8880", "Address to listen for http connections. See also -httpListenAddr.useProxyProtocol")
|
httpListenAddr = flag.String("httpListenAddr", ":8880", "Address to listen for http connections. See also -httpListenAddr.useProxyProtocol")
|
||||||
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
||||||
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt")
|
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
||||||
|
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
||||||
evaluationInterval = flag.Duration("evaluationInterval", time.Minute, "How often to evaluate the rules")
|
evaluationInterval = flag.Duration("evaluationInterval", time.Minute, "How often to evaluate the rules")
|
||||||
|
|
||||||
validateTemplates = flag.Bool("rule.validateTemplates", true, "Whether to validate annotation and label templates")
|
validateTemplates = flag.Bool("rule.validateTemplates", true, "Whether to validate annotation and label templates")
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ func (g *Group) toAPI() APIGroup {
|
|||||||
Headers: headersToStrings(g.Headers),
|
Headers: headersToStrings(g.Headers),
|
||||||
Labels: g.Labels,
|
Labels: g.Labels,
|
||||||
}
|
}
|
||||||
|
ag.Rules = make([]APIRule, 0)
|
||||||
for _, r := range g.Rules {
|
for _, r := range g.Rules {
|
||||||
ag.Rules = append(ag.Rules, r.ToAPI())
|
ag.Rules = append(ag.Rules, r.ToAPI())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{% import (
|
{% import (
|
||||||
"strings"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -85,10 +84,7 @@ type NavItem struct {
|
|||||||
|
|
||||||
{% func printNavItems(r *http.Request, current string, items []NavItem) %}
|
{% func printNavItems(r *http.Request, current string, items []NavItem) %}
|
||||||
{%code
|
{%code
|
||||||
prefix := "/vmalert/"
|
prefix := utils.Prefix(r.URL.Path)
|
||||||
if strings.HasPrefix(r.URL.Path, prefix) {
|
|
||||||
prefix = ""
|
|
||||||
}
|
|
||||||
%}
|
%}
|
||||||
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
|
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|||||||
@@ -9,52 +9,51 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:10
|
//line app/vmalert/tpl/header.qtpl:9
|
||||||
import (
|
import (
|
||||||
qtio422016 "io"
|
qtio422016 "io"
|
||||||
|
|
||||||
qt422016 "github.com/valyala/quicktemplate"
|
qt422016 "github.com/valyala/quicktemplate"
|
||||||
)
|
)
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:10
|
//line app/vmalert/tpl/header.qtpl:9
|
||||||
var (
|
var (
|
||||||
_ = qtio422016.Copy
|
_ = qtio422016.Copy
|
||||||
_ = qt422016.AcquireByteBuffer
|
_ = qt422016.AcquireByteBuffer
|
||||||
)
|
)
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:10
|
//line app/vmalert/tpl/header.qtpl:9
|
||||||
func StreamHeader(qw422016 *qt422016.Writer, r *http.Request, navItems []NavItem, title string) {
|
func StreamHeader(qw422016 *qt422016.Writer, r *http.Request, navItems []NavItem, title string) {
|
||||||
//line app/vmalert/tpl/header.qtpl:10
|
//line app/vmalert/tpl/header.qtpl:9
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line app/vmalert/tpl/header.qtpl:11
|
//line app/vmalert/tpl/header.qtpl:10
|
||||||
prefix := utils.Prefix(r.URL.Path)
|
prefix := utils.Prefix(r.URL.Path)
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:11
|
//line app/vmalert/tpl/header.qtpl:10
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>vmalert`)
|
<title>vmalert`)
|
||||||
//line app/vmalert/tpl/header.qtpl:15
|
//line app/vmalert/tpl/header.qtpl:14
|
||||||
if title != "" {
|
if title != "" {
|
||||||
//line app/vmalert/tpl/header.qtpl:15
|
//line app/vmalert/tpl/header.qtpl:14
|
||||||
qw422016.N().S(` - `)
|
qw422016.N().S(` - `)
|
||||||
//line app/vmalert/tpl/header.qtpl:15
|
//line app/vmalert/tpl/header.qtpl:14
|
||||||
qw422016.E().S(title)
|
qw422016.E().S(title)
|
||||||
//line app/vmalert/tpl/header.qtpl:15
|
//line app/vmalert/tpl/header.qtpl:14
|
||||||
}
|
}
|
||||||
//line app/vmalert/tpl/header.qtpl:15
|
//line app/vmalert/tpl/header.qtpl:14
|
||||||
qw422016.N().S(`</title>
|
qw422016.N().S(`</title>
|
||||||
<link href="`)
|
<link href="`)
|
||||||
//line app/vmalert/tpl/header.qtpl:16
|
//line app/vmalert/tpl/header.qtpl:15
|
||||||
qw422016.E().S(prefix)
|
qw422016.E().S(prefix)
|
||||||
//line app/vmalert/tpl/header.qtpl:16
|
//line app/vmalert/tpl/header.qtpl:15
|
||||||
qw422016.N().S(`static/css/bootstrap.min.css" rel="stylesheet" />
|
qw422016.N().S(`static/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
<style>
|
<style>
|
||||||
body{
|
body{
|
||||||
@@ -114,139 +113,136 @@ func StreamHeader(qw422016 *qt422016.Writer, r *http.Request, navItems []NavItem
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
`)
|
`)
|
||||||
//line app/vmalert/tpl/header.qtpl:74
|
//line app/vmalert/tpl/header.qtpl:73
|
||||||
streamprintNavItems(qw422016, r, title, navItems)
|
streamprintNavItems(qw422016, r, title, navItems)
|
||||||
//line app/vmalert/tpl/header.qtpl:74
|
//line app/vmalert/tpl/header.qtpl:73
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<main class="px-2">
|
<main class="px-2">
|
||||||
`)
|
`)
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
}
|
}
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
func WriteHeader(qq422016 qtio422016.Writer, r *http.Request, navItems []NavItem, title string) {
|
func WriteHeader(qq422016 qtio422016.Writer, r *http.Request, navItems []NavItem, title string) {
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
StreamHeader(qw422016, r, navItems, title)
|
StreamHeader(qw422016, r, navItems, title)
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
}
|
}
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
func Header(r *http.Request, navItems []NavItem, title string) string {
|
func Header(r *http.Request, navItems []NavItem, title string) string {
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
WriteHeader(qb422016, r, navItems, title)
|
WriteHeader(qb422016, r, navItems, title)
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
qs422016 := string(qb422016.B)
|
qs422016 := string(qb422016.B)
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
qt422016.ReleaseByteBuffer(qb422016)
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
return qs422016
|
return qs422016
|
||||||
//line app/vmalert/tpl/header.qtpl:76
|
//line app/vmalert/tpl/header.qtpl:75
|
||||||
}
|
}
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:80
|
//line app/vmalert/tpl/header.qtpl:79
|
||||||
type NavItem struct {
|
type NavItem struct {
|
||||||
Name string
|
Name string
|
||||||
Url string
|
Url string
|
||||||
}
|
}
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:86
|
//line app/vmalert/tpl/header.qtpl:85
|
||||||
func streamprintNavItems(qw422016 *qt422016.Writer, r *http.Request, current string, items []NavItem) {
|
func streamprintNavItems(qw422016 *qt422016.Writer, r *http.Request, current string, items []NavItem) {
|
||||||
//line app/vmalert/tpl/header.qtpl:86
|
//line app/vmalert/tpl/header.qtpl:85
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line app/vmalert/tpl/header.qtpl:88
|
//line app/vmalert/tpl/header.qtpl:87
|
||||||
prefix := "/vmalert/"
|
prefix := utils.Prefix(r.URL.Path)
|
||||||
if strings.HasPrefix(r.URL.Path, prefix) {
|
|
||||||
prefix = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:92
|
//line app/vmalert/tpl/header.qtpl:88
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
|
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="collapse navbar-collapse" id="navbarCollapse">
|
<div class="collapse navbar-collapse" id="navbarCollapse">
|
||||||
<ul class="navbar-nav me-auto mb-2 mb-md-0">
|
<ul class="navbar-nav me-auto mb-2 mb-md-0">
|
||||||
`)
|
`)
|
||||||
//line app/vmalert/tpl/header.qtpl:97
|
//line app/vmalert/tpl/header.qtpl:93
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
//line app/vmalert/tpl/header.qtpl:97
|
//line app/vmalert/tpl/header.qtpl:93
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
`)
|
`)
|
||||||
//line app/vmalert/tpl/header.qtpl:100
|
//line app/vmalert/tpl/header.qtpl:96
|
||||||
u, _ := url.Parse(item.Url)
|
u, _ := url.Parse(item.Url)
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:101
|
//line app/vmalert/tpl/header.qtpl:97
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<a class="nav-link`)
|
<a class="nav-link`)
|
||||||
//line app/vmalert/tpl/header.qtpl:102
|
//line app/vmalert/tpl/header.qtpl:98
|
||||||
if current == item.Name {
|
if current == item.Name {
|
||||||
//line app/vmalert/tpl/header.qtpl:102
|
//line app/vmalert/tpl/header.qtpl:98
|
||||||
qw422016.N().S(` active`)
|
qw422016.N().S(` active`)
|
||||||
//line app/vmalert/tpl/header.qtpl:102
|
//line app/vmalert/tpl/header.qtpl:98
|
||||||
}
|
}
|
||||||
//line app/vmalert/tpl/header.qtpl:102
|
//line app/vmalert/tpl/header.qtpl:98
|
||||||
qw422016.N().S(`"
|
qw422016.N().S(`"
|
||||||
href="`)
|
href="`)
|
||||||
//line app/vmalert/tpl/header.qtpl:103
|
//line app/vmalert/tpl/header.qtpl:99
|
||||||
if u.IsAbs() {
|
if u.IsAbs() {
|
||||||
//line app/vmalert/tpl/header.qtpl:103
|
//line app/vmalert/tpl/header.qtpl:99
|
||||||
qw422016.E().S(item.Url)
|
qw422016.E().S(item.Url)
|
||||||
//line app/vmalert/tpl/header.qtpl:103
|
//line app/vmalert/tpl/header.qtpl:99
|
||||||
} else {
|
} else {
|
||||||
//line app/vmalert/tpl/header.qtpl:103
|
//line app/vmalert/tpl/header.qtpl:99
|
||||||
qw422016.E().S(path.Join(prefix, item.Url))
|
qw422016.E().S(path.Join(prefix, item.Url))
|
||||||
//line app/vmalert/tpl/header.qtpl:103
|
//line app/vmalert/tpl/header.qtpl:99
|
||||||
}
|
}
|
||||||
//line app/vmalert/tpl/header.qtpl:103
|
//line app/vmalert/tpl/header.qtpl:99
|
||||||
qw422016.N().S(`">
|
qw422016.N().S(`">
|
||||||
`)
|
`)
|
||||||
//line app/vmalert/tpl/header.qtpl:104
|
//line app/vmalert/tpl/header.qtpl:100
|
||||||
qw422016.E().S(item.Name)
|
qw422016.E().S(item.Name)
|
||||||
//line app/vmalert/tpl/header.qtpl:104
|
//line app/vmalert/tpl/header.qtpl:100
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
`)
|
`)
|
||||||
//line app/vmalert/tpl/header.qtpl:107
|
//line app/vmalert/tpl/header.qtpl:103
|
||||||
}
|
}
|
||||||
//line app/vmalert/tpl/header.qtpl:107
|
//line app/vmalert/tpl/header.qtpl:103
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
`)
|
`)
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
}
|
}
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
func writeprintNavItems(qq422016 qtio422016.Writer, r *http.Request, current string, items []NavItem) {
|
func writeprintNavItems(qq422016 qtio422016.Writer, r *http.Request, current string, items []NavItem) {
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
streamprintNavItems(qw422016, r, current, items)
|
streamprintNavItems(qw422016, r, current, items)
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
}
|
}
|
||||||
|
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
func printNavItems(r *http.Request, current string, items []NavItem) string {
|
func printNavItems(r *http.Request, current string, items []NavItem) string {
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
writeprintNavItems(qb422016, r, current, items)
|
writeprintNavItems(qb422016, r, current, items)
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
qs422016 := string(qb422016.B)
|
qs422016 := string(qb422016.B)
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
qt422016.ReleaseByteBuffer(qb422016)
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
return qs422016
|
return qs422016
|
||||||
//line app/vmalert/tpl/header.qtpl:111
|
//line app/vmalert/tpl/header.qtpl:107
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,24 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver"
|
||||||
|
)
|
||||||
|
|
||||||
const prefix = "/vmalert/"
|
const prefix = "/vmalert/"
|
||||||
|
|
||||||
// Prefix returns "/vmalert/" prefix if it is missing in the path.
|
// Prefix returns "/vmalert/" prefix if it is missing in the path.
|
||||||
func Prefix(path string) string {
|
func Prefix(path string) string {
|
||||||
|
pp := httpserver.GetPathPrefix()
|
||||||
|
path = strings.TrimLeft(path, pp)
|
||||||
if strings.HasPrefix(path, prefix) {
|
if strings.HasPrefix(path, prefix) {
|
||||||
return ""
|
return pp
|
||||||
}
|
}
|
||||||
return prefix
|
res, err := url.JoinPath(pp, prefix)
|
||||||
|
if err != nil {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ func (rh *requestHandler) groups() []APIGroup {
|
|||||||
rh.m.groupsMu.RLock()
|
rh.m.groupsMu.RLock()
|
||||||
defer rh.m.groupsMu.RUnlock()
|
defer rh.m.groupsMu.RUnlock()
|
||||||
|
|
||||||
var groups []APIGroup
|
groups := make([]APIGroup, 0)
|
||||||
for _, g := range rh.m.groups {
|
for _, g := range rh.m.groups {
|
||||||
groups = append(groups, g.toAPI())
|
groups = append(groups, g.toAPI())
|
||||||
}
|
}
|
||||||
@@ -276,6 +276,7 @@ func (rh *requestHandler) listAlerts() ([]byte, error) {
|
|||||||
defer rh.m.groupsMu.RUnlock()
|
defer rh.m.groupsMu.RUnlock()
|
||||||
|
|
||||||
lr := listAlertsResponse{Status: "success"}
|
lr := listAlertsResponse{Status: "success"}
|
||||||
|
lr.Data.Alerts = make([]*APIAlert, 0)
|
||||||
for _, g := range rh.m.groups {
|
for _, g := range rh.m.groups {
|
||||||
for _, r := range g.Rules {
|
for _, r := range g.Rules {
|
||||||
a, ok := r.(*AlertingRule)
|
a, ok := r.(*AlertingRule)
|
||||||
|
|||||||
@@ -144,5 +144,81 @@ func TestHandler(t *testing.T) {
|
|||||||
t.Run("/api/v1/1/0/status", func(t *testing.T) {
|
t.Run("/api/v1/1/0/status", func(t *testing.T) {
|
||||||
getResp(ts.URL+"/api/v1/1/0/status", nil, 404)
|
getResp(ts.URL+"/api/v1/1/0/status", nil, 404)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEmptyResponse(t *testing.T) {
|
||||||
|
rhWithNoGroups := &requestHandler{m: &manager{groups: make(map[uint64]*Group)}}
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rhWithNoGroups.handler(w, r) }))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
getResp := func(url string, to interface{}, code int) {
|
||||||
|
t.Helper()
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err %s", err)
|
||||||
|
}
|
||||||
|
if code != resp.StatusCode {
|
||||||
|
t.Errorf("unexpected status code %d want %d", resp.StatusCode, code)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := resp.Body.Close(); err != nil {
|
||||||
|
t.Errorf("err closing body %s", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if to != nil {
|
||||||
|
if err = json.NewDecoder(resp.Body).Decode(to); err != nil {
|
||||||
|
t.Errorf("unexpected err %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("no groups /api/v1/alerts", func(t *testing.T) {
|
||||||
|
lr := listAlertsResponse{}
|
||||||
|
getResp(ts.URL+"/api/v1/alerts", &lr, 200)
|
||||||
|
if lr.Data.Alerts == nil {
|
||||||
|
t.Errorf("expected /api/v1/alerts response to have non-nil data")
|
||||||
|
}
|
||||||
|
|
||||||
|
lr = listAlertsResponse{}
|
||||||
|
getResp(ts.URL+"/vmalert/api/v1/alerts", &lr, 200)
|
||||||
|
if lr.Data.Alerts == nil {
|
||||||
|
t.Errorf("expected /api/v1/alerts response to have non-nil data")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("no groups /api/v1/rules", func(t *testing.T) {
|
||||||
|
lr := listGroupsResponse{}
|
||||||
|
getResp(ts.URL+"/api/v1/rules", &lr, 200)
|
||||||
|
if lr.Data.Groups == nil {
|
||||||
|
t.Errorf("expected /api/v1/rules response to have non-nil data")
|
||||||
|
}
|
||||||
|
|
||||||
|
lr = listGroupsResponse{}
|
||||||
|
getResp(ts.URL+"/vmalert/api/v1/rules", &lr, 200)
|
||||||
|
if lr.Data.Groups == nil {
|
||||||
|
t.Errorf("expected /api/v1/rules response to have non-nil data")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
rhWithEmptyGroup := &requestHandler{m: &manager{groups: map[uint64]*Group{0: {Name: "test"}}}}
|
||||||
|
ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rhWithEmptyGroup.handler(w, r) })
|
||||||
|
|
||||||
|
t.Run("empty group /api/v1/rules", func(t *testing.T) {
|
||||||
|
lr := listGroupsResponse{}
|
||||||
|
getResp(ts.URL+"/api/v1/rules", &lr, 200)
|
||||||
|
if lr.Data.Groups == nil {
|
||||||
|
t.Fatalf("expected /api/v1/rules response to have non-nil data")
|
||||||
|
}
|
||||||
|
|
||||||
|
lr = listGroupsResponse{}
|
||||||
|
getResp(ts.URL+"/vmalert/api/v1/rules", &lr, 200)
|
||||||
|
if lr.Data.Groups == nil {
|
||||||
|
t.Fatalf("expected /api/v1/rules response to have non-nil data")
|
||||||
|
}
|
||||||
|
|
||||||
|
group := lr.Data.Groups[0]
|
||||||
|
if group.Rules == nil {
|
||||||
|
t.Fatalf("expected /api/v1/rules response to have non-nil rules for group")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ import (
|
|||||||
var (
|
var (
|
||||||
httpListenAddr = flag.String("httpListenAddr", ":8427", "TCP address to listen for http connections. See also -httpListenAddr.useProxyProtocol")
|
httpListenAddr = flag.String("httpListenAddr", ":8427", "TCP address to listen for http connections. See also -httpListenAddr.useProxyProtocol")
|
||||||
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
useProxyProtocol = flag.Bool("httpListenAddr.useProxyProtocol", false, "Whether to use proxy protocol for connections accepted at -httpListenAddr . "+
|
||||||
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt")
|
"See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . "+
|
||||||
|
"With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing")
|
||||||
maxIdleConnsPerBackend = flag.Int("maxIdleConnsPerBackend", 100, "The maximum number of idle connections vmauth can open per each backend host. "+
|
maxIdleConnsPerBackend = flag.Int("maxIdleConnsPerBackend", 100, "The maximum number of idle connections vmauth can open per each backend host. "+
|
||||||
"See also -maxConcurrentRequests")
|
"See also -maxConcurrentRequests")
|
||||||
responseTimeout = flag.Duration("responseTimeout", 5*time.Minute, "The timeout for receiving a response from backend")
|
responseTimeout = flag.Duration("responseTimeout", 5*time.Minute, "The timeout for receiving a response from backend")
|
||||||
@@ -94,15 +95,15 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool {
|
|||||||
ui := ac[authToken]
|
ui := ac[authToken]
|
||||||
if ui == nil {
|
if ui == nil {
|
||||||
invalidAuthTokenRequests.Inc()
|
invalidAuthTokenRequests.Inc()
|
||||||
err := fmt.Errorf("cannot find the provided auth token %q in config", authToken)
|
|
||||||
if *logInvalidAuthTokens {
|
if *logInvalidAuthTokens {
|
||||||
|
err := fmt.Errorf("cannot find the provided auth token %q in config", authToken)
|
||||||
err = &httpserver.ErrorWithStatusCode{
|
err = &httpserver.ErrorWithStatusCode{
|
||||||
Err: err,
|
Err: err,
|
||||||
StatusCode: http.StatusUnauthorized,
|
StatusCode: http.StatusUnauthorized,
|
||||||
}
|
}
|
||||||
httpserver.Errorf(w, r, "%s", err)
|
httpserver.Errorf(w, r, "%s", err)
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, err.Error(), http.StatusUnauthorized)
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,29 +49,35 @@ func main() {
|
|||||||
logger.Init()
|
logger.Init()
|
||||||
pushmetrics.Init()
|
pushmetrics.Init()
|
||||||
|
|
||||||
|
// Storing snapshot delete function to be able to call it in case
|
||||||
|
// of error since logger.Fatal will exit the program without
|
||||||
|
// calling deferred functions.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2055
|
||||||
|
deleteSnapshot := func() {}
|
||||||
|
|
||||||
if len(*snapshotCreateURL) > 0 {
|
if len(*snapshotCreateURL) > 0 {
|
||||||
// create net/url object
|
// create net/url object
|
||||||
createUrl, err := url.Parse(*snapshotCreateURL)
|
createURL, err := url.Parse(*snapshotCreateURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("cannot parse snapshotCreateURL: %s", err)
|
logger.Fatalf("cannot parse snapshotCreateURL: %s", err)
|
||||||
}
|
}
|
||||||
if len(*snapshotName) > 0 {
|
if len(*snapshotName) > 0 {
|
||||||
logger.Fatalf("-snapshotName shouldn't be set if -snapshot.createURL is set, since snapshots are created automatically in this case")
|
logger.Fatalf("-snapshotName shouldn't be set if -snapshot.createURL is set, since snapshots are created automatically in this case")
|
||||||
}
|
}
|
||||||
logger.Infof("Snapshot create url %s", createUrl.Redacted())
|
logger.Infof("Snapshot create url %s", createURL.Redacted())
|
||||||
if len(*snapshotDeleteURL) <= 0 {
|
if len(*snapshotDeleteURL) <= 0 {
|
||||||
err := flag.Set("snapshot.deleteURL", strings.Replace(*snapshotCreateURL, "/create", "/delete", 1))
|
err := flag.Set("snapshot.deleteURL", strings.Replace(*snapshotCreateURL, "/create", "/delete", 1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("Failed to set snapshot.deleteURL flag: %v", err)
|
logger.Fatalf("Failed to set snapshot.deleteURL flag: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
deleteUrl, err := url.Parse(*snapshotDeleteURL)
|
deleteURL, err := url.Parse(*snapshotDeleteURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("cannot parse snapshotDeleteURL: %s", err)
|
logger.Fatalf("cannot parse snapshotDeleteURL: %s", err)
|
||||||
}
|
}
|
||||||
logger.Infof("Snapshot delete url %s", deleteUrl.Redacted())
|
logger.Infof("Snapshot delete url %s", deleteURL.Redacted())
|
||||||
|
|
||||||
name, err := snapshot.Create(createUrl.String())
|
name, err := snapshot.Create(createURL.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("cannot create snapshot: %s", err)
|
logger.Fatalf("cannot create snapshot: %s", err)
|
||||||
}
|
}
|
||||||
@@ -80,32 +86,48 @@ func main() {
|
|||||||
logger.Fatalf("cannot set snapshotName flag: %v", err)
|
logger.Fatalf("cannot set snapshotName flag: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
deleteSnapshot = func() {
|
||||||
err := snapshot.Delete(deleteUrl.String(), name)
|
err := snapshot.Delete(deleteURL.String(), name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("cannot delete snapshot: %s", err)
|
logger.Fatalf("cannot delete snapshot: %s", err)
|
||||||
}
|
}
|
||||||
}()
|
}
|
||||||
} else if len(*snapshotName) == 0 {
|
} else if len(*snapshotName) == 0 {
|
||||||
logger.Fatalf("`-snapshotName` or `-snapshot.createURL` must be provided")
|
logger.Fatalf("`-snapshotName` or `-snapshot.createURL` must be provided")
|
||||||
}
|
}
|
||||||
if err := snapshot.Validate(*snapshotName); err != nil {
|
|
||||||
logger.Fatalf("invalid -snapshotName=%q: %s", *snapshotName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go httpserver.Serve(*httpListenAddr, false, nil)
|
go httpserver.Serve(*httpListenAddr, false, nil)
|
||||||
|
|
||||||
|
err := makeBackup()
|
||||||
|
deleteSnapshot()
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("cannot create backup: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
startTime := time.Now()
|
||||||
|
logger.Infof("gracefully shutting down http server for metrics at %q", *httpListenAddr)
|
||||||
|
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
||||||
|
logger.Fatalf("cannot stop http server for metrics: %s", err)
|
||||||
|
}
|
||||||
|
logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeBackup() error {
|
||||||
|
if err := snapshot.Validate(*snapshotName); err != nil {
|
||||||
|
return fmt.Errorf("invalid -snapshotName=%q: %s", *snapshotName, err)
|
||||||
|
}
|
||||||
|
|
||||||
srcFS, err := newSrcFS()
|
srcFS, err := newSrcFS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("%s", err)
|
return err
|
||||||
}
|
}
|
||||||
dstFS, err := newDstFS()
|
dstFS, err := newDstFS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("%s", err)
|
return err
|
||||||
}
|
}
|
||||||
originFS, err := newOriginFS()
|
originFS, err := newOriginFS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("%s", err)
|
return err
|
||||||
}
|
}
|
||||||
a := &actions.Backup{
|
a := &actions.Backup{
|
||||||
Concurrency: *concurrency,
|
Concurrency: *concurrency,
|
||||||
@@ -114,18 +136,12 @@ func main() {
|
|||||||
Origin: originFS,
|
Origin: originFS,
|
||||||
}
|
}
|
||||||
if err := a.Run(); err != nil {
|
if err := a.Run(); err != nil {
|
||||||
logger.Fatalf("cannot create backup: %s", err)
|
return err
|
||||||
}
|
}
|
||||||
srcFS.MustStop()
|
srcFS.MustStop()
|
||||||
dstFS.MustStop()
|
dstFS.MustStop()
|
||||||
originFS.MustStop()
|
originFS.MustStop()
|
||||||
|
return nil
|
||||||
startTime := time.Now()
|
|
||||||
logger.Infof("gracefully shutting down http server for metrics at %q", *httpListenAddr)
|
|
||||||
if err := httpserver.Stop(*httpListenAddr); err != nil {
|
|
||||||
logger.Fatalf("cannot stop http server for metrics: %s", err)
|
|
||||||
}
|
|
||||||
logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func usage() {
|
func usage() {
|
||||||
@@ -189,7 +205,20 @@ func hasFilepathPrefix(path, prefix string) bool {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return strings.HasPrefix(pathAbs, prefixAbs)
|
if prefixAbs == pathAbs {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
rel, err := filepath.Rel(prefixAbs, pathAbs)
|
||||||
|
if err != nil {
|
||||||
|
// if paths can't be related - they don't match
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if i := strings.Index(rel, "."); i == 0 {
|
||||||
|
// if path can be related only with . as first char - they still don't match
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// if paths are related - it is a match
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOriginFS() (common.OriginFS, error) {
|
func newOriginFS() (common.OriginFS, error) {
|
||||||
|
|||||||
@@ -26,4 +26,9 @@ func TestHasFilepathPrefix(t *testing.T) {
|
|||||||
f("fs://"+pwd+"/foo", pwd+"/foo/bar", false)
|
f("fs://"+pwd+"/foo", pwd+"/foo/bar", false)
|
||||||
f("fs://"+pwd+"/foo/bar", pwd+"/foo", true)
|
f("fs://"+pwd+"/foo/bar", pwd+"/foo", true)
|
||||||
f("fs://"+pwd+"/foo", pwd+"/bar", false)
|
f("fs://"+pwd+"/foo", pwd+"/bar", false)
|
||||||
|
f("fs:///data1", "/data", false)
|
||||||
|
f("fs:///data", "/data1", false)
|
||||||
|
f("fs:///data", "/data/foo", false)
|
||||||
|
f("fs:///data/foo", "/data", true)
|
||||||
|
f("fs:///data/foo/", "/data/", true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -434,9 +434,10 @@ var (
|
|||||||
Value: 1,
|
Value: 1,
|
||||||
},
|
},
|
||||||
&cli.TimestampFlag{
|
&cli.TimestampFlag{
|
||||||
Name: remoteReadFilterTimeStart,
|
Name: remoteReadFilterTimeStart,
|
||||||
Usage: "The time filter in RFC3339 format to select timeseries with timestamp equal or higher than provided value. E.g. '2020-01-01T20:07:00Z'",
|
Usage: "The time filter in RFC3339 format to select timeseries with timestamp equal or higher than provided value. E.g. '2020-01-01T20:07:00Z'",
|
||||||
Layout: time.RFC3339,
|
Layout: time.RFC3339,
|
||||||
|
Required: true,
|
||||||
},
|
},
|
||||||
&cli.TimestampFlag{
|
&cli.TimestampFlag{
|
||||||
Name: remoteReadFilterTimeEnd,
|
Name: remoteReadFilterTimeEnd,
|
||||||
|
|||||||
@@ -153,6 +153,10 @@ func (c *Client) Explore() ([]*Series, error) {
|
|||||||
return nil, fmt.Errorf("failed to get field keys: %s", err)
|
return nil, fmt.Errorf("failed to get field keys: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(mFields) < 1 {
|
||||||
|
return nil, fmt.Errorf("found no numeric fields for import in database %q", c.database)
|
||||||
|
}
|
||||||
|
|
||||||
series, err := c.getSeries()
|
series, err := c.getSeries()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get series: %s", err)
|
return nil, fmt.Errorf("failed to get series: %s", err)
|
||||||
@@ -162,7 +166,8 @@ func (c *Client) Explore() ([]*Series, error) {
|
|||||||
for _, s := range series {
|
for _, s := range series {
|
||||||
fields, ok := mFields[s.Measurement]
|
fields, ok := mFields[s.Measurement]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("can't find field keys for measurement %q", s.Measurement)
|
log.Printf("skip measurement %q since it has no fields", s.Measurement)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
is := &Series{
|
is := &Series{
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ func modifyData(msg Metric, normalize bool) (Metric, error) {
|
|||||||
/*
|
/*
|
||||||
replace bad characters in metric name with _ per the data model
|
replace bad characters in metric name with _ per the data model
|
||||||
*/
|
*/
|
||||||
finalMsg.Metric = promrelabel.SanitizeName(name)
|
finalMsg.Metric = promrelabel.SanitizeMetricName(name)
|
||||||
// replace bad characters in tag keys with _ per the data model
|
// replace bad characters in tag keys with _ per the data model
|
||||||
for key, value := range msg.Tags {
|
for key, value := range msg.Tags {
|
||||||
// if normalization requested, lowercase the key and value
|
// if normalization requested, lowercase the key and value
|
||||||
@@ -191,7 +191,7 @@ func modifyData(msg Metric, normalize bool) (Metric, error) {
|
|||||||
/*
|
/*
|
||||||
replace all explicitly bad characters with _
|
replace all explicitly bad characters with _
|
||||||
*/
|
*/
|
||||||
key = promrelabel.SanitizeName(key)
|
key = promrelabel.SanitizeLabelName(key)
|
||||||
// tags that start with __ are considered custom stats for internal prometheus stuff, we should drop them
|
// tags that start with __ are considered custom stats for internal prometheus stuff, we should drop them
|
||||||
if !strings.HasPrefix(key, "__") {
|
if !strings.HasPrefix(key, "__") {
|
||||||
finalMsg.Tags[key] = value
|
finalMsg.Tags[key] = value
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ func pushAggregateSeries(tss []prompbmarshal.TimeSeries) {
|
|||||||
ctx.skipStreamAggr = true
|
ctx.skipStreamAggr = true
|
||||||
for _, ts := range tss {
|
for _, ts := range tss {
|
||||||
labels := ts.Labels
|
labels := ts.Labels
|
||||||
|
ctx.Labels = ctx.Labels[:0]
|
||||||
for _, label := range labels {
|
for _, label := range labels {
|
||||||
name := label.Name
|
name := label.Name
|
||||||
if name == "__name__" {
|
if name == "__name__" {
|
||||||
|
|||||||
@@ -128,9 +128,9 @@ func (ctx *Ctx) ApplyRelabeling(labels []prompb.Label) []prompb.Label {
|
|||||||
for i := range tmpLabels {
|
for i := range tmpLabels {
|
||||||
label := &tmpLabels[i]
|
label := &tmpLabels[i]
|
||||||
if label.Name == "__name__" {
|
if label.Name == "__name__" {
|
||||||
label.Value = promrelabel.SanitizeName(label.Value)
|
label.Value = promrelabel.SanitizeMetricName(label.Value)
|
||||||
} else {
|
} else {
|
||||||
label.Name = promrelabel.SanitizeName(label.Name)
|
label.Name = promrelabel.SanitizeLabelName(label.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,6 +114,13 @@ func RequestHandler(w http.ResponseWriter, r *http.Request) bool {
|
|||||||
timerpool.Put(t)
|
timerpool.Put(t)
|
||||||
qt.Printf("wait in queue because -search.maxConcurrentRequests=%d concurrent requests are executed", *maxConcurrentRequests)
|
qt.Printf("wait in queue because -search.maxConcurrentRequests=%d concurrent requests are executed", *maxConcurrentRequests)
|
||||||
defer func() { <-concurrencyLimitCh }()
|
defer func() { <-concurrencyLimitCh }()
|
||||||
|
case <-r.Context().Done():
|
||||||
|
timerpool.Put(t)
|
||||||
|
remoteAddr := httpserver.GetQuotedRemoteAddr(r)
|
||||||
|
requestURI := httpserver.GetRequestURI(r)
|
||||||
|
logger.Infof("client has cancelled the request after %.3f seconds: remoteAddr=%s, requestURI: %q",
|
||||||
|
d.Seconds(), remoteAddr, requestURI)
|
||||||
|
return true
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
timerpool.Put(t)
|
timerpool.Put(t)
|
||||||
concurrencyLimitTimeout.Inc()
|
concurrencyLimitTimeout.Inc()
|
||||||
|
|||||||
@@ -148,40 +148,31 @@ func timeseriesWorker(qt *querytracer.Tracer, workChs []chan *timeseriesWork, wo
|
|||||||
// Then help others with the remaining work.
|
// Then help others with the remaining work.
|
||||||
rowsProcessed = 0
|
rowsProcessed = 0
|
||||||
seriesProcessed = 0
|
seriesProcessed = 0
|
||||||
idx := int(workerID)
|
for i := uint(1); i < uint(len(workChs)); i++ {
|
||||||
for {
|
idx := (i + workerID) % uint(len(workChs))
|
||||||
tsw, idxNext := stealTimeseriesWork(workChs, idx)
|
ch := workChs[idx]
|
||||||
if tsw == nil {
|
for len(ch) > 0 {
|
||||||
// There is no more work
|
// Do not call runtime.Gosched() here in order to give a chance
|
||||||
break
|
// the real owner of the work to complete it, since it consumes additional CPU
|
||||||
|
// and slows down the code on systems with big number of CPU cores.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3966#issuecomment-1483208419
|
||||||
|
|
||||||
|
// It is expected that every channel in the workChs is already closed,
|
||||||
|
// so the next line should return immediately.
|
||||||
|
tsw, ok := <-ch
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
tsw.err = tsw.do(&tmpResult.rs, workerID)
|
||||||
|
rowsProcessed += tsw.rowsProcessed
|
||||||
|
seriesProcessed++
|
||||||
}
|
}
|
||||||
tsw.err = tsw.do(&tmpResult.rs, workerID)
|
|
||||||
rowsProcessed += tsw.rowsProcessed
|
|
||||||
seriesProcessed++
|
|
||||||
idx = idxNext
|
|
||||||
}
|
}
|
||||||
qt.Printf("others work processed: series=%d, samples=%d", seriesProcessed, rowsProcessed)
|
qt.Printf("others work processed: series=%d, samples=%d", seriesProcessed, rowsProcessed)
|
||||||
|
|
||||||
putTmpResult(tmpResult)
|
putTmpResult(tmpResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func stealTimeseriesWork(workChs []chan *timeseriesWork, startIdx int) (*timeseriesWork, int) {
|
|
||||||
for i := startIdx; i < startIdx+len(workChs); i++ {
|
|
||||||
// Give a chance other goroutines to perform their work
|
|
||||||
runtime.Gosched()
|
|
||||||
|
|
||||||
idx := i % len(workChs)
|
|
||||||
ch := workChs[idx]
|
|
||||||
// It is expected that every channel in the workChs is already closed,
|
|
||||||
// so the next line should return immediately.
|
|
||||||
tsw, ok := <-ch
|
|
||||||
if ok {
|
|
||||||
return tsw, idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, startIdx
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTmpResult() *result {
|
func getTmpResult() *result {
|
||||||
v := resultPool.Get()
|
v := resultPool.Get()
|
||||||
if v == nil {
|
if v == nil {
|
||||||
@@ -207,10 +198,17 @@ type result struct {
|
|||||||
|
|
||||||
var resultPool sync.Pool
|
var resultPool sync.Pool
|
||||||
|
|
||||||
|
// MaxWorkers returns the maximum number of workers netstorage can spin when calling RunParallel()
|
||||||
|
func MaxWorkers() int {
|
||||||
|
return gomaxprocs
|
||||||
|
}
|
||||||
|
|
||||||
|
var gomaxprocs = cgroup.AvailableCPUs()
|
||||||
|
|
||||||
// RunParallel runs f in parallel for all the results from rss.
|
// RunParallel runs f in parallel for all the results from rss.
|
||||||
//
|
//
|
||||||
// f shouldn't hold references to rs after returning.
|
// f shouldn't hold references to rs after returning.
|
||||||
// workerID is the id of the worker goroutine that calls f.
|
// workerID is the id of the worker goroutine that calls f. The workerID is in the range [0..MaxWorkers()-1].
|
||||||
// Data processing is immediately stopped if f returns non-nil error.
|
// Data processing is immediately stopped if f returns non-nil error.
|
||||||
//
|
//
|
||||||
// rss becomes unusable after the call to RunParallel.
|
// rss becomes unusable after the call to RunParallel.
|
||||||
@@ -244,7 +242,8 @@ func (rss *Results) runParallel(qt *querytracer.Tracer, f func(rs *Result, worke
|
|||||||
tsw.f = f
|
tsw.f = f
|
||||||
tsw.mustStop = &mustStop
|
tsw.mustStop = &mustStop
|
||||||
}
|
}
|
||||||
if gomaxprocs == 1 || tswsLen == 1 {
|
maxWorkers := MaxWorkers()
|
||||||
|
if maxWorkers == 1 || tswsLen == 1 {
|
||||||
// It is faster to process time series in the current goroutine.
|
// It is faster to process time series in the current goroutine.
|
||||||
tsw := getTimeseriesWork()
|
tsw := getTimeseriesWork()
|
||||||
tmpResult := getTmpResult()
|
tmpResult := getTmpResult()
|
||||||
@@ -280,8 +279,8 @@ func (rss *Results) runParallel(qt *querytracer.Tracer, f func(rs *Result, worke
|
|||||||
|
|
||||||
// Prepare worker channels.
|
// Prepare worker channels.
|
||||||
workers := len(tsws)
|
workers := len(tsws)
|
||||||
if workers > gomaxprocs {
|
if workers > maxWorkers {
|
||||||
workers = gomaxprocs
|
workers = maxWorkers
|
||||||
}
|
}
|
||||||
itemsPerWorker := (len(tsws) + workers - 1) / workers
|
itemsPerWorker := (len(tsws) + workers - 1) / workers
|
||||||
workChs := make([]chan *timeseriesWork, workers)
|
workChs := make([]chan *timeseriesWork, workers)
|
||||||
@@ -333,8 +332,6 @@ var (
|
|||||||
seriesReadPerQuery = metrics.NewHistogram(`vm_series_read_per_query`)
|
seriesReadPerQuery = metrics.NewHistogram(`vm_series_read_per_query`)
|
||||||
)
|
)
|
||||||
|
|
||||||
var gomaxprocs = cgroup.AvailableCPUs()
|
|
||||||
|
|
||||||
type packedTimeseries struct {
|
type packedTimeseries struct {
|
||||||
metricName string
|
metricName string
|
||||||
brs []blockRef
|
brs []blockRef
|
||||||
@@ -391,37 +388,25 @@ func unpackWorker(workChs []chan *unpackWork, workerID uint) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Then help others with their work.
|
// Then help others with their work.
|
||||||
idx := int(workerID)
|
for i := uint(1); i < uint(len(workChs)); i++ {
|
||||||
for {
|
idx := (i + workerID) % uint(len(workChs))
|
||||||
upw, idxNext := stealUnpackWork(workChs, idx)
|
ch := workChs[idx]
|
||||||
if upw == nil {
|
for len(ch) > 0 {
|
||||||
// There is no more work
|
// Give a chance other goroutines to perform their work
|
||||||
break
|
runtime.Gosched()
|
||||||
|
// It is expected that every channel in the workChs is already closed,
|
||||||
|
// so the next line should return immediately.
|
||||||
|
upw, ok := <-ch
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
upw.unpack(tmpBlock)
|
||||||
}
|
}
|
||||||
upw.unpack(tmpBlock)
|
|
||||||
idx = idxNext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
putTmpStorageBlock(tmpBlock)
|
putTmpStorageBlock(tmpBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func stealUnpackWork(workChs []chan *unpackWork, startIdx int) (*unpackWork, int) {
|
|
||||||
for i := startIdx; i < startIdx+len(workChs); i++ {
|
|
||||||
// Give a chance other goroutines to perform their work
|
|
||||||
runtime.Gosched()
|
|
||||||
|
|
||||||
idx := i % len(workChs)
|
|
||||||
ch := workChs[idx]
|
|
||||||
// It is expected that every channel in the workChs is already closed,
|
|
||||||
// so the next line should return immediately.
|
|
||||||
upw, ok := <-ch
|
|
||||||
if ok {
|
|
||||||
return upw, idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, startIdx
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTmpStorageBlock() *storage.Block {
|
func getTmpStorageBlock() *storage.Block {
|
||||||
v := tmpStorageBlockPool.Get()
|
v := tmpStorageBlockPool.Get()
|
||||||
if v == nil {
|
if v == nil {
|
||||||
@@ -1017,7 +1002,6 @@ func ExportBlocks(qt *querytracer.Tracer, sq *storage.SearchQuery, deadline sear
|
|||||||
indexSearchDuration.UpdateDuration(startTime)
|
indexSearchDuration.UpdateDuration(startTime)
|
||||||
|
|
||||||
// Start workers that call f in parallel on available CPU cores.
|
// Start workers that call f in parallel on available CPU cores.
|
||||||
gomaxprocs := cgroup.AvailableCPUs()
|
|
||||||
workCh := make(chan *exportWork, gomaxprocs*8)
|
workCh := make(chan *exportWork, gomaxprocs*8)
|
||||||
var (
|
var (
|
||||||
errGlobal error
|
errGlobal error
|
||||||
@@ -1187,8 +1171,10 @@ func ProcessSearchQuery(qt *querytracer.Tracer, sq *storage.SearchQuery, deadlin
|
|||||||
putStorageSearch(sr)
|
putStorageSearch(sr)
|
||||||
return nil, fmt.Errorf("cannot write %d bytes to temporary file: %w", len(buf), err)
|
return nil, fmt.Errorf("cannot write %d bytes to temporary file: %w", len(buf), err)
|
||||||
}
|
}
|
||||||
metricName := bytesutil.InternBytes(sr.MetricBlockRef.MetricName)
|
// Do not intern mb.MetricName, since it leads to increased memory usage.
|
||||||
brs := m[metricName]
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3692
|
||||||
|
metricName := sr.MetricBlockRef.MetricName
|
||||||
|
brs := m[string(metricName)]
|
||||||
if brs == nil {
|
if brs == nil {
|
||||||
brs = &blockRefs{}
|
brs = &blockRefs{}
|
||||||
brs.brs = brs.brsPrealloc[:0]
|
brs.brs = brs.brsPrealloc[:0]
|
||||||
@@ -1198,8 +1184,9 @@ func ProcessSearchQuery(qt *querytracer.Tracer, sq *storage.SearchQuery, deadlin
|
|||||||
addr: addr,
|
addr: addr,
|
||||||
})
|
})
|
||||||
if len(brs.brs) == 1 {
|
if len(brs.brs) == 1 {
|
||||||
orderedMetricNames = append(orderedMetricNames, metricName)
|
metricNameStr := string(metricName)
|
||||||
m[metricName] = brs
|
orderedMetricNames = append(orderedMetricNames, metricNameStr)
|
||||||
|
m[metricNameStr] = brs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := sr.Error(); err != nil {
|
if err := sr.Error(); err != nil {
|
||||||
|
|||||||
@@ -142,6 +142,9 @@ func (tbf *tmpBlocksFile) Finalize() error {
|
|||||||
// This should reduce the number of disk seeks, which is important
|
// This should reduce the number of disk seeks, which is important
|
||||||
// for HDDs.
|
// for HDDs.
|
||||||
r.MustFadviseSequentialRead(true)
|
r.MustFadviseSequentialRead(true)
|
||||||
|
// Collect local stats in order to improve performance on systems with big number of CPU cores.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3966
|
||||||
|
r.SetUseLocalStats()
|
||||||
tbf.r = r
|
tbf.r = r
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ package promql
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
||||||
"github.com/VictoriaMetrics/metricsql"
|
"github.com/VictoriaMetrics/metricsql"
|
||||||
)
|
)
|
||||||
@@ -63,31 +64,36 @@ var incrementalAggrFuncCallbacksMap = map[string]*incrementalAggrFuncCallbacks{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type incrementalAggrContextMap struct {
|
||||||
|
m map[string]*incrementalAggrContext
|
||||||
|
|
||||||
|
// The padding prevents false sharing on widespread platforms with
|
||||||
|
// 128 mod (cache line size) = 0 .
|
||||||
|
_ [128 - unsafe.Sizeof(map[string]*incrementalAggrContext{})%128]byte
|
||||||
|
}
|
||||||
|
|
||||||
type incrementalAggrFuncContext struct {
|
type incrementalAggrFuncContext struct {
|
||||||
ae *metricsql.AggrFuncExpr
|
ae *metricsql.AggrFuncExpr
|
||||||
|
|
||||||
m sync.Map
|
byWorkerID []incrementalAggrContextMap
|
||||||
|
|
||||||
callbacks *incrementalAggrFuncCallbacks
|
callbacks *incrementalAggrFuncCallbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
func newIncrementalAggrFuncContext(ae *metricsql.AggrFuncExpr, callbacks *incrementalAggrFuncCallbacks) *incrementalAggrFuncContext {
|
func newIncrementalAggrFuncContext(ae *metricsql.AggrFuncExpr, callbacks *incrementalAggrFuncCallbacks) *incrementalAggrFuncContext {
|
||||||
return &incrementalAggrFuncContext{
|
return &incrementalAggrFuncContext{
|
||||||
ae: ae,
|
ae: ae,
|
||||||
callbacks: callbacks,
|
byWorkerID: make([]incrementalAggrContextMap, netstorage.MaxWorkers()),
|
||||||
|
callbacks: callbacks,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iafc *incrementalAggrFuncContext) updateTimeseries(tsOrig *timeseries, workerID uint) {
|
func (iafc *incrementalAggrFuncContext) updateTimeseries(tsOrig *timeseries, workerID uint) {
|
||||||
v, ok := iafc.m.Load(workerID)
|
v := &iafc.byWorkerID[workerID]
|
||||||
if !ok {
|
if v.m == nil {
|
||||||
// It is safe creating and storing m in iafc.m without locking,
|
v.m = make(map[string]*incrementalAggrContext, 1)
|
||||||
// since it is guaranteed that only a single goroutine can execute
|
|
||||||
// code for the given workerID at a time.
|
|
||||||
v = make(map[string]*incrementalAggrContext, 1)
|
|
||||||
iafc.m.Store(workerID, v)
|
|
||||||
}
|
}
|
||||||
m := v.(map[string]*incrementalAggrContext)
|
m := v.m
|
||||||
|
|
||||||
ts := tsOrig
|
ts := tsOrig
|
||||||
keepOriginal := iafc.callbacks.keepOriginal
|
keepOriginal := iafc.callbacks.keepOriginal
|
||||||
@@ -128,9 +134,9 @@ func (iafc *incrementalAggrFuncContext) updateTimeseries(tsOrig *timeseries, wor
|
|||||||
func (iafc *incrementalAggrFuncContext) finalizeTimeseries() []*timeseries {
|
func (iafc *incrementalAggrFuncContext) finalizeTimeseries() []*timeseries {
|
||||||
mGlobal := make(map[string]*incrementalAggrContext)
|
mGlobal := make(map[string]*incrementalAggrContext)
|
||||||
mergeAggrFunc := iafc.callbacks.mergeAggrFunc
|
mergeAggrFunc := iafc.callbacks.mergeAggrFunc
|
||||||
iafc.m.Range(func(k, v interface{}) bool {
|
byWorkerID := iafc.byWorkerID
|
||||||
m := v.(map[string]*incrementalAggrContext)
|
for i := range byWorkerID {
|
||||||
for k, iac := range m {
|
for k, iac := range byWorkerID[i].m {
|
||||||
iacGlobal := mGlobal[k]
|
iacGlobal := mGlobal[k]
|
||||||
if iacGlobal == nil {
|
if iacGlobal == nil {
|
||||||
if iafc.ae.Limit > 0 && len(mGlobal) >= iafc.ae.Limit {
|
if iafc.ae.Limit > 0 && len(mGlobal) >= iafc.ae.Limit {
|
||||||
@@ -142,8 +148,7 @@ func (iafc *incrementalAggrFuncContext) finalizeTimeseries() []*timeseries {
|
|||||||
}
|
}
|
||||||
mergeAggrFunc(iacGlobal, iac)
|
mergeAggrFunc(iacGlobal, iac)
|
||||||
}
|
}
|
||||||
return true
|
}
|
||||||
})
|
|
||||||
tss := make([]*timeseries, 0, len(mGlobal))
|
tss := make([]*timeseries, 0, len(mGlobal))
|
||||||
finalizeAggrFunc := iafc.callbacks.finalizeAggrFunc
|
finalizeAggrFunc := iafc.callbacks.finalizeAggrFunc
|
||||||
for _, iac := range mGlobal {
|
for _, iac := range mGlobal {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage"
|
||||||
"github.com/VictoriaMetrics/metricsql"
|
"github.com/VictoriaMetrics/metricsql"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -99,7 +100,7 @@ func TestIncrementalAggr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testIncrementalParallelAggr(iafc *incrementalAggrFuncContext, tssSrc, tssExpected []*timeseries) error {
|
func testIncrementalParallelAggr(iafc *incrementalAggrFuncContext, tssSrc, tssExpected []*timeseries) error {
|
||||||
const workersCount = 3
|
workersCount := netstorage.MaxWorkers()
|
||||||
tsCh := make(chan *timeseries)
|
tsCh := make(chan *timeseries)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(workersCount)
|
wg.Add(workersCount)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/searchutils"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/searchutils"
|
||||||
@@ -893,31 +894,34 @@ func evalRollupFuncWithSubquery(qt *querytracer.Tracer, ec *EvalConfig, funcName
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tss := make([]*timeseries, 0, len(tssSQ)*len(rcs))
|
|
||||||
var tssLock sync.Mutex
|
|
||||||
var samplesScannedTotal uint64
|
var samplesScannedTotal uint64
|
||||||
keepMetricNames := getKeepMetricNames(expr)
|
keepMetricNames := getKeepMetricNames(expr)
|
||||||
doParallel(tssSQ, func(tsSQ *timeseries, values []float64, timestamps []int64) ([]float64, []int64) {
|
tsw := getTimeseriesByWorkerID()
|
||||||
|
seriesByWorkerID := tsw.byWorkerID
|
||||||
|
doParallel(tssSQ, func(tsSQ *timeseries, values []float64, timestamps []int64, workerID uint) ([]float64, []int64) {
|
||||||
values, timestamps = removeNanValues(values[:0], timestamps[:0], tsSQ.Values, tsSQ.Timestamps)
|
values, timestamps = removeNanValues(values[:0], timestamps[:0], tsSQ.Values, tsSQ.Timestamps)
|
||||||
preFunc(values, timestamps)
|
preFunc(values, timestamps)
|
||||||
for _, rc := range rcs {
|
for _, rc := range rcs {
|
||||||
if tsm := newTimeseriesMap(funcName, keepMetricNames, sharedTimestamps, &tsSQ.MetricName); tsm != nil {
|
if tsm := newTimeseriesMap(funcName, keepMetricNames, sharedTimestamps, &tsSQ.MetricName); tsm != nil {
|
||||||
samplesScanned := rc.DoTimeseriesMap(tsm, values, timestamps)
|
samplesScanned := rc.DoTimeseriesMap(tsm, values, timestamps)
|
||||||
atomic.AddUint64(&samplesScannedTotal, samplesScanned)
|
atomic.AddUint64(&samplesScannedTotal, samplesScanned)
|
||||||
tssLock.Lock()
|
seriesByWorkerID[workerID].tss = tsm.AppendTimeseriesTo(seriesByWorkerID[workerID].tss)
|
||||||
tss = tsm.AppendTimeseriesTo(tss)
|
|
||||||
tssLock.Unlock()
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var ts timeseries
|
var ts timeseries
|
||||||
samplesScanned := doRollupForTimeseries(funcName, keepMetricNames, rc, &ts, &tsSQ.MetricName, values, timestamps, sharedTimestamps)
|
samplesScanned := doRollupForTimeseries(funcName, keepMetricNames, rc, &ts, &tsSQ.MetricName, values, timestamps, sharedTimestamps)
|
||||||
atomic.AddUint64(&samplesScannedTotal, samplesScanned)
|
atomic.AddUint64(&samplesScannedTotal, samplesScanned)
|
||||||
tssLock.Lock()
|
seriesByWorkerID[workerID].tss = append(seriesByWorkerID[workerID].tss, &ts)
|
||||||
tss = append(tss, &ts)
|
|
||||||
tssLock.Unlock()
|
|
||||||
}
|
}
|
||||||
return values, timestamps
|
return values, timestamps
|
||||||
})
|
})
|
||||||
|
tss := make([]*timeseries, 0, len(tssSQ)*len(rcs))
|
||||||
|
for i := range seriesByWorkerID {
|
||||||
|
tss = append(tss, seriesByWorkerID[i].tss...)
|
||||||
|
}
|
||||||
|
putTimeseriesByWorkerID(tsw)
|
||||||
|
|
||||||
rowsScannedPerQuery.Update(float64(samplesScannedTotal))
|
rowsScannedPerQuery.Update(float64(samplesScannedTotal))
|
||||||
qt.Printf("rollup %s() over %d series returned by subquery: series=%d, samplesScanned=%d", funcName, len(tssSQ), len(tss), samplesScannedTotal)
|
qt.Printf("rollup %s() over %d series returned by subquery: series=%d, samplesScanned=%d", funcName, len(tssSQ), len(tss), samplesScannedTotal)
|
||||||
return tss, nil
|
return tss, nil
|
||||||
@@ -941,28 +945,36 @@ func getKeepMetricNames(expr metricsql.Expr) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func doParallel(tss []*timeseries, f func(ts *timeseries, values []float64, timestamps []int64) ([]float64, []int64)) {
|
func doParallel(tss []*timeseries, f func(ts *timeseries, values []float64, timestamps []int64, workerID uint) ([]float64, []int64)) {
|
||||||
concurrency := cgroup.AvailableCPUs()
|
workers := netstorage.MaxWorkers()
|
||||||
if concurrency > len(tss) {
|
if workers > len(tss) {
|
||||||
concurrency = len(tss)
|
workers = len(tss)
|
||||||
}
|
}
|
||||||
workCh := make(chan *timeseries, concurrency)
|
seriesPerWorker := (len(tss) + workers - 1) / workers
|
||||||
|
workChs := make([]chan *timeseries, workers)
|
||||||
|
for i := range workChs {
|
||||||
|
workChs[i] = make(chan *timeseries, seriesPerWorker)
|
||||||
|
}
|
||||||
|
for i, ts := range tss {
|
||||||
|
idx := i % len(workChs)
|
||||||
|
workChs[idx] <- ts
|
||||||
|
}
|
||||||
|
for _, workCh := range workChs {
|
||||||
|
close(workCh)
|
||||||
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(concurrency)
|
wg.Add(workers)
|
||||||
for i := 0; i < concurrency; i++ {
|
for i := 0; i < workers; i++ {
|
||||||
go func() {
|
go func(workerID uint) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
var tmpValues []float64
|
var tmpValues []float64
|
||||||
var tmpTimestamps []int64
|
var tmpTimestamps []int64
|
||||||
for ts := range workCh {
|
for ts := range workChs[workerID] {
|
||||||
tmpValues, tmpTimestamps = f(ts, tmpValues, tmpTimestamps)
|
tmpValues, tmpTimestamps = f(ts, tmpValues, tmpTimestamps, workerID)
|
||||||
}
|
}
|
||||||
}()
|
}(uint(i))
|
||||||
}
|
}
|
||||||
for _, ts := range tss {
|
|
||||||
workCh <- ts
|
|
||||||
}
|
|
||||||
close(workCh)
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,6 +1053,9 @@ func evalRollupFuncWithMetricExpr(qt *querytracer.Tracer, ec *EvalConfig, funcNa
|
|||||||
} else {
|
} else {
|
||||||
minTimestamp -= ec.Step
|
minTimestamp -= ec.Step
|
||||||
}
|
}
|
||||||
|
if minTimestamp < 0 {
|
||||||
|
minTimestamp = 0
|
||||||
|
}
|
||||||
sq := storage.NewSearchQuery(minTimestamp, ec.End, tfss, ec.MaxSeries)
|
sq := storage.NewSearchQuery(minTimestamp, ec.End, tfss, ec.MaxSeries)
|
||||||
rss, err := netstorage.ProcessSearchQuery(qt, sq, ec.Deadline)
|
rss, err := netstorage.ProcessSearchQuery(qt, sq, ec.Deadline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1177,9 +1192,11 @@ func evalRollupNoIncrementalAggregate(qt *querytracer.Tracer, funcName string, k
|
|||||||
preFunc func(values []float64, timestamps []int64), sharedTimestamps []int64) ([]*timeseries, error) {
|
preFunc func(values []float64, timestamps []int64), sharedTimestamps []int64) ([]*timeseries, error) {
|
||||||
qt = qt.NewChild("rollup %s() over %d series; rollupConfigs=%s", funcName, rss.Len(), rcs)
|
qt = qt.NewChild("rollup %s() over %d series; rollupConfigs=%s", funcName, rss.Len(), rcs)
|
||||||
defer qt.Done()
|
defer qt.Done()
|
||||||
tss := make([]*timeseries, 0, rss.Len()*len(rcs))
|
|
||||||
var tssLock sync.Mutex
|
|
||||||
var samplesScannedTotal uint64
|
var samplesScannedTotal uint64
|
||||||
|
tsw := getTimeseriesByWorkerID()
|
||||||
|
seriesByWorkerID := tsw.byWorkerID
|
||||||
|
seriesLen := rss.Len()
|
||||||
err := rss.RunParallel(qt, func(rs *netstorage.Result, workerID uint) error {
|
err := rss.RunParallel(qt, func(rs *netstorage.Result, workerID uint) error {
|
||||||
rs.Values, rs.Timestamps = dropStaleNaNs(funcName, rs.Values, rs.Timestamps)
|
rs.Values, rs.Timestamps = dropStaleNaNs(funcName, rs.Values, rs.Timestamps)
|
||||||
preFunc(rs.Values, rs.Timestamps)
|
preFunc(rs.Values, rs.Timestamps)
|
||||||
@@ -1187,23 +1204,25 @@ func evalRollupNoIncrementalAggregate(qt *querytracer.Tracer, funcName string, k
|
|||||||
if tsm := newTimeseriesMap(funcName, keepMetricNames, sharedTimestamps, &rs.MetricName); tsm != nil {
|
if tsm := newTimeseriesMap(funcName, keepMetricNames, sharedTimestamps, &rs.MetricName); tsm != nil {
|
||||||
samplesScanned := rc.DoTimeseriesMap(tsm, rs.Values, rs.Timestamps)
|
samplesScanned := rc.DoTimeseriesMap(tsm, rs.Values, rs.Timestamps)
|
||||||
atomic.AddUint64(&samplesScannedTotal, samplesScanned)
|
atomic.AddUint64(&samplesScannedTotal, samplesScanned)
|
||||||
tssLock.Lock()
|
seriesByWorkerID[workerID].tss = tsm.AppendTimeseriesTo(seriesByWorkerID[workerID].tss)
|
||||||
tss = tsm.AppendTimeseriesTo(tss)
|
|
||||||
tssLock.Unlock()
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var ts timeseries
|
var ts timeseries
|
||||||
samplesScanned := doRollupForTimeseries(funcName, keepMetricNames, rc, &ts, &rs.MetricName, rs.Values, rs.Timestamps, sharedTimestamps)
|
samplesScanned := doRollupForTimeseries(funcName, keepMetricNames, rc, &ts, &rs.MetricName, rs.Values, rs.Timestamps, sharedTimestamps)
|
||||||
atomic.AddUint64(&samplesScannedTotal, samplesScanned)
|
atomic.AddUint64(&samplesScannedTotal, samplesScanned)
|
||||||
tssLock.Lock()
|
seriesByWorkerID[workerID].tss = append(seriesByWorkerID[workerID].tss, &ts)
|
||||||
tss = append(tss, &ts)
|
|
||||||
tssLock.Unlock()
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
tss := make([]*timeseries, 0, seriesLen*len(rcs))
|
||||||
|
for i := range seriesByWorkerID {
|
||||||
|
tss = append(tss, seriesByWorkerID[i].tss...)
|
||||||
|
}
|
||||||
|
putTimeseriesByWorkerID(tsw)
|
||||||
|
|
||||||
rowsScannedPerQuery.Update(float64(samplesScannedTotal))
|
rowsScannedPerQuery.Update(float64(samplesScannedTotal))
|
||||||
qt.Printf("samplesScanned=%d", samplesScannedTotal)
|
qt.Printf("samplesScanned=%d", samplesScannedTotal)
|
||||||
return tss, nil
|
return tss, nil
|
||||||
@@ -1225,6 +1244,42 @@ func doRollupForTimeseries(funcName string, keepMetricNames bool, rc *rollupConf
|
|||||||
return samplesScanned
|
return samplesScanned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type timeseriesWithPadding struct {
|
||||||
|
tss []*timeseries
|
||||||
|
|
||||||
|
// The padding prevents false sharing on widespread platforms with
|
||||||
|
// 128 mod (cache line size) = 0 .
|
||||||
|
_ [128 - unsafe.Sizeof([]*timeseries{})%128]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type timeseriesByWorkerID struct {
|
||||||
|
byWorkerID []timeseriesWithPadding
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tsw *timeseriesByWorkerID) reset() {
|
||||||
|
byWorkerID := tsw.byWorkerID
|
||||||
|
for i := range byWorkerID {
|
||||||
|
byWorkerID[i].tss = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTimeseriesByWorkerID() *timeseriesByWorkerID {
|
||||||
|
v := timeseriesByWorkerIDPool.Get()
|
||||||
|
if v == nil {
|
||||||
|
return ×eriesByWorkerID{
|
||||||
|
byWorkerID: make([]timeseriesWithPadding, netstorage.MaxWorkers()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v.(*timeseriesByWorkerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func putTimeseriesByWorkerID(tsw *timeseriesByWorkerID) {
|
||||||
|
tsw.reset()
|
||||||
|
timeseriesByWorkerIDPool.Put(tsw)
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeseriesByWorkerIDPool sync.Pool
|
||||||
|
|
||||||
var bbPool bytesutil.ByteBufferPool
|
var bbPool bytesutil.ByteBufferPool
|
||||||
|
|
||||||
func evalNumber(ec *EvalConfig, n float64) []*timeseries {
|
func evalNumber(ec *EvalConfig, n float64) []*timeseries {
|
||||||
|
|||||||
@@ -6122,7 +6122,7 @@ func TestExecSuccess(t *testing.T) {
|
|||||||
q := `interpolate(time() < 1300)`
|
q := `interpolate(time() < 1300)`
|
||||||
r1 := netstorage.Result{
|
r1 := netstorage.Result{
|
||||||
MetricName: metricNameExpected,
|
MetricName: metricNameExpected,
|
||||||
Values: []float64{1000, 1200, 1200, 1200, 1200, 1200},
|
Values: []float64{1000, 1200, nan, nan, nan, nan},
|
||||||
Timestamps: timestampsExpected,
|
Timestamps: timestampsExpected,
|
||||||
}
|
}
|
||||||
resultExpected := []netstorage.Result{r1}
|
resultExpected := []netstorage.Result{r1}
|
||||||
@@ -6133,7 +6133,18 @@ func TestExecSuccess(t *testing.T) {
|
|||||||
q := `interpolate(time() > 1500)`
|
q := `interpolate(time() > 1500)`
|
||||||
r1 := netstorage.Result{
|
r1 := netstorage.Result{
|
||||||
MetricName: metricNameExpected,
|
MetricName: metricNameExpected,
|
||||||
Values: []float64{1600, 1600, 1600, 1600, 1800, 2000},
|
Values: []float64{nan, nan, nan, 1600, 1800, 2000},
|
||||||
|
Timestamps: timestampsExpected,
|
||||||
|
}
|
||||||
|
resultExpected := []netstorage.Result{r1}
|
||||||
|
f(q, resultExpected)
|
||||||
|
})
|
||||||
|
t.Run(`interpolate(tail_head_and_middle)`, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
q := `interpolate(time() > 1100 and time() < 1300 default time() > 1700 and time() < 1900)`
|
||||||
|
r1 := netstorage.Result{
|
||||||
|
MetricName: metricNameExpected,
|
||||||
|
Values: []float64{nan, 1200, 1400, 1600, 1800, nan},
|
||||||
Timestamps: timestampsExpected,
|
Timestamps: timestampsExpected,
|
||||||
}
|
}
|
||||||
resultExpected := []netstorage.Result{r1}
|
resultExpected := []netstorage.Result{r1}
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ func mustSaveRollupResultCacheKeyPrefix(path string) {
|
|||||||
var tooBigRollupResults = metrics.NewCounter("vm_too_big_rollup_results_total")
|
var tooBigRollupResults = metrics.NewCounter("vm_too_big_rollup_results_total")
|
||||||
|
|
||||||
// Increment this value every time the format of the cache changes.
|
// Increment this value every time the format of the cache changes.
|
||||||
const rollupResultCacheVersion = 8
|
const rollupResultCacheVersion = 9
|
||||||
|
|
||||||
func marshalRollupResultCacheKey(dst []byte, expr metricsql.Expr, window, step int64, etfs [][]storage.TagFilter) []byte {
|
func marshalRollupResultCacheKey(dst []byte, expr metricsql.Expr, window, step int64, etfs [][]storage.TagFilter) []byte {
|
||||||
dst = append(dst, rollupResultCacheVersion)
|
dst = append(dst, rollupResultCacheVersion)
|
||||||
|
|||||||
@@ -82,15 +82,17 @@ func marshalTimeseriesFast(dst []byte, tss []*timeseries, maxSize int, step int6
|
|||||||
logger.Panicf("BUG: tss cannot be empty")
|
logger.Panicf("BUG: tss cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the required size for marshaled tss.
|
// timestamps are stored only once for all the tss, since they must be identical
|
||||||
size := 0
|
|
||||||
for _, ts := range tss {
|
|
||||||
size += ts.marshaledFastSizeNoTimestamps()
|
|
||||||
}
|
|
||||||
// timestamps are stored only once for all the tss, since they are identical.
|
|
||||||
assertIdenticalTimestamps(tss, step)
|
assertIdenticalTimestamps(tss, step)
|
||||||
size += 8 * len(tss[0].Timestamps)
|
timestamps := tss[0].Timestamps
|
||||||
|
|
||||||
|
// Calculate the required size for marshaled tss.
|
||||||
|
size := 8 + 8 // 8 bytes for len(tss) and 8 bytes for len(timestamps)
|
||||||
|
size += 8 * len(timestamps) // encoded timestamps
|
||||||
|
size += 8 * len(tss) * len(timestamps) // encoded values
|
||||||
|
for _, ts := range tss {
|
||||||
|
size += marshaledFastMetricNameSize(&ts.MetricName)
|
||||||
|
}
|
||||||
if size > maxSize {
|
if size > maxSize {
|
||||||
// Do not marshal tss, since it would occupy too much space
|
// Do not marshal tss, since it would occupy too much space
|
||||||
return dst
|
return dst
|
||||||
@@ -98,176 +100,133 @@ func marshalTimeseriesFast(dst []byte, tss []*timeseries, maxSize int, step int6
|
|||||||
|
|
||||||
// Allocate the buffer for the marshaled tss before its' marshaling.
|
// Allocate the buffer for the marshaled tss before its' marshaling.
|
||||||
// This should reduce memory fragmentation and memory usage.
|
// This should reduce memory fragmentation and memory usage.
|
||||||
dst = bytesutil.ResizeNoCopyMayOverallocate(dst, size)
|
dstLen := len(dst)
|
||||||
dst = marshalFastTimestamps(dst[:0], tss[0].Timestamps)
|
dst = bytesutil.ResizeWithCopyMayOverallocate(dst, size+dstLen)
|
||||||
|
dst = dst[:dstLen]
|
||||||
|
|
||||||
|
// Marshal timestamps and values at first, so they are 8-byte aligned.
|
||||||
|
// This prevents from SIGBUS error on arm architectures.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3927
|
||||||
|
dst = encoding.MarshalUint64(dst, uint64(len(tss)))
|
||||||
|
dst = encoding.MarshalUint64(dst, uint64(len(timestamps)))
|
||||||
|
dst = marshalTimestampsFast(dst, timestamps)
|
||||||
for _, ts := range tss {
|
for _, ts := range tss {
|
||||||
dst = ts.marshalFastNoTimestamps(dst)
|
dst = marshalValuesFast(dst, ts.Values)
|
||||||
|
}
|
||||||
|
for _, ts := range tss {
|
||||||
|
dst = marshalMetricNameFast(dst, &ts.MetricName)
|
||||||
}
|
}
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// unmarshalTimeseriesFast unmarshals timeseries from src.
|
// unmarshalTimeseriesFast unmarshals timeseries from src.
|
||||||
//
|
//
|
||||||
// The returned timeseries refer to src, so it is unsafe to modify it
|
// The returned timeseries refer to src, so it is unsafe to modify it while timeseries are in use.
|
||||||
// until timeseries are in use.
|
|
||||||
func unmarshalTimeseriesFast(src []byte) ([]*timeseries, error) {
|
func unmarshalTimeseriesFast(src []byte) ([]*timeseries, error) {
|
||||||
tail, timestamps, err := unmarshalFastTimestamps(src)
|
if len(src) < 16 {
|
||||||
|
return nil, fmt.Errorf("cannot unmarshal timeseries from %d bytes; need at least 16 bytes", len(src))
|
||||||
|
}
|
||||||
|
tssLen := encoding.UnmarshalUint64(src)
|
||||||
|
timestampsLen := encoding.UnmarshalUint64(src[8:])
|
||||||
|
src = src[16:]
|
||||||
|
|
||||||
|
// Unmarshal timestamps
|
||||||
|
tail, timestamps, err := unmarshalTimestampsFast(src, timestampsLen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
src = tail
|
src = tail
|
||||||
|
|
||||||
var tss []*timeseries
|
tss := make([]*timeseries, tssLen)
|
||||||
for len(src) > 0 {
|
for i := range tss {
|
||||||
var ts timeseries
|
var ts timeseries
|
||||||
ts.denyReuse = false
|
ts.denyReuse = true
|
||||||
ts.Timestamps = timestamps
|
ts.Timestamps = timestamps
|
||||||
|
tss[i] = &ts
|
||||||
|
}
|
||||||
|
|
||||||
tail, err := ts.unmarshalFastNoTimestamps(src)
|
// Unmarshal values
|
||||||
|
for _, ts := range tss {
|
||||||
|
tail, values, err := unmarshalValuesFast(src, timestampsLen)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ts.Values = values
|
||||||
|
src = tail
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal metric names for the time series
|
||||||
|
for _, ts := range tss {
|
||||||
|
tail, err := unmarshalMetricNameFast(&ts.MetricName, src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
src = tail
|
src = tail
|
||||||
|
}
|
||||||
|
|
||||||
tss = append(tss, &ts)
|
if len(src) > 0 {
|
||||||
|
return nil, fmt.Errorf("unexpected non-empty tail left after unmarshaling %d timeseries; len(tail)=%d", len(tss), len(src))
|
||||||
}
|
}
|
||||||
return tss, nil
|
return tss, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshaledFastSizeNoTimestamps returns the size of marshaled ts
|
// marshaledFastMetricNameSize returns the size of marshaled mn returned from marshalMetricNameFast.
|
||||||
// returned from marshalFastNoTimestamps.
|
func marshaledFastMetricNameSize(mn *storage.MetricName) int {
|
||||||
func (ts *timeseries) marshaledFastSizeNoTimestamps() int {
|
n := 0
|
||||||
mn := &ts.MetricName
|
n += 2 + len(mn.MetricGroup)
|
||||||
n := 2 + len(mn.MetricGroup)
|
|
||||||
n += 2 // Length of tags.
|
n += 2 // Length of tags.
|
||||||
for i := range mn.Tags {
|
for i := range mn.Tags {
|
||||||
tag := &mn.Tags[i]
|
tag := &mn.Tags[i]
|
||||||
n += 2 + len(tag.Key)
|
n += 2 + len(tag.Key)
|
||||||
n += 2 + len(tag.Value)
|
n += 2 + len(tag.Value)
|
||||||
}
|
}
|
||||||
n += 8 * len(ts.Values)
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshalFastNoTimestamps appends marshaled ts to dst and returns the result.
|
func marshalValuesFast(dst []byte, values []float64) []byte {
|
||||||
//
|
// Do not marshal len(values), since it is already encoded as len(timestamps) at marshalTimestampsFast.
|
||||||
// It doesn't marshal timestamps.
|
valuesBuf := float64ToByteSlice(values)
|
||||||
//
|
|
||||||
// The result must be unmarshaled with unmarshalFastNoTimestamps.
|
|
||||||
func (ts *timeseries) marshalFastNoTimestamps(dst []byte) []byte {
|
|
||||||
mn := &ts.MetricName
|
|
||||||
dst = marshalBytesFast(dst, mn.MetricGroup)
|
|
||||||
dst = encoding.MarshalUint16(dst, uint16(len(mn.Tags)))
|
|
||||||
// There is no need in tags' sorting - they must be sorted after unmarshaling.
|
|
||||||
for i := range mn.Tags {
|
|
||||||
tag := &mn.Tags[i]
|
|
||||||
dst = marshalBytesFast(dst, tag.Key)
|
|
||||||
dst = marshalBytesFast(dst, tag.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not marshal len(ts.Values), since it is already encoded as len(ts.Timestamps)
|
|
||||||
// during marshalFastTimestamps.
|
|
||||||
var valuesBuf []byte
|
|
||||||
if len(ts.Values) > 0 {
|
|
||||||
valuesBuf = float64ToByteSlice(ts.Values)
|
|
||||||
}
|
|
||||||
dst = append(dst, valuesBuf...)
|
dst = append(dst, valuesBuf...)
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshalFastTimestamps(dst []byte, timestamps []int64) []byte {
|
// it is unsafe modifying src while the returned values is in use.
|
||||||
dst = encoding.MarshalUint32(dst, uint32(len(timestamps)))
|
func unmarshalValuesFast(src []byte, valuesLen uint64) ([]byte, []float64, error) {
|
||||||
var timestampsBuf []byte
|
bufSize := valuesLen * 8
|
||||||
if len(timestamps) > 0 {
|
if uint64(len(src)) < bufSize {
|
||||||
timestampsBuf = int64ToByteSlice(timestamps)
|
return src, nil, fmt.Errorf("cannot unmarshal values; got %d ytes; want at least %d bytes", uint64(len(src)), bufSize)
|
||||||
}
|
}
|
||||||
|
values := byteSliceToFloat64(src[:bufSize])
|
||||||
|
return src[bufSize:], values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func marshalTimestampsFast(dst []byte, timestamps []int64) []byte {
|
||||||
|
timestampsBuf := int64ToByteSlice(timestamps)
|
||||||
dst = append(dst, timestampsBuf...)
|
dst = append(dst, timestampsBuf...)
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// it is unsafe modifying src while the returned timestamps is in use.
|
// it is unsafe modifying src while the returned timestamps is in use.
|
||||||
func unmarshalFastTimestamps(src []byte) ([]byte, []int64, error) {
|
func unmarshalTimestampsFast(src []byte, timestampsLen uint64) ([]byte, []int64, error) {
|
||||||
if len(src) < 4 {
|
bufSize := timestampsLen * 8
|
||||||
return src, nil, fmt.Errorf("cannot decode len(timestamps); got %d bytes; want at least %d bytes", len(src), 4)
|
if uint64(len(src)) < bufSize {
|
||||||
}
|
|
||||||
timestampsCount := int(encoding.UnmarshalUint32(src))
|
|
||||||
src = src[4:]
|
|
||||||
if timestampsCount == 0 {
|
|
||||||
return src, nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
bufSize := timestampsCount * 8
|
|
||||||
if len(src) < bufSize {
|
|
||||||
return src, nil, fmt.Errorf("cannot unmarshal timestamps; got %d bytes; want at least %d bytes", len(src), bufSize)
|
return src, nil, fmt.Errorf("cannot unmarshal timestamps; got %d bytes; want at least %d bytes", len(src), bufSize)
|
||||||
}
|
}
|
||||||
timestamps := byteSliceToInt64(src[:bufSize])
|
timestamps := byteSliceToInt64(src[:bufSize])
|
||||||
src = src[bufSize:]
|
return src[bufSize:], timestamps, nil
|
||||||
|
|
||||||
return src, timestamps, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unmarshalFastNoTimestamps unmarshals ts from src, so ts members reference src.
|
// marshalMetricNameFast appends marshaled mn to dst and returns the result.
|
||||||
//
|
//
|
||||||
// It is expected that ts.Timestamps is already unmarshaled.
|
// The result must be unmarshaled with unmarshalMetricNameFast.
|
||||||
//
|
func marshalMetricNameFast(dst []byte, mn *storage.MetricName) []byte {
|
||||||
// It is unsafe to modify src while ts is in use.
|
dst = marshalBytesFast(dst, mn.MetricGroup)
|
||||||
func (ts *timeseries) unmarshalFastNoTimestamps(src []byte) ([]byte, error) {
|
dst = encoding.MarshalUint16(dst, uint16(len(mn.Tags)))
|
||||||
// ts members point to src, so they cannot be re-used.
|
// There is no need in tags' sorting - they must be sorted after unmarshaling.
|
||||||
ts.denyReuse = true
|
return marshalMetricTagsFast(dst, mn.Tags)
|
||||||
|
|
||||||
tail, err := unmarshalMetricNameFast(&ts.MetricName, src)
|
|
||||||
if err != nil {
|
|
||||||
return tail, fmt.Errorf("cannot unmarshal MetricName: %w", err)
|
|
||||||
}
|
|
||||||
src = tail
|
|
||||||
|
|
||||||
valuesCount := len(ts.Timestamps)
|
|
||||||
if valuesCount == 0 {
|
|
||||||
return src, nil
|
|
||||||
}
|
|
||||||
bufSize := valuesCount * 8
|
|
||||||
if len(src) < bufSize {
|
|
||||||
return src, fmt.Errorf("cannot unmarshal values; got %d bytes; want at least %d bytes", len(src), bufSize)
|
|
||||||
}
|
|
||||||
ts.Values = byteSliceToFloat64(src[:bufSize])
|
|
||||||
|
|
||||||
return src[bufSize:], nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func float64ToByteSlice(a []float64) (b []byte) {
|
// unmarshalMetricNameFast unmarshals mn from src, so mn members hold references to src.
|
||||||
sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
|
||||||
sh.Data = uintptr(unsafe.Pointer(&a[0]))
|
|
||||||
sh.Len = len(a) * int(unsafe.Sizeof(a[0]))
|
|
||||||
sh.Cap = sh.Len
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func int64ToByteSlice(a []int64) (b []byte) {
|
|
||||||
sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
|
||||||
sh.Data = uintptr(unsafe.Pointer(&a[0]))
|
|
||||||
sh.Len = len(a) * int(unsafe.Sizeof(a[0]))
|
|
||||||
sh.Cap = sh.Len
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func byteSliceToInt64(b []byte) (a []int64) {
|
|
||||||
sh := (*reflect.SliceHeader)(unsafe.Pointer(&a))
|
|
||||||
sh.Data = uintptr(unsafe.Pointer(&b[0]))
|
|
||||||
sh.Len = len(b) / int(unsafe.Sizeof(a[0]))
|
|
||||||
sh.Cap = sh.Len
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func byteSliceToFloat64(b []byte) (a []float64) {
|
|
||||||
sh := (*reflect.SliceHeader)(unsafe.Pointer(&a))
|
|
||||||
sh.Data = uintptr(unsafe.Pointer(&b[0]))
|
|
||||||
sh.Len = len(b) / int(unsafe.Sizeof(a[0]))
|
|
||||||
sh.Cap = sh.Len
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// unmarshalMetricNameFast unmarshals mn from src, so mn members
|
|
||||||
// hold references to src.
|
|
||||||
//
|
//
|
||||||
// It is unsafe modifying src while mn is in use.
|
// It is unsafe modifying src while mn is in use.
|
||||||
func unmarshalMetricNameFast(mn *storage.MetricName, src []byte) ([]byte, error) {
|
func unmarshalMetricNameFast(mn *storage.MetricName, src []byte) ([]byte, error) {
|
||||||
@@ -320,9 +279,7 @@ func marshalMetricTagsFast(dst []byte, tags []storage.Tag) []byte {
|
|||||||
|
|
||||||
func marshalMetricNameSorted(dst []byte, mn *storage.MetricName) []byte {
|
func marshalMetricNameSorted(dst []byte, mn *storage.MetricName) []byte {
|
||||||
dst = marshalBytesFast(dst, mn.MetricGroup)
|
dst = marshalBytesFast(dst, mn.MetricGroup)
|
||||||
sortMetricTags(mn)
|
return marshalMetricTagsSorted(dst, mn)
|
||||||
dst = marshalMetricTagsFast(dst, mn.Tags)
|
|
||||||
return dst
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshalMetricTagsSorted(dst []byte, mn *storage.MetricName) []byte {
|
func marshalMetricTagsSorted(dst []byte, mn *storage.MetricName) []byte {
|
||||||
@@ -348,6 +305,62 @@ func unmarshalBytesFast(src []byte) ([]byte, []byte, error) {
|
|||||||
return src[n:], src[:n], nil
|
return src[n:], src[:n], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func float64ToByteSlice(a []float64) (b []byte) {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||||
|
sh.Data = uintptr(unsafe.Pointer(&a[0]))
|
||||||
|
sh.Len = len(a) * int(unsafe.Sizeof(a[0]))
|
||||||
|
sh.Cap = sh.Len
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func int64ToByteSlice(a []int64) (b []byte) {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||||
|
sh.Data = uintptr(unsafe.Pointer(&a[0]))
|
||||||
|
sh.Len = len(a) * int(unsafe.Sizeof(a[0]))
|
||||||
|
sh.Cap = sh.Len
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func byteSliceToInt64(b []byte) (a []int64) {
|
||||||
|
if len(b) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sh := (*reflect.SliceHeader)(unsafe.Pointer(&a))
|
||||||
|
sh.Data = uintptr(unsafe.Pointer(&b[0]))
|
||||||
|
sh.Len = len(b) / int(unsafe.Sizeof(a[0]))
|
||||||
|
sh.Cap = sh.Len
|
||||||
|
// Make sure that the returned slice is properly aligned to 8 bytes.
|
||||||
|
// This prevents from SIGBUS error on arm architectures, which deny unaligned access.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3927
|
||||||
|
if sh.Data%8 != 0 {
|
||||||
|
logger.Panicf("BUG: the input byte slice b must be aligned to 8 bytes")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func byteSliceToFloat64(b []byte) (a []float64) {
|
||||||
|
if len(b) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sh := (*reflect.SliceHeader)(unsafe.Pointer(&a))
|
||||||
|
sh.Data = uintptr(unsafe.Pointer(&b[0]))
|
||||||
|
sh.Len = len(b) / int(unsafe.Sizeof(a[0]))
|
||||||
|
sh.Cap = sh.Len
|
||||||
|
// Make sure that the returned slice is properly aligned to 8 bytes.
|
||||||
|
// This prevents from SIGBUS error on arm architectures, which deny unaligned access.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3927
|
||||||
|
if sh.Data%8 != 0 {
|
||||||
|
logger.Panicf("BUG: the input byte slice b must be aligned to 8 bytes")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func stringMetricName(mn *storage.MetricName) string {
|
func stringMetricName(mn *storage.MetricName) string {
|
||||||
var dst []byte
|
var dst []byte
|
||||||
dst = append(dst, mn.MetricGroup...)
|
dst = append(dst, mn.MetricGroup...)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package promql
|
package promql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
|
||||||
)
|
)
|
||||||
@@ -14,91 +14,98 @@ func TestMain(m *testing.M) {
|
|||||||
os.Exit(n)
|
os.Exit(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeseriesMarshalUnmarshalFast(t *testing.T) {
|
func TestMarshalTimeseriesFast(t *testing.T) {
|
||||||
t.Run("single", func(t *testing.T) {
|
f := func(tss []*timeseries) {
|
||||||
var tsOrig timeseries
|
t.Helper()
|
||||||
buf := tsOrig.marshalFastNoTimestamps(nil)
|
data := marshalTimeseriesFast(nil, tss, 1e9, 10)
|
||||||
n := tsOrig.marshaledFastSizeNoTimestamps()
|
tss2, err := unmarshalTimeseriesFast(data)
|
||||||
if n != len(buf) {
|
|
||||||
t.Fatalf("unexpected marshaled size; got %d; want %d", n, len(buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
var tsGot timeseries
|
|
||||||
tail, err := tsGot.unmarshalFastNoTimestamps(buf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot unmarshal timeseries: %s", err)
|
t.Fatalf("cannot unmarshal timeseries: %s", err)
|
||||||
}
|
}
|
||||||
if len(tail) > 0 {
|
if !reflect.DeepEqual(tss, tss2) {
|
||||||
t.Fatalf("unexpected non-empty tail left: len(tail)=%d; tail=%X", len(tail), tail)
|
t.Fatalf("unexpected timeseries unmarshaled\ngot\n%#v\nwant\n%#v", tss2[0], tss[0])
|
||||||
}
|
|
||||||
tsOrig.denyReuse = true
|
|
||||||
tsOrig.MetricName.MetricGroup = []byte{}
|
|
||||||
if !reflect.DeepEqual(&tsOrig, &tsGot) {
|
|
||||||
t.Fatalf("unexpected ts\ngot:\n%s\nwant:\n%s", &tsGot, &tsOrig)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("multiple", func(t *testing.T) {
|
|
||||||
var dst []byte
|
|
||||||
var tssOrig []*timeseries
|
|
||||||
timestamps := []int64{2}
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
var ts timeseries
|
|
||||||
ts.denyReuse = true
|
|
||||||
ts.MetricName.MetricGroup = []byte(fmt.Sprintf("metricGroup %d", i))
|
|
||||||
ts.MetricName.Tags = []storage.Tag{{
|
|
||||||
Key: []byte(fmt.Sprintf("key %d", i)),
|
|
||||||
Value: []byte(fmt.Sprintf("value %d", i)),
|
|
||||||
}}
|
|
||||||
ts.Values = []float64{float64(i) + 0.2}
|
|
||||||
ts.Timestamps = timestamps
|
|
||||||
|
|
||||||
dstLen := len(dst)
|
|
||||||
dst = ts.marshalFastNoTimestamps(dst)
|
|
||||||
n := ts.marshaledFastSizeNoTimestamps()
|
|
||||||
if n != len(dst)-dstLen {
|
|
||||||
t.Fatalf("unexpected marshaled size on iteration %d; got %d; want %d", i, n, len(dst)-dstLen)
|
|
||||||
}
|
|
||||||
|
|
||||||
var tsGot timeseries
|
|
||||||
tsGot.Timestamps = ts.Timestamps
|
|
||||||
tail, err := tsGot.unmarshalFastNoTimestamps(dst[dstLen:])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("cannot unmarshal timeseries on iteration %d: %s", i, err)
|
|
||||||
}
|
|
||||||
if len(tail) > 0 {
|
|
||||||
t.Fatalf("unexpected non-empty tail left on iteration %d: len(tail)=%d; tail=%x", i, len(tail), tail)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(&ts, &tsGot) {
|
|
||||||
t.Fatalf("unexpected ts on iteration %d\ngot:\n%s\nwant:\n%s", i, &tsGot, &ts)
|
|
||||||
}
|
|
||||||
|
|
||||||
tssOrig = append(tssOrig, &ts)
|
|
||||||
}
|
|
||||||
buf := marshalTimeseriesFast(nil, tssOrig, 1e6, 123)
|
|
||||||
tssGot, err := unmarshalTimeseriesFast(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("error in unmarshalTimeseriesFast: %s", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(tssOrig, tssGot) {
|
|
||||||
t.Fatalf("unexpected unmarshaled timeseries\ngot:\n%s\nwant:\n%s", tssGot, tssOrig)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
src := dst
|
// Check 8-byte alignment.
|
||||||
for i := 0; i < 10; i++ {
|
// This prevents from SIGBUS error on arm architectures.
|
||||||
tsOrig := tssOrig[i]
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3927
|
||||||
var ts timeseries
|
for _, ts := range tss2 {
|
||||||
ts.Timestamps = tsOrig.Timestamps
|
if len(ts.Values) == 0 {
|
||||||
tail, err := ts.unmarshalFastNoTimestamps(src)
|
continue
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("cannot unmarshal timeseries[%d]: %s", i, err)
|
|
||||||
}
|
}
|
||||||
src = tail
|
|
||||||
if !reflect.DeepEqual(tsOrig, &ts) {
|
// check float64 alignment
|
||||||
t.Fatalf("unexpected ts on iteration %d:\n%+v\nwant:\n%+v", i, &ts, tsOrig)
|
addr := uintptr(unsafe.Pointer(&ts.Values[0]))
|
||||||
|
if mod := addr % unsafe.Alignof(ts.Values[0]); mod != 0 {
|
||||||
|
t.Fatalf("mis-aligned; &ts.Values[0]=%p; mod=%d", &ts.Values[0], mod)
|
||||||
|
}
|
||||||
|
// check int64 alignment
|
||||||
|
addr = uintptr(unsafe.Pointer(&ts.Timestamps[0]))
|
||||||
|
if mod := addr % unsafe.Alignof(ts.Timestamps[0]); mod != 0 {
|
||||||
|
t.Fatalf("mis-aligned; &ts.Timestamps[0]=%p; mod=%d", &ts.Timestamps[0], mod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(src) > 0 {
|
}
|
||||||
t.Fatalf("unexpected tail left; len(tail)=%d; tail=%X", len(src), src)
|
|
||||||
}
|
// Single series
|
||||||
|
f([]*timeseries{{
|
||||||
|
MetricName: storage.MetricName{
|
||||||
|
MetricGroup: []byte{},
|
||||||
|
},
|
||||||
|
denyReuse: true,
|
||||||
|
}})
|
||||||
|
f([]*timeseries{{
|
||||||
|
MetricName: storage.MetricName{
|
||||||
|
MetricGroup: []byte("foobar"),
|
||||||
|
Tags: []storage.Tag{
|
||||||
|
{
|
||||||
|
Key: []byte("tag1"),
|
||||||
|
Value: []byte("value1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("tag2"),
|
||||||
|
Value: []byte("value2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Values: []float64{1, 2, 3.234},
|
||||||
|
Timestamps: []int64{10, 20, 30},
|
||||||
|
denyReuse: true,
|
||||||
|
}})
|
||||||
|
|
||||||
|
// Multiple series
|
||||||
|
f([]*timeseries{
|
||||||
|
{
|
||||||
|
MetricName: storage.MetricName{
|
||||||
|
MetricGroup: []byte("foobar"),
|
||||||
|
Tags: []storage.Tag{
|
||||||
|
{
|
||||||
|
Key: []byte("tag1"),
|
||||||
|
Value: []byte("value1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("tag2"),
|
||||||
|
Value: []byte("value2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Values: []float64{1, 2.34, -33},
|
||||||
|
Timestamps: []int64{-10, 0, 10},
|
||||||
|
denyReuse: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MetricName: storage.MetricName{
|
||||||
|
MetricGroup: []byte("baz"),
|
||||||
|
Tags: []storage.Tag{
|
||||||
|
{
|
||||||
|
Key: []byte("tag12"),
|
||||||
|
Value: []byte("value13"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Values: []float64{4, 1, 2.34},
|
||||||
|
Timestamps: []int64{-10, 0, 10},
|
||||||
|
denyReuse: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -552,18 +552,28 @@ func vmrangeBucketsToLE(tss []*timeseries) []*timeseries {
|
|||||||
for _, xs := range xss {
|
for _, xs := range xss {
|
||||||
ts := xs.ts
|
ts := xs.ts
|
||||||
if isZeroTS(ts) {
|
if isZeroTS(ts) {
|
||||||
// Skip time series with zeros. They are substituted by xssNew below.
|
// Skip buckets with zero values - they will be merged into a single bucket
|
||||||
xsPrev = xs
|
// when the next non-zero bucket appears.
|
||||||
|
|
||||||
|
// Do not store xs in xsPrev in order to properly create `le` time series
|
||||||
|
// for zero buckets.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4021
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if xs.start != xsPrev.end && uniqTs[xs.startStr] == nil {
|
if xs.start != xsPrev.end {
|
||||||
uniqTs[xs.startStr] = xs.ts
|
// There is a gap between the previous bucket and the current bucket
|
||||||
xssNew = append(xssNew, x{
|
// or the previous bucket is skipped because it was zero.
|
||||||
endStr: xs.startStr,
|
// Fill it with a time series with le=xs.start.
|
||||||
end: xs.start,
|
if uniqTs[xs.startStr] == nil {
|
||||||
ts: copyTS(ts, xs.startStr),
|
uniqTs[xs.startStr] = xs.ts
|
||||||
})
|
xssNew = append(xssNew, x{
|
||||||
|
endStr: xs.startStr,
|
||||||
|
end: xs.start,
|
||||||
|
ts: copyTS(ts, xs.startStr),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Convert the current time series to a time series with le=xs.end
|
||||||
ts.MetricName.AddTag("le", xs.endStr)
|
ts.MetricName.AddTag("le", xs.endStr)
|
||||||
prevTs := uniqTs[xs.endStr]
|
prevTs := uniqTs[xs.endStr]
|
||||||
if prevTs != nil {
|
if prevTs != nil {
|
||||||
@@ -575,7 +585,7 @@ func vmrangeBucketsToLE(tss []*timeseries) []*timeseries {
|
|||||||
}
|
}
|
||||||
xsPrev = xs
|
xsPrev = xs
|
||||||
}
|
}
|
||||||
if !math.IsInf(xsPrev.end, 1) && !isZeroTS(xsPrev.ts) {
|
if xsPrev.ts != nil && !math.IsInf(xsPrev.end, 1) && !isZeroTS(xsPrev.ts) {
|
||||||
xssNew = append(xssNew, x{
|
xssNew = append(xssNew, x{
|
||||||
endStr: "+Inf",
|
endStr: "+Inf",
|
||||||
end: math.Inf(1),
|
end: math.Inf(1),
|
||||||
@@ -1165,7 +1175,8 @@ func transformInterpolate(tfa *transformFuncArg) ([]*timeseries, error) {
|
|||||||
}
|
}
|
||||||
rvs := args[0]
|
rvs := args[0]
|
||||||
for _, ts := range rvs {
|
for _, ts := range rvs {
|
||||||
values := ts.Values
|
values := skipLeadingNaNs(ts.Values)
|
||||||
|
values = skipTrailingNaNs(values)
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,36 @@ foo{le="+Inf"} 1.23 456`,
|
|||||||
foo{le="+Inf"} 5.3 0`,
|
foo{le="+Inf"} 5.3 0`,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Adjacent empty vmrange bucket
|
||||||
|
f(
|
||||||
|
`foo{vmrange="7.743e+05...8.799e+05"} 5 123
|
||||||
|
foo{vmrange="6.813e+05...7.743e+05"} 0 123`,
|
||||||
|
`foo{le="7.743e+05"} 0 123
|
||||||
|
foo{le="8.799e+05"} 5 123
|
||||||
|
foo{le="+Inf"} 5 123`,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Multiple adjacent empty vmrange bucket
|
||||||
|
f(
|
||||||
|
`foo{vmrange="7.743e+05...8.799e+05"} 5 123
|
||||||
|
foo{vmrange="6.813e+05...7.743e+05"} 0 123
|
||||||
|
foo{vmrange="5.813e+05...6.813e+05"} 0 123
|
||||||
|
`,
|
||||||
|
`foo{le="7.743e+05"} 0 123
|
||||||
|
foo{le="8.799e+05"} 5 123
|
||||||
|
foo{le="+Inf"} 5 123`,
|
||||||
|
)
|
||||||
|
f(
|
||||||
|
`foo{vmrange="8.799e+05...9.813e+05"} 0 123
|
||||||
|
foo{vmrange="7.743e+05...8.799e+05"} 5 123
|
||||||
|
foo{vmrange="6.813e+05...7.743e+05"} 0 123
|
||||||
|
foo{vmrange="5.813e+05...6.813e+05"} 0 123
|
||||||
|
`,
|
||||||
|
`foo{le="7.743e+05"} 0 123
|
||||||
|
foo{le="8.799e+05"} 5 123
|
||||||
|
foo{le="+Inf"} 5 123`,
|
||||||
|
)
|
||||||
|
|
||||||
// Multiple non-empty vmrange buckets
|
// Multiple non-empty vmrange buckets
|
||||||
f(
|
f(
|
||||||
`foo{vmrange="4.084e+02...4.642e+02"} 2 123
|
`foo{vmrange="4.084e+02...4.642e+02"} 2 123
|
||||||
|
|||||||
@@ -37,8 +37,10 @@ var (
|
|||||||
finalMergeDelay = flag.Duration("finalMergeDelay", 0, "The delay before starting final merge for per-month partition after no new data is ingested into it. "+
|
finalMergeDelay = flag.Duration("finalMergeDelay", 0, "The delay before starting final merge for per-month partition after no new data is ingested into it. "+
|
||||||
"Final merge may require additional disk IO and CPU resources. Final merge may increase query speed and reduce disk space usage in some cases. "+
|
"Final merge may require additional disk IO and CPU resources. Final merge may increase query speed and reduce disk space usage in some cases. "+
|
||||||
"Zero value disables final merge")
|
"Zero value disables final merge")
|
||||||
bigMergeConcurrency = flag.Int("bigMergeConcurrency", 0, "The maximum number of CPU cores to use for big merges. Default value is used if set to 0")
|
_ = flag.Int("bigMergeConcurrency", 0, "Deprecated: this flag does nothing. Please use -smallMergeConcurrency "+
|
||||||
smallMergeConcurrency = flag.Int("smallMergeConcurrency", 0, "The maximum number of CPU cores to use for small merges. Default value is used if set to 0")
|
"for controlling the concurrency of background merges. See https://docs.victoriametrics.com/#storage")
|
||||||
|
smallMergeConcurrency = flag.Int("smallMergeConcurrency", 0, "The maximum number of workers for background merges. See https://docs.victoriametrics.com/#storage . "+
|
||||||
|
"It isn't recommended tuning this flag in general case, since this may lead to uncontrolled increase in the number of parts and increased CPU usage during queries")
|
||||||
retentionTimezoneOffset = flag.Duration("retentionTimezoneOffset", 0, "The offset for performing indexdb rotation. "+
|
retentionTimezoneOffset = flag.Duration("retentionTimezoneOffset", 0, "The offset for performing indexdb rotation. "+
|
||||||
"If set to 0, then the indexdb rotation is performed at 4am UTC time per each -retentionPeriod. "+
|
"If set to 0, then the indexdb rotation is performed at 4am UTC time per each -retentionPeriod. "+
|
||||||
"If set to 2h, then the indexdb rotation is performed at 4am EET time (the timezone with +2h offset)")
|
"If set to 2h, then the indexdb rotation is performed at 4am EET time (the timezone with +2h offset)")
|
||||||
@@ -91,7 +93,6 @@ func Init(resetCacheIfNeeded func(mrs []storage.MetricRow)) {
|
|||||||
resetResponseCacheIfNeeded = resetCacheIfNeeded
|
resetResponseCacheIfNeeded = resetCacheIfNeeded
|
||||||
storage.SetLogNewSeries(*logNewSeries)
|
storage.SetLogNewSeries(*logNewSeries)
|
||||||
storage.SetFinalMergeDelay(*finalMergeDelay)
|
storage.SetFinalMergeDelay(*finalMergeDelay)
|
||||||
storage.SetBigMergeWorkersCount(*bigMergeConcurrency)
|
|
||||||
storage.SetMergeWorkersCount(*smallMergeConcurrency)
|
storage.SetMergeWorkersCount(*smallMergeConcurrency)
|
||||||
storage.SetRetentionTimezoneOffset(*retentionTimezoneOffset)
|
storage.SetRetentionTimezoneOffset(*retentionTimezoneOffset)
|
||||||
storage.SetFreeDiskSpaceLimit(minFreeDiskSpaceBytes.N)
|
storage.SetFreeDiskSpaceLimit(minFreeDiskSpaceBytes.N)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM node:18-alpine3.15
|
FROM node:18-alpine3.17
|
||||||
|
|
||||||
RUN apk update && apk upgrade
|
RUN apk update && apk upgrade
|
||||||
RUN apk add --no-cache bash bash-doc bash-completion libtool autoconf automake nasm pkgconfig libpng gcc make g++ zlib-dev gawk
|
RUN apk add --no-cache bash bash-doc bash-completion libtool autoconf automake nasm pkgconfig libpng gcc make g++ zlib-dev gawk
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.19.5 as build-web-stage
|
FROM golang:1.21.0 as build-web-stage
|
||||||
COPY build /build
|
COPY build /build
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
@@ -6,7 +6,7 @@ COPY web/ /build/
|
|||||||
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o web-amd64 github.com/VictoriMetrics/vmui/ && \
|
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o web-amd64 github.com/VictoriMetrics/vmui/ && \
|
||||||
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o web-windows github.com/VictoriMetrics/vmui/
|
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o web-windows github.com/VictoriMetrics/vmui/
|
||||||
|
|
||||||
FROM alpine:3.17.1
|
FROM alpine:3.18.0
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
COPY --from=build-web-stage /build/web-amd64 /app/web
|
COPY --from=build-web-stage /build/web-amd64 /app/web
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
DOCKER_NAMESPACE := victoriametrics
|
DOCKER_NAMESPACE := victoriametrics
|
||||||
|
|
||||||
ROOT_IMAGE ?= alpine:3.17.1
|
ROOT_IMAGE ?= alpine:3.18.3
|
||||||
CERTS_IMAGE := alpine:3.17.1
|
CERTS_IMAGE := alpine:3.18.3
|
||||||
GO_BUILDER_IMAGE := golang:1.20.0-alpine
|
|
||||||
|
GO_BUILDER_IMAGE := golang:1.21.0-alpine
|
||||||
BUILDER_IMAGE := local/builder:2.0.0-$(shell echo $(GO_BUILDER_IMAGE) | tr :/ __)-1
|
BUILDER_IMAGE := local/builder:2.0.0-$(shell echo $(GO_BUILDER_IMAGE) | tr :/ __)-1
|
||||||
BASE_IMAGE := local/base:1.1.4-$(shell echo $(ROOT_IMAGE) | tr :/ __)-$(shell echo $(CERTS_IMAGE) | tr :/ __)
|
BASE_IMAGE := local/base:1.1.4-$(shell echo $(ROOT_IMAGE) | tr :/ __)-$(shell echo $(CERTS_IMAGE) | tr :/ __)
|
||||||
|
|
||||||
@@ -77,8 +78,8 @@ publish-via-docker: \
|
|||||||
--build-arg root_image=$(ROOT_IMAGE) \
|
--build-arg root_image=$(ROOT_IMAGE) \
|
||||||
--build-arg APP_NAME=$(APP_NAME) \
|
--build-arg APP_NAME=$(APP_NAME) \
|
||||||
--tag $(DOCKER_NAMESPACE)/$(APP_NAME):$(PKG_TAG)$(RACE) \
|
--tag $(DOCKER_NAMESPACE)/$(APP_NAME):$(PKG_TAG)$(RACE) \
|
||||||
--tag $(DOCKER_NAMESPACE)/$(APP_NAME):$(LATEST_TAG)$(RACE) \
|
|
||||||
-o type=image \
|
-o type=image \
|
||||||
|
--provenance=false \
|
||||||
-f app/$(APP_NAME)/multiarch/Dockerfile \
|
-f app/$(APP_NAME)/multiarch/Dockerfile \
|
||||||
--push \
|
--push \
|
||||||
bin
|
bin
|
||||||
|
|||||||
@@ -34,12 +34,12 @@ groups:
|
|||||||
Consider to increase the limit as fast as possible."
|
Consider to increase the limit as fast as possible."
|
||||||
|
|
||||||
- alert: TooHighMemoryUsage
|
- alert: TooHighMemoryUsage
|
||||||
expr: (process_resident_memory_anon_bytes / vm_available_memory_bytes) > 0.9
|
expr: (process_resident_memory_anon_bytes / vm_available_memory_bytes) > 0.8
|
||||||
for: 5m
|
for: 5m
|
||||||
labels:
|
labels:
|
||||||
severity: critical
|
severity: critical
|
||||||
annotations:
|
annotations:
|
||||||
summary: "It is more than 90% of memory used by \"{{ $labels.job }}\"(\"{{ $labels.instance }}\") during the last 5m"
|
summary: "It is more than 80% of memory used by \"{{ $labels.job }}\"(\"{{ $labels.instance }}\") during the last 5m"
|
||||||
description: "Too high memory usage may result into multiple issues such as OOMs or degraded performance.
|
description: "Too high memory usage may result into multiple issues such as OOMs or degraded performance.
|
||||||
Consider to either increase available memory or decrease the load on the process."
|
Consider to either increase available memory or decrease the load on the process."
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,144 @@ The following tip changes can be tested by building VictoriaMetrics components f
|
|||||||
* [How to build vmauth](https://docs.victoriametrics.com/vmauth.html#how-to-build-from-sources)
|
* [How to build vmauth](https://docs.victoriametrics.com/vmauth.html#how-to-build-from-sources)
|
||||||
* [How to build vmctl](https://docs.victoriametrics.com/vmctl.html#how-to-build)
|
* [How to build vmctl](https://docs.victoriametrics.com/vmctl.html#how-to-build)
|
||||||
|
|
||||||
## tip
|
## v1.87.x long-time support release (LTS)
|
||||||
|
|
||||||
|
## [v1.87.8](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.87.8)
|
||||||
|
|
||||||
|
Released at 2023-09-01
|
||||||
|
|
||||||
|
**v1.87.x is a line of LTS releases (e.g. long-time support). It contains important up-to-date bugfixes.
|
||||||
|
The v1.87.x line will be supported for at least 12 months since [v1.87.0](https://docs.victoriametrics.com/CHANGELOG.html#v1870) release**
|
||||||
|
|
||||||
|
* BUGFIX: [build](https://docs.victoriametrics.com/): fix Docker builds for old Docker releases. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4907).
|
||||||
|
* BUGFIX: vmselect: correctly handle requests with `/select/multitenant` prefix. Such requests must be rejected since vmselect does not support multitenancy endpoint. Previously, such requests were causing panic. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4910).
|
||||||
|
* BUGFIX: [vminsert](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): properly check for [read-only state](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#readonly-mode) at `vmstorage`. Previously it wasn't properly checked, which could lead to increased resource usage and data ingestion slowdown when some of `vmstorage` nodes are in read-only mode. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4870).
|
||||||
|
* BUGFIX: [vminsert](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): properly close broken vmstorage connection during [read-only state](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#readonly-mode) checks at `vmstorage`. Previously it wasn't properly closed, which prevents restoring `vmstorage` node from read-only mode. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4870).
|
||||||
|
* BUGFIX: [vmstorage](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): prevent from breaking `vmselect` -> `vmstorage` RPC communication when `vmstorage` returns an empty label name at `/api/v1/labels` request. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4932).
|
||||||
|
* BUGFIX: do not allow starting VictoriaMetrics components with improperly set boolean command-line flags in the form `-boolFlagName value`, since this leads to silent incomplete flags' parsing. This form should be replaced with `-boolFlagName=value`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4845).
|
||||||
|
* BUGFIX: properly replace `:` chars in label names with `_` when `-usePromCompatibleNaming` command-line flag is passed to `vmagent`, `vminsert` or single-node VictoriaMetrics. This addresses [this comment](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3113#issuecomment-1275077071).
|
||||||
|
* BUGFIX: [vmbackup](https://docs.victoriametrics.com/vmbackup.html): correctly check if specified `-dst` belongs to specified `-storageDataPath`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4837).
|
||||||
|
|
||||||
|
## [v1.87.7](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.87.7)
|
||||||
|
|
||||||
|
Released at 2023-08-12
|
||||||
|
|
||||||
|
**v1.87.x is a line of LTS releases (e.g. long-time support). It contains important up-to-date bugfixes.
|
||||||
|
The v1.87.x line will be supported for at least 12 months since [v1.87.0](https://docs.victoriametrics.com/CHANGELOG.html#v1870) release**
|
||||||
|
|
||||||
|
* SECURITY: upgrade Go builder from Go1.20.4 to Go1.21.0.
|
||||||
|
* SECURITY: upgrade base docker image (Alpine) from 3.18.2 to 3.18.3. See [alpine 3.18.3 release notes](https://alpinelinux.org/posts/Alpine-3.15.10-3.16.7-3.17.5-3.18.3-released.html).
|
||||||
|
|
||||||
|
* BUGFIX: vmselect: fix timestamp alignment for Prometheus querying API if time argument is less than 10m from the beginning of Unix epoch.
|
||||||
|
* BUGFIX: vminsert: fixed decoding of label values with slash when accepting data via [pushgateway protocol](https://docs.victoriametrics.com/#how-to-import-data-in-prometheus-exposition-format). This fixes Prometheus golang client compatibility. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4692).
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): properly validate scheme for `proxy_url` field at the scrape config. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4811) for details.
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): close HTTP connections to [service discovery](https://docs.victoriametrics.com/sd_configs.html) servers when they are no longer needed. This should prevent from possible connection exhasution in some cases. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4724).
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): properly apply `if` filters during [relabeling](https://docs.victoriametrics.com/vmagent.html#relabeling-enhancements). Previously the `if` filter could improperly work. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4806) and [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4816).
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): fix possible panic at shutdown when [stream aggregation](https://docs.victoriametrics.com/stream-aggregation.html) is enabled. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4407) for details.
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): use local scrape timestamps for the scraped metrics unless `honor_timestamps: true` option is explicitly set at [scrape_config](https://docs.victoriametrics.com/sd_configs.html#scrape_configs). This fixes gaps for metrics collected from [cadvisor](https://github.com/google/cadvisor) or similar exporters, which export metrics with invalid timestamps. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4697) and [this comment](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4697#issuecomment-1654614799) for details.
|
||||||
|
* BUGFIX: [vmauth](https://docs.victoriametrics.com/vmauth.html): Properly handle LOCAL command for proxy protocol. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3335#issuecomment-1569864108).
|
||||||
|
* BUGFIX: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): properly return error from [/api/v1/query](https://docs.victoriametrics.com/keyConcepts.html#instant-query) and [/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query) at `vmselect` when the `-search.maxSamplesPerQuery` or `-search.maxSamplesPerSeries` [limit](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#resource-usage-limits) is exceeded. Previously incomplete response could be returned without the error if `vmselect` runs with `-replicationFactor` greater than 1. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4472).
|
||||||
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): correctly calculate evaluation time for rules. Before, there was a low probability for discrepancy between actual time and rules evaluation time if evaluation interval was lower than the execution time for rules within the group.
|
||||||
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): reset evaluation timestamp after modifying group interval. Before, there could have latency on rule evaluation time.
|
||||||
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): Properly set datasource query params. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4340). Thanks to @gsakun for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4341).
|
||||||
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): Properly form path to static assets in WEB UI if `http.pathPrefix` set. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4349).
|
||||||
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): properly return empty slices instead of nil for `/api/v1/rules` for groups with present name but absent `rules`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4221).
|
||||||
|
* BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): interrupt explore procedure in influx mode if vmctl found no numeric fields.
|
||||||
|
* BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): fix panic in case `--remote-read-filter-time-start` flag is not set for remote-read mode. This flag is now required to use remote-read mode. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4553).
|
||||||
|
|
||||||
|
## [v1.87.6](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.87.6)
|
||||||
|
|
||||||
|
Released at 2023-05-18
|
||||||
|
|
||||||
|
**v1.87.x is a line of LTS releases (e.g. long-time support). It contains important up-to-date bugfixes.
|
||||||
|
The v1.87.x line will be supported for at least 12 months since [v1.87.0](https://docs.victoriametrics.com/CHANGELOG.html#v1870) release**
|
||||||
|
|
||||||
|
* SECURITY: upgrade Go builder from Go1.20.3 to Go1.20.4. See [the list of issues addressed in Go1.20.4](https://github.com/golang/go/issues?q=milestone%3AGo1.20.4+label%3ACherryPickApproved).
|
||||||
|
* SECURITY: upgrade base docker image (alpine) from 3.17.3 to 3.18.0. See [alpine 3.18.0 release notes](https://www.alpinelinux.org/posts/Alpine-3.18.0-released.html).
|
||||||
|
* SECURITY: serve `/robots.txt` content to disallow indexing of the exposed instances by search engines. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4128) for details.
|
||||||
|
|
||||||
|
* BUGFIX: reduce the probability of sudden increase in the number of small parts on systems with small number of CPU cores.
|
||||||
|
* BUGFIX: reduce the possibility of increased CPU usage when data with timestamps older than one hour is ingested into VictoriaMetrics. This reduces spikes for the graph `sum(rate(vm_slow_per_day_index_inserts_total))`. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4258).
|
||||||
|
* BUGFIX: do not ignore trailing empty field in CSV lines when [importing data in CSV format](https://docs.victoriametrics.com/#how-to-import-csv-data). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4048).
|
||||||
|
* BUGFIX: disallow `"` chars when parsing Prometheus label names, since they aren't allowed by [Prometheus text exposition format](https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md#text-format-example). Previously this could result in silent incorrect parsing of incorrect Prometheus labels such as `foo{"bar"="baz"}` or `{foo:"bar",baz="aaa"}`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4284).
|
||||||
|
* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): fix a panic when the duration in the query contains uppercase `M` suffix. Such a suffix isn't allowed to use in durations, since it clashes with `a million` suffix, e.g. it isn't clear whether `rate(metric[5M])` means rate over 5 minutes, 5 months or 5 million seconds. See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3589) and [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4120) issues.
|
||||||
|
* BUGFIX: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): prevent from possible panic when the number of vmstorage nodes increases when [automatic vmstorage discovery](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#automatic-vmstorage-discovery) is enabled.
|
||||||
|
* BUGFIX: properly limit the number of [OpenTSDB HTTP](https://docs.victoriametrics.com/#sending-opentsdb-data-via-http-apiput-requests) concurrent requests specified via `-maxConcurrentInserts` command-line flag. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4204). Thanks to @zouxiang1993 for [the fix](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4208).
|
||||||
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): properly return empty slices instead of nil for `/api/v1/rules` and `/api/v1/alerts` API handlers. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4221).
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): add `__meta_kubernetes_endpoints_name` label for all ports discovered from endpoint. Previously, ports not matched by `Service` did not have this label. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4154) for details. Thanks to @thunderbird86 for discovering and [fixing](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4253) the issue.
|
||||||
|
* BUGFIX: fix possible infinite loop during `indexdb` rotation when `-retentionTimezoneOffset` command-line flag is set and the local timezone is not UTC. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4207). Thanks to @faceair for [the fix](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4206).
|
||||||
|
* BUGFIX: [vmauth](https://docs.victoriametrics.com/vmauth.html): do not return invalid auth credentials in http response by default, since it may be logged by client. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4188).
|
||||||
|
* BUGFIX: [alerts-health](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/alerts-health.yml): update threshold for `TooHighMemoryUsage` alert from 90% to 80%, since 90% is too high for production environments.
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): properly handle the `vm_promscrape_config_last_reload_successful` metric after config reload. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4260).
|
||||||
|
* BUGFIX: [stream aggregation](https://docs.victoriametrics.com/stream-aggregation.html): fix bug with duplicated labels during stream aggregation via single-node VictoriaMetrics. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4277).
|
||||||
|
* BUGFIX: [stream aggregation](https://docs.victoriametrics.com/stream-aggregation.html): suppress `series after dedup` error message in logs when `-remoteWrite.streamAggr.dedupInterval` command-line flag is set at [vmagent](https://docs.victoriametrics.com/vmgent.html) or when `-streamAggr.dedupInterval` command-line flag is set at [single-node VictoriaMetrics](https://docs.victoriametrics.com/).
|
||||||
|
|
||||||
|
## [v1.87.5](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.87.5)
|
||||||
|
|
||||||
|
Released at 2023-04-06
|
||||||
|
|
||||||
|
**v1.87.x is a line of LTS releases (e.g. long-time support). It contains important up-to-date bugfixes.
|
||||||
|
The v1.87.x line will be supported for at least 12 months since [v1.87.0](https://docs.victoriametrics.com/CHANGELOG.html#v1870) release**
|
||||||
|
|
||||||
|
* SECURITY: upgrade base docker image (alpine) from 3.17.2 to 3.17.3. See [alpine 3.17.3 release notes](https://alpinelinux.org/posts/Alpine-3.17.3-released.html).
|
||||||
|
* SECURITY: upgrade Go builder from Go1.20.2 to Go1.20.3. See [the list of issues addressed in Go1.20.3](https://github.com/golang/go/issues?q=milestone%3AGo1.20.3+label%3ACherryPickApproved).
|
||||||
|
|
||||||
|
* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): properly convert [VictoriaMetrics historgram buckets](https://valyala.medium.com/improving-histogram-usability-for-prometheus-and-grafana-bc7e5df0e350) to Prometheus histogram buckets when VictoriaMetrics histogram contain zero buckets. Previously these buckets were ignored, and this could lead to missing Prometheus histogram buckets after the conversion. Thanks to @zklapow for [the fix](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4021).
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmgent.html): fix CPU and memory usage spikes when files pointed by [file_sd_config](https://docs.victoriametrics.com/sd_configs.html#file_sd_configs) cannot be re-read. See [this_issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3989).
|
||||||
|
* BUGFIX: prevent unexpected merges on start-up when `-storage.minFreeDiskSpaceBytes` is set. See [the issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4023).
|
||||||
|
* BUGFIX: properly support comma-separated filters inside [retention filters](https://docs.victoriametrics.com/#retention-filters). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3915).
|
||||||
|
* BUGFIX: verify response code when fetching configuration files via HTTP. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4034).
|
||||||
|
|
||||||
|
## [v1.87.4](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.87.4)
|
||||||
|
|
||||||
|
Released at 2023-03-25
|
||||||
|
|
||||||
|
**v1.87.x is a line of LTS releases (e.g. long-time support). It contains important up-to-date bugfixes.
|
||||||
|
The v1.87.x line will be supported for at least 12 months since [v1.87.0](https://docs.victoriametrics.com/CHANGELOG.html#v1870) release**
|
||||||
|
|
||||||
|
* BUGFIX: prevent from slow [snapshot creating](https://docs.victoriametrics.com/#how-to-work-with-snapshots) under high data ingestion rate. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3551).
|
||||||
|
* BUGFIX: [vmauth](https://docs.victoriametrics.com/vmauth.html): suppress [proxy protocol](https://www.haproxy.org/download/2.3/doc/proxy-protocol.txt) parsing errors in case of `EOF`. Usually, the error is caused by health checks and is not a sign of an actual error.
|
||||||
|
* BUGFIX: [vmbackup](https://docs.victoriametrics.com/vmbackup.html): fix snapshot not being deleted in case of error during backup. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2055).
|
||||||
|
* BUGFIX: allow using dashes and dots in environment variables names referred in config files via `%{ENV-VAR.SYNTAX}`. See [these docs](https://docs.victoriametrics.com/#environment-variables) and [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3999).
|
||||||
|
* BUGFIX: return back query performance scalability on hosts with big number of CPU cores. The scalability has been reduced in [v1.86.0](https://docs.victoriametrics.com/CHANGELOG.html#v1860). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3966).
|
||||||
|
|
||||||
|
|
||||||
|
## [v1.87.3](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.87.3)
|
||||||
|
|
||||||
|
Released at 2023-03-12
|
||||||
|
|
||||||
|
**v1.87.x is a line of LTS releases (e.g. long-time support). It contains important up-to-date bugfixes.
|
||||||
|
The v1.87.x line will be supported for at least 12 months since [v1.87.0](https://docs.victoriametrics.com/CHANGELOG.html#v1870) release**
|
||||||
|
|
||||||
|
* SECURITY: upgrade Go builder from Go1.20.1 to Go1.20.2. See [the list of issues addressed in Go1.20.2](https://github.com/golang/go/issues?q=milestone%3AGo1.20.2+label%3ACherryPickApproved).
|
||||||
|
|
||||||
|
* BUGFIX: vmstorage: fix a bug, which could lead to incomplete or empty results for heavy queries selecting tens of thousands of time series. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3946).
|
||||||
|
* BUGFIX: vmselect: reduce memory usage and CPU usage when performing heavy queries. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3692).
|
||||||
|
* BUGFIX: prevent from possible `invalid memory address or nil pointer dereference` panic during [background merge](https://docs.victoriametrics.com/#storage). The issue has been introduced at [v1.85.0](https://docs.victoriametrics.com/CHANGELOG.html#v1850). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3897).
|
||||||
|
* BUGFIX: prevent from possible `SIGBUS` crash on ARM architectures (Raspberry Pi), which deny unaligned access to 8-byte words. Thanks to @oliverpool for narrowing down the issue and for [the initial attempt to fix it](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3927).
|
||||||
|
* BUGFIX: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): always return `is_partial: true` in partial responses. Previously partial responses could be returned as non-partial in some cases.
|
||||||
|
* BUGFIX: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): properly take into account `-rpc.disableCompression` command-line flag at `vmstorage`. It was ignored since [v1.78.0](https://docs.victoriametrics.com/CHANGELOG.html#v1780). See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3932).
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): do not register `vm_promscrape_config_*` metrics if `-promscrape.config` flag is not used. Previously those metrics were registered and never updated, which was confusing and could trigger false-positive alerts.
|
||||||
|
* BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): skip measurements with no fields when migrating data from influxdb. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3837).
|
||||||
|
* BUGFIX: [vmauth](https://docs.victoriametrics.com/vmauth.html): fix `cannot serve http` panic when plain HTTP request is sent to `vmauth` configured to accept requests over [proxy protocol](https://www.haproxy.org/download/2.3/doc/proxy-protocol.txt)-encoded request (e.g. when `vmauth` runs with `-httpListenAddr.useProxyProtocol` command-line flag). The issue has been introduced at [v1.87.0](https://docs.victoriametrics.com/CHANGELOG.html#v1870) when implementing [this feature](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3335).
|
||||||
|
|
||||||
|
## [v1.87.2](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.87.2)
|
||||||
|
|
||||||
|
Released at 2023-02-24
|
||||||
|
|
||||||
|
**v1.87.x is a line of LTS releases (e.g. long-time support). It contains important up-to-date bugfixes.
|
||||||
|
The v1.87.x line will be supported for at least 12 months since [v1.87.0](https://docs.victoriametrics.com/CHANGELOG.html#v1870) release**
|
||||||
|
|
||||||
|
* SECURITY: upgrade base docker image (alpine) from 3.17.1 to 3.17.2. See [alpine 3.17.2 release notes](https://alpinelinux.org/posts/Alpine-3.17.2-released.html).
|
||||||
|
* SECURITY: upgrade Go builder from Go1.20.0 to Go1.20.1. See [the list of issues addressed in Go1.20.1](https://github.com/golang/go/issues?q=milestone%3AGo1.20.1+label%3ACherryPickApproved).
|
||||||
|
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): immediately cancel in-flight scrape requests during configuration reload when [stream parsing mode](https://docs.victoriametrics.com/vmagent.html#stream-parsing-mode) is disabled. Previously `vmagent` could wait for long time until all the in-flight requests are completed before reloading the configuration. This could significantly slow down configuration reload. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3747).
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): do not wait for 2 seconds after the first unsuccessful attempt to scrape the target before performing the next attempt. This should improve scrape speed when the target closes [http keep-alive connection](https://en.wikipedia.org/wiki/HTTP_persistent_connection) between scrapes. See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3293) and [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3747) issues.
|
||||||
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): fix [Azure service discovery](https://docs.victoriametrics.com/sd_configs.html#azure_sd_configs) inside [Azure Container App](https://learn.microsoft.com/en-us/azure/container-apps/overview). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3830). Thanks to @MattiasAng for the fix!
|
||||||
|
* BUGFIX: do not put auxiliary directories scheduled for removal into snapshots. This should prevent from `cannot create hard links from ...must-remove...` errors when making snapshots / backups. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3858).
|
||||||
|
* BUGFIX: prevent from possible data ingestion slowdown and query performance slowdown during [background merges of big parts](https://docs.victoriametrics.com/#storage) on systems with small number of CPU cores (1 or 2 CPU cores). The issue has been introduced in [v1.85.0](https://docs.victoriametrics.com/CHANGELOG.html#v1850) when implementing [this feature](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3337). See also [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3790).
|
||||||
|
* BUGFIX: properly parse timestamps in milliseconds when [ingesting data via OpenTSDB telnet put protocol](https://docs.victoriametrics.com/#sending-data-via-telnet-put-protocol). Previously timestamps in milliseconds were mistakenly multiplied by 1000. Thanks to @Droxenator for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3810).
|
||||||
|
* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): do not add extrapolated points outside the real points when using [interpolate()](https://docs.victoriametrics.com/MetricsQL.html#interpolate) function. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3816).
|
||||||
|
|
||||||
## [v1.87.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.87.1)
|
## [v1.87.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.87.1)
|
||||||
|
|
||||||
@@ -520,6 +657,18 @@ Released at 2022-08-08
|
|||||||
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): properly show date picker at `Table` tab. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2874).
|
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): properly show date picker at `Table` tab. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2874).
|
||||||
* BUGFIX: properly generate http redirects if `-http.pathPrefix` command-line flag is set. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2918).
|
* BUGFIX: properly generate http redirects if `-http.pathPrefix` command-line flag is set. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2918).
|
||||||
|
|
||||||
|
## [v1.79.9](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.79.9)
|
||||||
|
|
||||||
|
Released at 2023-02-24
|
||||||
|
|
||||||
|
**v1.79.x is a line of LTS releases (e.g. long-time support). It contains important up-to-date bugfixes.
|
||||||
|
The v1.79.x line will be supported for at least 12 months since [v1.79.0](https://docs.victoriametrics.com/CHANGELOG.html#v1790) release**
|
||||||
|
|
||||||
|
* SECURITY: upgrade base docker image (alpine) from 3.17.1 to 3.17.2. See [alpine 3.17.2 release notes](https://alpinelinux.org/posts/Alpine-3.17.2-released.html).
|
||||||
|
* SECURITY: upgrade Go builder from Go1.20.0 to Go1.20.1. See [the list of issues addressed in Go1.20.1](https://github.com/golang/go/issues?q=milestone%3AGo1.20.1+label%3ACherryPickApproved).
|
||||||
|
|
||||||
|
* BUGFIX: properly parse timestamps in milliseconds when [ingesting data via OpenTSDB telnet put protocol](https://docs.victoriametrics.com/#sending-data-via-telnet-put-protocol). Previously timestamps in milliseconds were mistakenly multiplied by 1000. Thanks to @Droxenator for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3810).
|
||||||
|
|
||||||
## [v1.79.8](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.79.8)
|
## [v1.79.8](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.79.8)
|
||||||
|
|
||||||
Released at 2023-02-03
|
Released at 2023-02-03
|
||||||
|
|||||||
@@ -1224,7 +1224,7 @@ Below is the output for `/path/to/vmstorage -help`:
|
|||||||
|
|
||||||
```
|
```
|
||||||
-bigMergeConcurrency int
|
-bigMergeConcurrency int
|
||||||
The maximum number of CPU cores to use for big merges. Default value is used if set to 0
|
Deprecated: this flag does nothing. Please use -smallMergeConcurrency for controlling the concurrency of background merges. See https://docs.victoriametrics.com/#storage
|
||||||
-cacheExpireDuration duration
|
-cacheExpireDuration duration
|
||||||
Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
|
Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
|
||||||
-cluster.tls
|
-cluster.tls
|
||||||
@@ -1355,7 +1355,7 @@ Below is the output for `/path/to/vmstorage -help`:
|
|||||||
-search.maxUniqueTimeseries int
|
-search.maxUniqueTimeseries int
|
||||||
The maximum number of unique time series, which can be scanned during every query. This allows protecting against heavy queries, which select unexpectedly high number of series. Zero means 'no limit'. See also -search.max* command-line flags at vmselect
|
The maximum number of unique time series, which can be scanned during every query. This allows protecting against heavy queries, which select unexpectedly high number of series. Zero means 'no limit'. See also -search.max* command-line flags at vmselect
|
||||||
-smallMergeConcurrency int
|
-smallMergeConcurrency int
|
||||||
The maximum number of CPU cores to use for small merges. Default value is used if set to 0
|
The maximum number of workers for background merges. See https://docs.victoriametrics.com/#storage . It isn't recommended tuning this flag in general case, since this may lead to uncontrolled increase in the number of parts and increased CPU usage during queries
|
||||||
-snapshotAuthKey string
|
-snapshotAuthKey string
|
||||||
authKey, which must be passed in query string to /snapshot* pages
|
authKey, which must be passed in query string to /snapshot* pages
|
||||||
-snapshotsMaxAge value
|
-snapshotsMaxAge value
|
||||||
|
|||||||
@@ -2131,7 +2131,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
|
|||||||
|
|
||||||
```
|
```
|
||||||
-bigMergeConcurrency int
|
-bigMergeConcurrency int
|
||||||
The maximum number of CPU cores to use for big merges. Default value is used if set to 0
|
Deprecated: this flag does nothing. Please use -smallMergeConcurrency for controlling the concurrency of background merges. See https://docs.victoriametrics.com/#storage
|
||||||
-cacheExpireDuration duration
|
-cacheExpireDuration duration
|
||||||
Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
|
Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
|
||||||
-configAuthKey string
|
-configAuthKey string
|
||||||
@@ -2470,7 +2470,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
|
|||||||
-selfScrapeJob string
|
-selfScrapeJob string
|
||||||
Value for 'job' label, which is added to self-scraped metrics (default "victoria-metrics")
|
Value for 'job' label, which is added to self-scraped metrics (default "victoria-metrics")
|
||||||
-smallMergeConcurrency int
|
-smallMergeConcurrency int
|
||||||
The maximum number of CPU cores to use for small merges. Default value is used if set to 0
|
The maximum number of workers for background merges. See https://docs.victoriametrics.com/#storage . It isn't recommended tuning this flag in general case, since this may lead to uncontrolled increase in the number of parts and increased CPU usage during queries
|
||||||
-snapshotAuthKey string
|
-snapshotAuthKey string
|
||||||
authKey, which must be passed in query string to /snapshot* pages
|
authKey, which must be passed in query string to /snapshot* pages
|
||||||
-snapshotsMaxAge value
|
-snapshotsMaxAge value
|
||||||
|
|||||||
@@ -2134,7 +2134,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
|
|||||||
|
|
||||||
```
|
```
|
||||||
-bigMergeConcurrency int
|
-bigMergeConcurrency int
|
||||||
The maximum number of CPU cores to use for big merges. Default value is used if set to 0
|
Deprecated: this flag does nothing. Please use -smallMergeConcurrency for controlling the concurrency of background merges. See https://docs.victoriametrics.com/#storage
|
||||||
-cacheExpireDuration duration
|
-cacheExpireDuration duration
|
||||||
Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
|
Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
|
||||||
-configAuthKey string
|
-configAuthKey string
|
||||||
@@ -2473,7 +2473,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
|
|||||||
-selfScrapeJob string
|
-selfScrapeJob string
|
||||||
Value for 'job' label, which is added to self-scraped metrics (default "victoria-metrics")
|
Value for 'job' label, which is added to self-scraped metrics (default "victoria-metrics")
|
||||||
-smallMergeConcurrency int
|
-smallMergeConcurrency int
|
||||||
The maximum number of CPU cores to use for small merges. Default value is used if set to 0
|
The maximum number of workers for background merges. See https://docs.victoriametrics.com/#storage . It isn't recommended tuning this flag in general case, since this may lead to uncontrolled increase in the number of parts and increased CPU usage during queries
|
||||||
-snapshotAuthKey string
|
-snapshotAuthKey string
|
||||||
authKey, which must be passed in query string to /snapshot* pages
|
authKey, which must be passed in query string to /snapshot* pages
|
||||||
-snapshotsMaxAge value
|
-snapshotsMaxAge value
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_azure_subscription_id`: the subscription ID
|
* `__meta_azure_subscription_id`: the subscription ID
|
||||||
* `__meta_azure_tenant_id`: the tenant ID
|
* `__meta_azure_tenant_id`: the tenant ID
|
||||||
|
|
||||||
|
The list of discovered Azure targets is refreshed at the interval, which can be configured via `-promscrape.azureSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## consul_sd_configs
|
## consul_sd_configs
|
||||||
|
|
||||||
@@ -173,6 +174,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_consul_tagpresent_<tagname>`: "true" for every <tagname> tag of the target
|
* `__meta_consul_tagpresent_<tagname>`: "true" for every <tagname> tag of the target
|
||||||
* `__meta_consul_tags`: the list of tags of the target joined by the `tag_separator`
|
* `__meta_consul_tags`: the list of tags of the target joined by the `tag_separator`
|
||||||
|
|
||||||
|
The list of discovered Consul targets is refreshed at the interval, which can be configured via `-promscrape.consulSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## digitalocean_sd_configs
|
## digitalocean_sd_configs
|
||||||
|
|
||||||
@@ -211,6 +213,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_digitalocean_tags`: the comma-separated list of tags of the droplet
|
* `__meta_digitalocean_tags`: the comma-separated list of tags of the droplet
|
||||||
* `__meta_digitalocean_vpc`: the id of the droplet's VPC
|
* `__meta_digitalocean_vpc`: the id of the droplet's VPC
|
||||||
|
|
||||||
|
The list of discovered DigitalOcean targets is refreshed at the interval, which can be configured via `-promscrape.digitaloceanSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## dns_sd_configs
|
## dns_sd_configs
|
||||||
|
|
||||||
@@ -243,6 +246,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_dns_srv_record_port`: the port field of the SRV record
|
* `__meta_dns_srv_record_port`: the port field of the SRV record
|
||||||
* `__meta_dns_mx_record_target`: the target field of the MX record.
|
* `__meta_dns_mx_record_target`: the target field of the MX record.
|
||||||
|
|
||||||
|
The list of discovered DNS targets is refreshed at the interval, which can be configured via `-promscrape.dnsSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## docker_sd_configs
|
## docker_sd_configs
|
||||||
|
|
||||||
@@ -293,6 +297,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_docker_port_public`: the external port if a port-mapping exists
|
* `__meta_docker_port_public`: the external port if a port-mapping exists
|
||||||
* `__meta_docker_port_public_ip`: the public IP if a port-mapping exists
|
* `__meta_docker_port_public_ip`: the public IP if a port-mapping exists
|
||||||
|
|
||||||
|
The list of discovered Docker targets is refreshed at the interval, which can be configured via `-promscrape.dockerSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## dockerswarm_sd_configs
|
## dockerswarm_sd_configs
|
||||||
|
|
||||||
@@ -413,6 +418,7 @@ One of the following roles can be configured to discover targets:
|
|||||||
* `__meta_dockerswarm_node_role`: the role of the node
|
* `__meta_dockerswarm_node_role`: the role of the node
|
||||||
* `__meta_dockerswarm_node_status`: the status of the node
|
* `__meta_dockerswarm_node_status`: the status of the node
|
||||||
|
|
||||||
|
The list of discovered Docker Swarm targets is refreshed at the interval, which can be configured via `-promscrape.dockerswarmSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## ec2_sd_configs
|
## ec2_sd_configs
|
||||||
|
|
||||||
@@ -491,6 +497,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_ec2_tag_<tagkey>`: each tag value of the instance
|
* `__meta_ec2_tag_<tagkey>`: each tag value of the instance
|
||||||
* `__meta_ec2_vpc_id`: the ID of the VPC in which the instance is running, if available
|
* `__meta_ec2_vpc_id`: the ID of the VPC in which the instance is running, if available
|
||||||
|
|
||||||
|
The list of discovered EC2 targets is refreshed at the interval, which can be configured via `-promscrape.ec2SDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## eureka_sd_configs
|
## eureka_sd_configs
|
||||||
|
|
||||||
@@ -531,11 +538,11 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_eureka_app_instance_datacenterinfo_name`: the datacenter name of the app instance
|
* `__meta_eureka_app_instance_datacenterinfo_name`: the datacenter name of the app instance
|
||||||
* `__meta_eureka_app_instance_datacenterinfo_metadata_<metadataname>`: the datacenter metadata
|
* `__meta_eureka_app_instance_datacenterinfo_metadata_<metadataname>`: the datacenter metadata
|
||||||
|
|
||||||
|
The list of discovered Eureka targets is refreshed at the interval, which can be configured via `-promscrape.eurekaSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## file_sd_configs
|
## file_sd_configs
|
||||||
|
|
||||||
File-based service discovery reads a set of files with lists of targets to scrape.
|
File-based service discovery reads a set of files with lists of targets to scrape.
|
||||||
Scrape targets are automatically updated when the underlying files are changed with the interval
|
|
||||||
|
|
||||||
Configuration example:
|
Configuration example:
|
||||||
|
|
||||||
@@ -583,6 +590,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
|
|
||||||
See the [list of integrations](https://prometheus.io/docs/operating/integrations/#file-service-discovery) with `file_sd_configs`.
|
See the [list of integrations](https://prometheus.io/docs/operating/integrations/#file-service-discovery) with `file_sd_configs`.
|
||||||
|
|
||||||
|
The list of discovered file-based targets is refreshed at the interval, which can be configured via `-promscrape.fileSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## gce_sd_configs
|
## gce_sd_configs
|
||||||
|
|
||||||
@@ -639,6 +647,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_gce_tags`: list of instance tags separated by tag_separator
|
* `__meta_gce_tags`: list of instance tags separated by tag_separator
|
||||||
* `__meta_gce_zone`: the GCE zone URL in which the instance is running
|
* `__meta_gce_zone`: the GCE zone URL in which the instance is running
|
||||||
|
|
||||||
|
The list of discovered GCE targets is refreshed at the interval, which can be configured via `-promscrape.gceSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## http_sd_configs
|
## http_sd_configs
|
||||||
|
|
||||||
@@ -679,6 +688,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
|
|
||||||
* `__meta_url`: the URL from which the target was extracted
|
* `__meta_url`: the URL from which the target was extracted
|
||||||
|
|
||||||
|
The list of discovered HTTP-based targets is refreshed at the interval, which can be configured via `-promscrape.httpSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## kubernetes_sd_configs
|
## kubernetes_sd_configs
|
||||||
|
|
||||||
@@ -872,6 +882,8 @@ One of the following `role` types can be configured to discover targets:
|
|||||||
* `__meta_kubernetes_ingress_scheme`: Protocol scheme of ingress, https if TLS config is set. Defaults to http.
|
* `__meta_kubernetes_ingress_scheme`: Protocol scheme of ingress, https if TLS config is set. Defaults to http.
|
||||||
* `__meta_kubernetes_ingress_path`: Path from ingress spec. Defaults to `/`.
|
* `__meta_kubernetes_ingress_path`: Path from ingress spec. Defaults to `/`.
|
||||||
|
|
||||||
|
The list of discovered Kuberntes targets is refreshed at the interval, which can be configured via `-promscrape.kubernetesSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## nomad_sd_configs
|
## nomad_sd_configs
|
||||||
|
|
||||||
Nomad SD configuration allows retrieving scrape targets from [HashiCorp Nomad Services](https://www.hashicorp.com/blog/nomad-service-discovery).
|
Nomad SD configuration allows retrieving scrape targets from [HashiCorp Nomad Services](https://www.hashicorp.com/blog/nomad-service-discovery).
|
||||||
@@ -927,6 +939,8 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_nomad_tagpresent_<tagname>`: "true" for every <tagname> tag of the target
|
* `__meta_nomad_tagpresent_<tagname>`: "true" for every <tagname> tag of the target
|
||||||
* `__meta_nomad_tags`: the list of tags of the target joined by the `tag_separator`
|
* `__meta_nomad_tags`: the list of tags of the target joined by the `tag_separator`
|
||||||
|
|
||||||
|
The list of discovered Nomad targets is refreshed at the interval, which can be configured via `-promscrape.nomadSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## openstack_sd_configs
|
## openstack_sd_configs
|
||||||
|
|
||||||
OpenStack SD configuration allows retrieving scrape targets from [OpenStack Nova](https://docs.openstack.org/nova/latest/) instances.
|
OpenStack SD configuration allows retrieving scrape targets from [OpenStack Nova](https://docs.openstack.org/nova/latest/) instances.
|
||||||
@@ -1035,6 +1049,7 @@ One of the following `role` types can be configured to discover targets:
|
|||||||
* `__meta_openstack_tag_<tagkey>`: each tag value of the instance.
|
* `__meta_openstack_tag_<tagkey>`: each tag value of the instance.
|
||||||
* `__meta_openstack_user_id`: the user account owning the tenant.
|
* `__meta_openstack_user_id`: the user account owning the tenant.
|
||||||
|
|
||||||
|
The list of discovered OpenStack targets is refreshed at the interval, which can be configured via `-promscrape.openstackSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## static_configs
|
## static_configs
|
||||||
|
|
||||||
@@ -1136,6 +1151,7 @@ The following meta labels are available on discovered targets during [relabeling
|
|||||||
* `__meta_yandexcloud_instance_private_dns_<record number>`: if configured DNS records for private IP
|
* `__meta_yandexcloud_instance_private_dns_<record number>`: if configured DNS records for private IP
|
||||||
* `__meta_yandexcloud_instance_public_dns_<record number>`: if configured DNS records for public IP
|
* `__meta_yandexcloud_instance_public_dns_<record number>`: if configured DNS records for public IP
|
||||||
|
|
||||||
|
The list of discovered Yandex Cloud targets is refreshed at the interval, which can be configured via `-promscrape.yandexcloudSDCheckInterval` command-line flag.
|
||||||
|
|
||||||
## scrape_configs
|
## scrape_configs
|
||||||
|
|
||||||
@@ -1208,7 +1224,8 @@ scrape_configs:
|
|||||||
# If honor_timestamps is set to "false", the timestamps of the metrics exposed
|
# If honor_timestamps is set to "false", the timestamps of the metrics exposed
|
||||||
# by the target will be ignored.
|
# by the target will be ignored.
|
||||||
#
|
#
|
||||||
# By default honor_timestamps is set to true.
|
# By default, honor_timestamps is set to false.
|
||||||
|
# See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4697#issuecomment-1656540535 for details.
|
||||||
# honor_timestamps: <boolean>
|
# honor_timestamps: <boolean>
|
||||||
|
|
||||||
# scheme configures the protocol scheme used for requests.
|
# scheme configures the protocol scheme used for requests.
|
||||||
|
|||||||
147
go.mod
147
go.mod
@@ -3,117 +3,126 @@ module github.com/VictoriaMetrics/VictoriaMetrics
|
|||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/storage v1.29.0
|
cloud.google.com/go/storage v1.32.0
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.1
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0
|
||||||
github.com/VictoriaMetrics/fastcache v1.12.0
|
github.com/VictoriaMetrics/fastcache v1.12.1
|
||||||
|
|
||||||
// Do not use the original github.com/valyala/fasthttp because of issues
|
// Do not use the original github.com/valyala/fasthttp because of issues
|
||||||
// like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b
|
// like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b
|
||||||
github.com/VictoriaMetrics/fasthttp v1.1.0
|
github.com/VictoriaMetrics/fasthttp v1.2.0
|
||||||
github.com/VictoriaMetrics/metrics v1.23.1
|
github.com/VictoriaMetrics/metrics v1.24.0
|
||||||
github.com/VictoriaMetrics/metricsql v0.51.2
|
github.com/VictoriaMetrics/metricsql v0.56.2
|
||||||
github.com/aws/aws-sdk-go-v2 v1.17.4
|
github.com/aws/aws-sdk-go-v2 v1.21.0
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.18.12
|
github.com/aws/aws-sdk-go-v2/config v1.18.38
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.51
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.82
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.30.2
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5
|
||||||
github.com/cespare/xxhash/v2 v2.2.0
|
github.com/cespare/xxhash/v2 v2.2.0
|
||||||
github.com/cheggaaa/pb/v3 v3.1.0
|
github.com/cheggaaa/pb/v3 v3.1.4
|
||||||
github.com/gogo/protobuf v1.3.2
|
github.com/gogo/protobuf v1.3.2
|
||||||
github.com/golang/snappy v0.0.4
|
github.com/golang/snappy v0.0.4
|
||||||
github.com/googleapis/gax-go/v2 v2.7.0
|
github.com/googleapis/gax-go/v2 v2.12.0
|
||||||
github.com/influxdata/influxdb v1.11.0
|
github.com/influxdata/influxdb v1.11.2
|
||||||
github.com/klauspost/compress v1.15.15
|
github.com/klauspost/compress v1.16.7
|
||||||
github.com/prometheus/prometheus v0.42.0
|
github.com/prometheus/prometheus v0.46.0
|
||||||
github.com/urfave/cli/v2 v2.24.3
|
github.com/urfave/cli/v2 v2.25.7
|
||||||
github.com/valyala/fastjson v1.6.4
|
github.com/valyala/fastjson v1.6.4
|
||||||
github.com/valyala/fastrand v1.1.0
|
github.com/valyala/fastrand v1.1.0
|
||||||
github.com/valyala/fasttemplate v1.2.2
|
github.com/valyala/fasttemplate v1.2.2
|
||||||
github.com/valyala/gozstd v1.17.0
|
github.com/valyala/gozstd v1.20.1
|
||||||
github.com/valyala/histogram v1.2.0
|
github.com/valyala/histogram v1.2.0
|
||||||
github.com/valyala/quicktemplate v1.7.0
|
github.com/valyala/quicktemplate v1.7.0
|
||||||
golang.org/x/net v0.6.0
|
golang.org/x/net v0.14.0
|
||||||
golang.org/x/oauth2 v0.5.0
|
golang.org/x/oauth2 v0.11.0
|
||||||
golang.org/x/sys v0.5.0
|
golang.org/x/sys v0.11.0
|
||||||
google.golang.org/api v0.109.0
|
google.golang.org/api v0.138.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.109.0 // indirect
|
cloud.google.com/go v0.110.7 // indirect
|
||||||
cloud.google.com/go/compute v1.18.0 // indirect
|
cloud.google.com/go/compute v1.23.0 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
cloud.google.com/go/iam v0.10.0 // indirect
|
cloud.google.com/go/iam v1.1.2 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1 // indirect
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
|
||||||
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect
|
||||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
||||||
github.com/aws/aws-sdk-go v1.44.198 // indirect
|
github.com/aws/aws-sdk-go v1.45.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.12 // indirect
|
github.com/aws/aws-sdk-go-v2/credentials v1.13.36 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.22 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.29 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.19 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.23 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.13.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.18.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 // indirect
|
||||||
github.com/aws/smithy-go v1.13.5 // indirect
|
github.com/aws/smithy-go v1.14.2 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/dennwc/varint v1.0.0 // indirect
|
github.com/dennwc/varint v1.0.0 // indirect
|
||||||
github.com/fatih/color v1.14.1 // indirect
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||||
github.com/go-kit/log v0.2.1 // indirect
|
github.com/go-kit/log v0.2.1 // indirect
|
||||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||||
github.com/go-logr/logr v1.2.3 // indirect
|
github.com/go-logr/logr v1.2.4 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/s2a-go v0.1.5 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.2 // indirect
|
github.com/google/uuid v1.3.1 // indirect
|
||||||
|
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
|
||||||
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect
|
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
github.com/jpillora/backoff v1.0.0 // indirect
|
github.com/jpillora/backoff v1.0.0 // indirect
|
||||||
|
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||||
github.com/oklog/ulid v1.3.1 // indirect
|
github.com/oklog/ulid v1.3.1 // indirect
|
||||||
|
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
github.com/prometheus/client_golang v1.16.0 // indirect
|
||||||
github.com/prometheus/client_model v0.3.0 // indirect
|
github.com/prometheus/client_model v0.4.0 // indirect
|
||||||
github.com/prometheus/common v0.39.0 // indirect
|
github.com/prometheus/common v0.44.0 // indirect
|
||||||
github.com/prometheus/common/sigv4 v0.1.0 // indirect
|
github.com/prometheus/common/sigv4 v0.1.0 // indirect
|
||||||
github.com/prometheus/procfs v0.9.0 // indirect
|
github.com/prometheus/procfs v0.11.1 // indirect
|
||||||
github.com/rivo/uniseg v0.4.3 // indirect
|
github.com/rivo/uniseg v0.4.4 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/stretchr/testify v1.8.1 // indirect
|
github.com/stretchr/testify v1.8.4 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.39.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.13.0 // indirect
|
go.opentelemetry.io/otel v1.17.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v0.36.0 // indirect
|
go.opentelemetry.io/otel/metric v1.17.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.13.0 // indirect
|
go.opentelemetry.io/otel/trace v1.17.0 // indirect
|
||||||
go.uber.org/atomic v1.10.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
go.uber.org/goleak v1.2.0 // indirect
|
go.uber.org/goleak v1.2.1 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect
|
golang.org/x/crypto v0.12.0 // indirect
|
||||||
golang.org/x/sync v0.1.0 // indirect
|
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
|
||||||
golang.org/x/text v0.7.0 // indirect
|
golang.org/x/sync v0.3.0 // indirect
|
||||||
|
golang.org/x/text v0.12.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc // indirect
|
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||||
google.golang.org/grpc v1.53.0 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||||
|
google.golang.org/grpc v1.57.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.31.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
419
go.sum
419
go.sum
@@ -13,23 +13,22 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
|
|||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||||
cloud.google.com/go v0.109.0 h1:38CZoKGlCnPZjGdyj0ZfpoGae0/wgNfy5F0byyxg0Gk=
|
cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o=
|
||||||
cloud.google.com/go v0.109.0/go.mod h1:2sYycXt75t/CSB5R9M2wPU1tJmire7AQZTPtITcGBVE=
|
cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||||
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
|
cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
|
||||||
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
|
cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||||
cloud.google.com/go/iam v0.10.0 h1:fpP/gByFs6US1ma53v7VxhvbJpO2Aapng6wabJ99MuI=
|
cloud.google.com/go/iam v1.1.2 h1:gacbrBdWcoVmGLozRuStX45YKvJtzIjJdAolzUs1sm4=
|
||||||
cloud.google.com/go/iam v0.10.0/go.mod h1:nXAECrMt2qHpF6RZUZseteD6QyanL68reN4OXPw0UWM=
|
cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
|
||||||
cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||||
@@ -39,39 +38,41 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
|||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI=
|
cloud.google.com/go/storage v1.32.0 h1:5w6DxEGOnktmJHarxAOUywxVW9lbNWIzlzzUltG/3+o=
|
||||||
cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=
|
cloud.google.com/go/storage v1.32.0/go.mod h1:Hhh/dogNRGca7IWv1RC2YqEn0c0G77ctA/OxflYkiD8=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw=
|
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.1 h1:gVXuXcWd1i4C2Ruxe321aU+IKGaStvGB/S90PUPB/W8=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.1/go.mod h1:DffdKW9RFqa5VgmsjUOsS7UE7eiA5iAvYUs63bhKQ0M=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1 h1:LNHhpdK7hzUcx/k1LIcuh5k7k1LGIWLQfCjaneSj7Fc=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1/go.mod h1:uE9zaUfEQT/nbQjVi2IblCG9iaLtZsuYZ8ne+PuQ02M=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 h1:u/LLAOFgsMv7HmNL4Qufg58y+qElGOt5qv0z1mURkRY=
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0/go.mod h1:2e8rMJtl2+2j+HXbTBwnyGpm5Nou7KhvSfxOq8JpTag=
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0 h1:Ma67P/GGprNwsslzEH6+Kb8nybI8jpDTm4Wmzu2ReK8=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0 h1:nVocQV40OQne5613EeLayJiRAJuKlBGy+m22qWG+WRg=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0/go.mod h1:7QJP7dr2wznCMeqIrhMgWGf7XpAQnVrJqDm9nvV3Cu4=
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||||
github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM=
|
github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.22 h1:/GblQdIudfEM3AWWZ0mrYJQSd7JS4S/Mbzh6F0ov0Xc=
|
github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8=
|
||||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||||
github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk=
|
github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk=
|
||||||
github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac=
|
github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac=
|
||||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 h1:BWe8a+f/t+7KY7zH2mqygeUD0t8hNFXe08p1Pb3/jKE=
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 h1:hVeq+yCyUi+MsoO/CU95yqCIcdzra5ovzk8Q2BBpV2M=
|
||||||
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
|
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||||
github.com/VictoriaMetrics/fastcache v1.12.0 h1:vnVi/y9yKDcD9akmc4NqAoqgQhJrOwUF+j9LTgn4QDE=
|
github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40=
|
||||||
github.com/VictoriaMetrics/fastcache v1.12.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8=
|
github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o=
|
||||||
github.com/VictoriaMetrics/fasthttp v1.1.0 h1:3crd4YWHsMwu60GUXRH6OstowiFvqrwS4a/ueoLdLL0=
|
github.com/VictoriaMetrics/fasthttp v1.2.0 h1:nd9Wng4DlNtaI27WlYh5mGXCJOmee/2c2blTJwfyU9I=
|
||||||
github.com/VictoriaMetrics/fasthttp v1.1.0/go.mod h1:/7DMcogqd+aaD3G3Hg5kFgoFwlR2uydjiWvoLp5ZTqQ=
|
github.com/VictoriaMetrics/fasthttp v1.2.0/go.mod h1:zv5YSmasAoSyv8sBVexfArzFDIGGTN4TfCKAtAw7IfE=
|
||||||
github.com/VictoriaMetrics/metrics v1.18.1/go.mod h1:ArjwVz7WpgpegX/JpB0zpNF2h2232kErkEnzH1sxMmA=
|
github.com/VictoriaMetrics/metrics v1.18.1/go.mod h1:ArjwVz7WpgpegX/JpB0zpNF2h2232kErkEnzH1sxMmA=
|
||||||
github.com/VictoriaMetrics/metrics v1.23.1 h1:/j8DzeJBxSpL2qSIdqnRFLvQQhbJyJbbEi22yMm7oL0=
|
github.com/VictoriaMetrics/metrics v1.24.0 h1:ILavebReOjYctAGY5QU2F9X0MYvkcrG3aEn2RKa1Zkw=
|
||||||
github.com/VictoriaMetrics/metrics v1.23.1/go.mod h1:rAr/llLpEnAdTehiNlUxKgnjcOuROSzpw0GvjpEbvFc=
|
github.com/VictoriaMetrics/metrics v1.24.0/go.mod h1:eFT25kvsTidQFHb6U0oa0rTrDRdz4xTYjpL8+UPohys=
|
||||||
github.com/VictoriaMetrics/metricsql v0.51.2 h1:GCbxti0I46x3Ld/WhcUyawvLr6J0x90IaMftkjosHJI=
|
github.com/VictoriaMetrics/metricsql v0.56.2 h1:quBAbYOlWMhmdgzFSCr1yjtVcdZYZrVQJ7nR9zor7ZM=
|
||||||
github.com/VictoriaMetrics/metricsql v0.51.2/go.mod h1:6pP1ZeLVJHqJrHlF6Ij3gmpQIznSsgktEcZgsAWYel0=
|
github.com/VictoriaMetrics/metricsql v0.56.2/go.mod h1:6pP1ZeLVJHqJrHlF6Ij3gmpQIznSsgktEcZgsAWYel0=
|
||||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
|
||||||
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||||
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
@@ -85,92 +86,100 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah
|
|||||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||||
github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
|
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
|
||||||
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||||
github.com/aws/aws-sdk-go v1.44.198 h1:kgnvxQv4/kP5M0nbxBx0Ac0so9ndr9f8Ti0g+NmPQF8=
|
github.com/aws/aws-sdk-go v1.45.1 h1:PXuxDZIo/Y9Bvtg2t055+dY4hRwNAEcq6bUMv9fXcjk=
|
||||||
github.com/aws/aws-sdk-go v1.44.198/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
github.com/aws/aws-sdk-go v1.45.1/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.17.4 h1:wyC6p9Yfq6V2y98wfDsj6OnNQa4w2BLGCLIxzNhwOGY=
|
github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.17.4/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
|
github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.18.12 h1:fKs/I4wccmfrNRO9rdrbMO1NgLxct6H9rNMiPdBxHWw=
|
github.com/aws/aws-sdk-go-v2/config v1.18.38 h1:CByQCELMgm2tM1lAehx3XNg0R/pfeXsYzqn0Aq2chJQ=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.18.12/go.mod h1:J36fOhj1LQBr+O4hJCiT8FwVvieeoSGOtPuvhKlsNu8=
|
github.com/aws/aws-sdk-go-v2/config v1.18.38/go.mod h1:vNm9Hf5VgG2fSUWhT3zFrqN/RosGcabFMYgiSoxKFU8=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.12 h1:Cb+HhuEnV19zHRaYYVglwvdHGMJWbdsyP4oHhw04xws=
|
github.com/aws/aws-sdk-go-v2/credentials v1.13.36 h1:ps0cPswZjpsOk6sLwG6fdXTzrYjCplgPEyG3OUbbdqE=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.12/go.mod h1:37HG2MBroXK3jXfxVGtbM2J48ra2+Ltu+tmwr/jO0KA=
|
github.com/aws/aws-sdk-go-v2/credentials v1.13.36/go.mod h1:sY2phUzxbygoyDtTXhqi7GjGjCQ1S5a5Rj8u3ksBxCg=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.22 h1:3aMfcTmoXtTZnaT86QlVaYh+BRMbvrrmZwIQ5jWqCZQ=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 h1:uDZJF1hu0EVT/4bogChk8DyjSF6fof6uL/0Y26Ma7Fg=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.22/go.mod h1:YGSIJyQ6D6FjKMQh16hVFSIUD54L4F7zTGePqYMYYJU=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11/go.mod h1:TEPP4tENqBGO99KwVpV9MlOX4NSrSLP8u3KRy2CDwA8=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.51 h1:iTFYCAdKzSAjGnVIUe88Hxvix0uaBqr0Rv7qJEOX5hE=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.82 h1:gPh2fLhr1kwH2HXFhs1kCblIgHTabqE1N9gwYPhS/fw=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.51/go.mod h1:7Grl2gV+dx9SWrUIgwwlUvU40t7+lOSbx34XwfmsTkY=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.82/go.mod h1:4pzmxw8ZmkpbvGqrmedWaXuDL2xcABews1VLYqe9Djk=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 h1:r+XwaCLpIvCKjBIYy/HVZujQS9tsz5ohHG3ZIe0wKoE=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28/go.mod h1:3lwChorpIM/BhImY/hy+Z6jekmN92cXGPI1QJasVPYY=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22 h1:7AwGYXDdqRQYsluvKFmWoqpcOQJ4bH634SkYf3FNj/A=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22/go.mod h1:EqK7gVrIGAHyZItrD1D8B0ilgwMD1GiWAmbU4u/JHNk=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.29 h1:J4xhFd6zHhdF9jPP0FQJ6WknzBboGMBNjKOv4iTuw4A=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 h1:GPUcE/Yq7Ur8YSUk6lVkoIMWnJNO0HT18GUzCWCgCI0=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.29/go.mod h1:TwuqRBGzxjQJIwH16/fOZodwXt2Zxa9/cwJC5ke4j7s=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42/go.mod h1:rzfdUlfA+jdgLDmPKjd3Chq9V7LVLYo1Nz++Wb91aRo=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.19 h1:FGvpyTg2LKEmMrLlpjOgkoNp9XF5CGeyAyo33LdqZW8=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 h1:6lJvvkQ9HmbHZ4h/IEwclwv2mrTW8Uq1SOB/kXy0mfw=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.19/go.mod h1:8W88sW3PjamQpKFUQvHWWKay6ARsNvZnzU7+a4apubw=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4/go.mod h1:1PrKYwxTM+zjpw9Y41KFtoJCQrJ34Z47Y4VgVbfndjo=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 h1:m0QTSI6pZYJTk5WSKx3fm5cNW/DCicVzULBgU/6IyD0=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14/go.mod h1:dDilntgHy9WnHXsh7dDtUPgHKEfTJIBUTHM8OWm0f/0=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.23 h1:c5+bNdV8E4fIPteWx4HZSkqI07oY9exbfQ7JH7Yx4PI=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 h1:eev2yZX7esGRjqRbnVk1UxMLw4CyVZDpZXRCcy75oQk=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.23/go.mod h1:1jcUfF+FAOEwtIcNiHPaV4TSoZqkUIPzrohmD7fb95c=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36/go.mod h1:lGnOkH9NJATw0XEPcAknFBj3zzNTEGRHtSw+CwC1YTg=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22 h1:LjFQf8hFuMO22HkV5VWGLBvmCLBCLPivUAmpdpnp4Vs=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22/go.mod h1:xt0Au8yPIwYXf/GYPy/vl4K3CgwhfQMYbrH7DlUUIws=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22 h1:ISLJ2BKXe4zzyZ7mp5ewKECiw0U7KpLgS3S6OxY9Cm0=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 h1:v0jkRigbSD6uOdwcaUQmgEwG1BkPfAPDqaeNt/29ghg=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22/go.mod h1:QFVbqK54XArazLvn2wvWMRBi/jGrWii46qbr5DyPGjc=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4/go.mod h1:LhTyt8J04LL+9cIt7pYJ5lbS/U98ZmXovLOR/4LUsk8=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.30.2 h1:5EQWIFO+Hc8E2hFcXQJ1vm6ufl/PMt/6RVRDZRju2vM=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5 h1:A42xdtStObqy7NGvzZKpnyNXvoOmm+FENobZ0/ssHWk=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.30.2/go.mod h1:SXDHd6fI2RhqB7vmAzyYQCTQnpZrIprVJvYxpzW3JAM=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5/go.mod h1:rDGMZA7f4pbmTtPOk5v5UM2lmX6UAbRnMDJeDvnH7AM=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.1 h1:lQKN/LNa3qqu2cDOQZybP7oL4nMGGiFqob0jZJaR8/4=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.13.6 h1:2PylFCfKCEDv6PeSN09pC/VUiRd10wi1VfHG5FrW0/g=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.1/go.mod h1:IgV8l3sj22nQDd5qcAGY0WenwCzCphqdbFOpfktZPrI=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.13.6/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.1 h1:0bLhH6DRAqox+g0LatcjGKjjhU6Eudyys6HB6DJVPj8=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 h1:dnInJb4S0oy8aQuri1mV6ipLlnZPfnsDNB9BGO9PDNY=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.1/go.mod h1:O1YSOg3aekZibh2SngvCRRG+cRHKKlYgxf/JBF/Kr/k=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5/go.mod h1:yygr8ACQRY2PrEcy3xsUI357stq2AxnFM6DIsR9lij4=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.18.3 h1:s49mSnsBZEXjfGBkRfmK+nPqzT7Lt3+t2SmAKNyHblw=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 h1:CQBFElb0LS8RojMJlxRSo/HXipvTZW2S44Lt9Mk2aYQ=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.18.3/go.mod h1:b+psTJn33Q4qGoDaM7ZiOVVG8uVjGI6HaZ8WBHdgDgU=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.21.5/go.mod h1:VC7JDqsqiwXukYEDjoHh9U0fOJtNWh04FPQz4ct4GGU=
|
||||||
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
|
github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ=
|
||||||
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cheggaaa/pb/v3 v3.1.0 h1:3uouEsl32RL7gTiQsuaXD4Bzbfl5tGztXGUvXbs4O04=
|
github.com/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo=
|
||||||
github.com/cheggaaa/pb/v3 v3.1.0/go.mod h1:YjrevcBqadFDaGQKRdmZxTY42pXEqda48Ea3lt0K/BE=
|
github.com/cheggaaa/pb/v3 v3.1.4/go.mod h1:6wVjILNBaXMs8c21qRiaUM8BR82erfgau1DQ4iUXmSA=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b h1:ACGZRIr7HsgBKHsueQ1yM4WaVaXh21ynwqsF8M8tXhA=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
|
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||||
|
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
|
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
|
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
|
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
|
github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
|
||||||
github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
|
github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
|
||||||
github.com/digitalocean/godo v1.95.0 h1:S48/byPKui7RHZc1wYEPfRvkcEvToADNb5I3guu95xg=
|
github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E=
|
||||||
github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c=
|
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||||
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||||
github.com/docker/docker v20.10.23+incompatible h1:1ZQUUYAdh+oylOT85aA2ZcfRp22jmLhoaEcVEfK8dyA=
|
github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI=
|
||||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
|
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
|
||||||
github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
|
github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/go-control-plane v0.10.3 h1:xdCVXxEe0Y3FQith+0cj2irwZudqGYvecuLB1HtdexY=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.9.1 h1:PS7VIOgmSVhWUEeZwTe7z7zouA22Cr590PzXKbZHOVY=
|
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
|
||||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||||
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
|
||||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
@@ -185,21 +194,23 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
|
|||||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
|
||||||
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
|
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||||
github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 h1:JVrqSeQfdhYRFk24TvhTZWU0q8lfCojxZQFi3Ou7+uY=
|
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
|
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
|
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
|
||||||
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
|
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
@@ -228,14 +239,15 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
|||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
|
github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
@@ -255,7 +267,7 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
|||||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ=
|
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
@@ -264,39 +276,42 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
|
|||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
|
github.com/google/s2a-go v0.1.5 h1:8IYp3w9nysqv3JH+NJgXJzGbDHzLOTj43BmSkp+O7qg=
|
||||||
|
github.com/google/s2a-go v0.1.5/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.2 h1:jUqbmxlR+gGPQq/uvQviKpS1bSQecfs2t7o6F14sk9s=
|
github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.2/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=
|
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
|
||||||
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
|
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
|
||||||
github.com/gophercloud/gophercloud v1.1.1 h1:MuGyqbSxiuVBqkPZ3+Nhbytk1xZxhmfCB2Rg1cJWFWM=
|
github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo=
|
||||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww=
|
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww=
|
||||||
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A=
|
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A=
|
||||||
github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/hashicorp/cronexpr v1.1.1 h1:NJZDd87hGXjoZBdvyCF9mX4DCq5Wy7+A/w+A7q0wn6c=
|
github.com/hashicorp/consul/api v1.22.0 h1:ydEvDooB/A0c/xpsBd8GSt7P2/zYPBui4KrNip0xGjE=
|
||||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A=
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||||
github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs=
|
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
||||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ=
|
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
|
||||||
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4=
|
github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4=
|
||||||
github.com/hashicorp/nomad/api v0.0.0-20230124213148-69fd1a0e4bf7 h1:XOdd3JHyeQnBRxotBo9ibxBFiYGuYhQU25s/YeV2cTU=
|
github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e h1:sr4lujmn9heD030xx/Pd4B/JSmvRhFzuotNXaaV0WLs=
|
||||||
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
|
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
|
||||||
github.com/hetznercloud/hcloud-go v1.39.0 h1:RUlzI458nGnPR6dlcZlrsGXYC1hQlFbKdm8tVtEQQB0=
|
github.com/hetznercloud/hcloud-go/v2 v2.0.0 h1:Sg1DJ+MAKvbYAqaBaq9tPbwXBS2ckPIaMtVdUjKu+4g=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||||
github.com/influxdata/influxdb v1.11.0 h1:0X+ZsbcOWc6AEi5MHee9BYqXCKmz8IZsljrRYjmV8Qg=
|
github.com/influxdata/influxdb v1.11.2 h1:qOF3uQN1mDfJNEKwbAgJsqehf8IXgKok2vlGm736oGo=
|
||||||
github.com/influxdata/influxdb v1.11.0/go.mod h1:V93tJcidY0Zh0LtSONZWnXXGDyt20dtVf+Ddp4EnhaA=
|
github.com/influxdata/influxdb v1.11.2/go.mod h1:eUMkLTE2vQwvSk6KGMrTBLKPaqSuczuelGbggigMPFw=
|
||||||
github.com/ionos-cloud/sdk-go/v6 v6.1.3 h1:vb6yqdpiqaytvreM0bsn2pXw+1YDvEk2RKSmBAQvgDQ=
|
github.com/ionos-cloud/sdk-go/v6 v6.1.8 h1:493wE/BkZxJf7x79UCE0cYGPZoqQcPiEBALvt7uVGY0=
|
||||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||||
@@ -316,34 +331,32 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
|||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||||
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||||
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
|
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||||
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
|
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/linode/linodego v1.12.0 h1:33mOIrZ+gVva14gyJMKPZ85mQGovAvZCEP1ftgmFBjA=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
|
github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YUw=
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
@@ -360,69 +373,74 @@ github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
|||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||||
github.com/ovh/go-ovh v1.3.0 h1:mvZaddk4E4kLcXhzb+cxBsMPYp2pHqiQpWYkInsuZPQ=
|
github.com/ovh/go-ovh v1.4.1 h1:VBGa5wMyQtTP7Zb+w97zRCh9sLtM/2YKRyy+MEJmWaM=
|
||||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||||
|
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||||
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
||||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||||
github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||||
github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI=
|
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
|
||||||
github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y=
|
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
|
||||||
github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4=
|
github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4=
|
||||||
github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI=
|
github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
|
||||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
|
||||||
github.com/prometheus/prometheus v0.42.0 h1:G769v8covTkOiNckXFIwLx01XE04OE6Fr0JPA0oR2nI=
|
github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73vCMk/Kw=
|
||||||
github.com/prometheus/prometheus v0.42.0/go.mod h1:Pfqb/MLnnR2KK+0vchiaH39jXxvLMBk+3lnIGP4N7Vk=
|
github.com/prometheus/prometheus v0.46.0/go.mod h1:10L5IJE5CEsjee1FnOcVswYXlPIscDWWt3IJ2UDYrz4=
|
||||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
|
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||||
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.12 h1:Aaz4T7dZp7cB2cv7D/tGtRdSMh48sRaDYr7Jh0HV4qQ=
|
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.19 h1:+1H+N9QFl2Sfvia0FBYfMrHYHYhmpZxhSE0wpPL2lYs=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/urfave/cli/v2 v2.24.3 h1:7Q1w8VN8yE0MJEHP06bv89PjYsN4IHWED2s1v/Zlfm0=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/urfave/cli/v2 v2.24.3/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
|
||||||
|
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
|
github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
|
||||||
@@ -432,8 +450,8 @@ github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G
|
|||||||
github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ=
|
github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ=
|
||||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
github.com/valyala/gozstd v1.17.0 h1:M4Ds4MIrw+pD+s6vYtuFZ8D3iEw9htzfdytOV3C3iQU=
|
github.com/valyala/gozstd v1.20.1 h1:xPnnnvjmaDDitMFfDxmQ4vpx0+3CdTg2o3lALvXTU/g=
|
||||||
github.com/valyala/gozstd v1.17.0/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ=
|
github.com/valyala/gozstd v1.20.1/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ=
|
||||||
github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ=
|
github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ=
|
||||||
github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY=
|
github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY=
|
||||||
github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM=
|
github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM=
|
||||||
@@ -454,18 +472,19 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.39.0 h1:vFEBG7SieZJzvnRWQ81jxpuEqe6J8Ex+hgc9CqOTzHc=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0 h1:HKORGpiOY0R0nAPtKx/ub8/7XoHhRooP8yNRkuPfelI=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.39.0/go.mod h1:9rgTcOKdIhDOC0IcAu8a+R+FChqSUBihKpM1lVNi6T0=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0/go.mod h1:e+y1M74SYXo/FcIx3UATwth2+5dDkM8dBi7eXg1tbw8=
|
||||||
go.opentelemetry.io/otel v1.13.0 h1:1ZAKnNQKwBBxFtww/GwxNUyTf0AxkZzrukO8MeXqe4Y=
|
go.opentelemetry.io/otel v1.17.0 h1:MW+phZ6WZ5/uk2nd93ANk/6yJ+dVrvNWUjGhnnFU5jM=
|
||||||
go.opentelemetry.io/otel v1.13.0/go.mod h1:FH3RtdZCzRkJYFTCsAKDy9l/XYjMdNv6QrkFFB8DvVg=
|
go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0=
|
||||||
go.opentelemetry.io/otel/metric v0.36.0 h1:t0lgGI+L68QWt3QtOIlqM9gXoxqxWLhZ3R/e5oOAY0Q=
|
go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc=
|
||||||
go.opentelemetry.io/otel/metric v0.36.0/go.mod h1:wKVw57sd2HdSZAzyfOM9gTqqE8v7CbqWsYL6AyrH9qk=
|
go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o=
|
||||||
go.opentelemetry.io/otel/trace v1.13.0 h1:CBgRZ6ntv+Amuj1jDsMhZtlAPT6gbyIRdaIzFhfBSdY=
|
go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ=
|
||||||
go.opentelemetry.io/otel/trace v1.13.0/go.mod h1:muCvmmO9KKpvuXSf3KKAXXB2ygNYHQ+ZfI5X08d3tds=
|
go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY=
|
||||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
|
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
||||||
|
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
@@ -474,7 +493,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||||
|
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@@ -485,8 +506,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg=
|
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
|
||||||
golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
@@ -499,7 +520,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
|||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
@@ -509,7 +529,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
|||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -543,18 +563,19 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||||
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
|
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
|
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
|
||||||
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
|
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -566,8 +587,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -585,7 +606,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -607,18 +627,19 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||||
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -626,9 +647,10 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@@ -677,7 +699,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
|
|||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4=
|
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -700,8 +722,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
|
|||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||||
google.golang.org/api v0.109.0 h1:sW9hgHyX497PP5//NUM7nqfV8D0iDfBApqq7sOh1XR8=
|
google.golang.org/api v0.138.0 h1:K/tVp05MxNVbHShRw9m7e9VJGdagNeTdMzqPH7AUqr0=
|
||||||
google.golang.org/api v0.109.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
|
google.golang.org/api v0.138.0/go.mod h1:4xyob8CxC+0GChNBvEUAk8VBKNvYOTWM9T3v3UfRxuY=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
@@ -733,14 +755,19 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG
|
|||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc h1:ijGwO+0vL2hJt5gaygqP2j6PfflOBrRot0IczKbmtio=
|
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY=
|
||||||
google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
@@ -753,9 +780,12 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
|
|||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
|
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||||
|
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
|
||||||
|
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
@@ -768,8 +798,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
|||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@@ -777,9 +807,10 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
|
|||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||||
gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
@@ -796,16 +827,16 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ=
|
k8s.io/api v0.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y=
|
||||||
k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ=
|
k8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM=
|
||||||
k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU=
|
k8s.io/client-go v0.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8=
|
||||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
||||||
k8s.io/kube-openapi v0.0.0-20221207184640-f3cff1453715 h1:tBEbstoM+K0FiBV5KGAKQ0kuvf54v/hwpldiJt69w1s=
|
k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515 h1:OmK1d0WrkD3IPfkskvroRykOulHVHf0s0ZIFRjyt+UI=
|
||||||
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y=
|
k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk=
|
||||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||||
|
|||||||
@@ -24,12 +24,7 @@ func (t *Token) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewToken returns new Token for the given authToken.
|
// NewToken returns new Token for the given authToken.
|
||||||
//
|
|
||||||
// If authToken == "multitenant", then nil Token is returned.
|
|
||||||
func NewToken(authToken string) (*Token, error) {
|
func NewToken(authToken string) (*Token, error) {
|
||||||
if authToken == "multitenant" {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
var t Token
|
var t Token
|
||||||
if err := t.Init(authToken); err != nil {
|
if err := t.Init(authToken); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -37,6 +32,16 @@ func NewToken(authToken string) (*Token, error) {
|
|||||||
return &t, nil
|
return &t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewTokenPossibleMultitenant returns new Token for the given authToken.
|
||||||
|
//
|
||||||
|
// If authToken == "multitenant", then nil Token is returned.
|
||||||
|
func NewTokenPossibleMultitenant(authToken string) (*Token, error) {
|
||||||
|
if authToken == "multitenant" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return NewToken(authToken)
|
||||||
|
}
|
||||||
|
|
||||||
// Init initializes t from authToken.
|
// Init initializes t from authToken.
|
||||||
func (t *Token) Init(authToken string) error {
|
func (t *Token) Init(authToken string) error {
|
||||||
tmp := strings.Split(authToken, ":")
|
tmp := strings.Split(authToken, ":")
|
||||||
|
|||||||
@@ -26,6 +26,24 @@ func TestNewTokenSuccess(t *testing.T) {
|
|||||||
f("1:4294967295", "1:4294967295")
|
f("1:4294967295", "1:4294967295")
|
||||||
// max uint32 accountID and projectID
|
// max uint32 accountID and projectID
|
||||||
f("4294967295:4294967295", "4294967295:4294967295")
|
f("4294967295:4294967295", "4294967295:4294967295")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewTokenPossibleMultitenantSuccess(t *testing.T) {
|
||||||
|
f := func(token string, want string) {
|
||||||
|
t.Helper()
|
||||||
|
newToken, err := NewTokenPossibleMultitenant(token)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
got := newToken.String()
|
||||||
|
if got != want {
|
||||||
|
t.Fatalf("unexpected NewToken() result;got\n%s\nwant\n%s", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// token with accountID only
|
||||||
|
f("1", "1")
|
||||||
|
// token with accountID and projecTID
|
||||||
|
f("1:2", "1:2")
|
||||||
// multitenant
|
// multitenant
|
||||||
f("multitenant", "multitenant")
|
f("multitenant", "multitenant")
|
||||||
}
|
}
|
||||||
@@ -75,4 +93,6 @@ func TestNewTokenFailure(t *testing.T) {
|
|||||||
f("a:b:c")
|
f("a:b:c")
|
||||||
// many int parts in the token"
|
// many int parts in the token"
|
||||||
f("1:2:3")
|
f("1:2:3")
|
||||||
|
// multitenant
|
||||||
|
f("multitenant")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package actions
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -194,7 +195,7 @@ func NewRemoteFS(path string) (common.RemoteFS, error) {
|
|||||||
return nil, fmt.Errorf("dir must be absolute; got %q", dir)
|
return nil, fmt.Errorf("dir must be absolute; got %q", dir)
|
||||||
}
|
}
|
||||||
fs := &fsremote.FS{
|
fs := &fsremote.FS{
|
||||||
Dir: dir,
|
Dir: filepath.Clean(dir),
|
||||||
}
|
}
|
||||||
return fs, nil
|
return fs, nil
|
||||||
case "gcs", "gs":
|
case "gcs", "gs":
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func TestMarshalUnmarshalInt64Array(t *testing.T) {
|
|||||||
v += int64(r.NormFloat64() * 1e6)
|
v += int64(r.NormFloat64() * 1e6)
|
||||||
va = append(va, v)
|
va = append(va, v)
|
||||||
}
|
}
|
||||||
for precisionBits := uint8(1); precisionBits < 17; precisionBits++ {
|
for precisionBits := uint8(1); precisionBits < 14; precisionBits++ {
|
||||||
testMarshalUnmarshalInt64Array(t, va, precisionBits, MarshalTypeZSTDNearestDelta)
|
testMarshalUnmarshalInt64Array(t, va, precisionBits, MarshalTypeZSTDNearestDelta)
|
||||||
}
|
}
|
||||||
for precisionBits := uint8(23); precisionBits < 65; precisionBits++ {
|
for precisionBits := uint8(23); precisionBits < 65; precisionBits++ {
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ func ParseFlagSet(fs *flag.FlagSet, args []string) {
|
|||||||
// Do not use lib/logger here, since it is uninitialized yet.
|
// Do not use lib/logger here, since it is uninitialized yet.
|
||||||
log.Fatalf("cannot parse flags %q: %s", args, err)
|
log.Fatalf("cannot parse flags %q: %s", args, err)
|
||||||
}
|
}
|
||||||
|
if fs.NArg() > 0 {
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4845
|
||||||
|
log.Fatalf("unprocessed command-line args left: %s; the most likely reason is missing `=` between boolean flag name and value; "+
|
||||||
|
"see https://pkg.go.dev/flag#hdr-Command_line_flag_syntax", fs.Args())
|
||||||
|
}
|
||||||
if !*enable {
|
if !*enable {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,4 +113,7 @@ func isValidEnvVarName(s string) bool {
|
|||||||
return envVarNameRegex.MatchString(s)
|
return envVarNameRegex.MatchString(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
var envVarNameRegex = regexp.MustCompile("^[a-zA-Z0-9_]+$")
|
// envVarNameRegex is used for validating environment variable names.
|
||||||
|
//
|
||||||
|
// Allow dashes and dots in env var names - see https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3999
|
||||||
|
var envVarNameRegex = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_\-.]*$`)
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ func TestExpandTemplates(t *testing.T) {
|
|||||||
f([]string{"foo=%{bar}", "bar=x"}, []string{"bar=x", "foo=x"})
|
f([]string{"foo=%{bar}", "bar=x"}, []string{"bar=x", "foo=x"})
|
||||||
f([]string{"a=x%{b}", "b=y%{c}z%{d}", "c=123", "d=qwe"}, []string{"a=xy123zqwe", "b=y123zqwe", "c=123", "d=qwe"})
|
f([]string{"a=x%{b}", "b=y%{c}z%{d}", "c=123", "d=qwe"}, []string{"a=xy123zqwe", "b=y123zqwe", "c=123", "d=qwe"})
|
||||||
f([]string{"a=x%{b}y", "b=z%{a}q", "c"}, []string{"a=xzxzxzxz%{a}qyqyqyqy", "b=zxzxzxzx%{b}yqyqyqyq", "c="})
|
f([]string{"a=x%{b}y", "b=z%{a}q", "c"}, []string{"a=xzxzxzxz%{a}qyqyqyqy", "b=zxzxzxzx%{b}yqyqyqyq", "c="})
|
||||||
f([]string{"a=%{x.y}"}, []string{"a=%{x.y}"})
|
f([]string{"a=%{x.y}", "x.y=test"}, []string{"a=test", "x.y=test"})
|
||||||
|
f([]string{"a=%{x y}"}, []string{"a=%{x y}"})
|
||||||
|
f([]string{"a=%{123}"}, []string{"a=%{123}"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLookupEnv(t *testing.T) {
|
func TestLookupEnv(t *testing.T) {
|
||||||
@@ -49,7 +51,9 @@ func TestLookupEnv(t *testing.T) {
|
|||||||
|
|
||||||
func TestReplaceSuccess(t *testing.T) {
|
func TestReplaceSuccess(t *testing.T) {
|
||||||
envVars = map[string]string{
|
envVars = map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
|
"foo.bar_1": "baz",
|
||||||
|
"foo-bar_2": "test",
|
||||||
}
|
}
|
||||||
f := func(s, resultExpected string) {
|
f := func(s, resultExpected string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
@@ -71,7 +75,8 @@ func TestReplaceSuccess(t *testing.T) {
|
|||||||
f("", "")
|
f("", "")
|
||||||
f("foo", "foo")
|
f("foo", "foo")
|
||||||
f("a %{foo}-x", "a bar-x")
|
f("a %{foo}-x", "a bar-x")
|
||||||
f("%{foo.bar}", "%{foo.bar}")
|
f("%{foo.bar_1}", "baz")
|
||||||
|
f("qq.%{foo-bar_2}.ww", "qq.test.ww")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReplaceFailure(t *testing.T) {
|
func TestReplaceFailure(t *testing.T) {
|
||||||
@@ -85,4 +90,7 @@ func TestReplaceFailure(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("foo %{bar} %{baz}")
|
f("foo %{bar} %{baz}")
|
||||||
|
f("%{Foo_Foo_1}")
|
||||||
|
f("%{Foo-Bar-2}")
|
||||||
|
f("%{Foo.Baz.3}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,16 +59,19 @@ func NewArrayBytes(name, description string) *ArrayBytes {
|
|||||||
// -foo=value1 -foo=value2
|
// -foo=value1 -foo=value2
|
||||||
// -foo=value1,value2
|
// -foo=value1,value2
|
||||||
//
|
//
|
||||||
// Flag values may be quoted. For instance, the following arg creates an array of ("a", "b, c") items:
|
// Each flag value may contain commas inside single quotes, double quotes, [], () or {} braces.
|
||||||
|
// For example, -foo=[a,b,c] defines a single command-line flag with `[a,b,c]` value.
|
||||||
//
|
//
|
||||||
// -foo='a,"b, c"'
|
// Flag values may be quoted. For instance, the following arg creates an array of ("a", "b,c") items:
|
||||||
|
//
|
||||||
|
// -foo='a,"b,c"'
|
||||||
type ArrayString []string
|
type ArrayString []string
|
||||||
|
|
||||||
// String implements flag.Value interface
|
// String implements flag.Value interface
|
||||||
func (a *ArrayString) String() string {
|
func (a *ArrayString) String() string {
|
||||||
aEscaped := make([]string, len(*a))
|
aEscaped := make([]string, len(*a))
|
||||||
for i, v := range *a {
|
for i, v := range *a {
|
||||||
if strings.ContainsAny(v, `", `+"\n") {
|
if strings.ContainsAny(v, `,'"{[(`+"\n") {
|
||||||
v = fmt.Sprintf("%q", v)
|
v = fmt.Sprintf("%q", v)
|
||||||
}
|
}
|
||||||
aEscaped[i] = v
|
aEscaped[i] = v
|
||||||
@@ -94,55 +97,105 @@ func parseArrayValues(s string) []string {
|
|||||||
if len(tail) == 0 {
|
if len(tail) == 0 {
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
if tail[0] == ',' {
|
|
||||||
tail = tail[1:]
|
|
||||||
}
|
|
||||||
s = tail
|
s = tail
|
||||||
|
if s[0] == ',' {
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var closeQuotes = map[byte]byte{
|
||||||
|
'"': '"',
|
||||||
|
'\'': '\'',
|
||||||
|
'[': ']',
|
||||||
|
'{': '}',
|
||||||
|
'(': ')',
|
||||||
|
}
|
||||||
|
|
||||||
func getNextArrayValue(s string) (string, string) {
|
func getNextArrayValue(s string) (string, string) {
|
||||||
if len(s) == 0 {
|
v, tail := getNextArrayValueMaybeQuoted(s)
|
||||||
return "", ""
|
if strings.HasPrefix(v, `"`) && strings.HasSuffix(v, `"`) {
|
||||||
|
vUnquoted, err := strconv.Unquote(v)
|
||||||
|
if err == nil {
|
||||||
|
return vUnquoted, tail
|
||||||
|
}
|
||||||
|
v = v[1 : len(v)-1]
|
||||||
|
v = strings.ReplaceAll(v, `\"`, `"`)
|
||||||
|
v = strings.ReplaceAll(v, `\\`, `\`)
|
||||||
|
return v, tail
|
||||||
}
|
}
|
||||||
if s[0] != '"' {
|
if strings.HasPrefix(v, `'`) && strings.HasSuffix(v, `'`) {
|
||||||
// Fast path - unquoted string
|
v = v[1 : len(v)-1]
|
||||||
n := strings.IndexByte(s, ',')
|
v = strings.ReplaceAll(v, `\'`, "'")
|
||||||
|
v = strings.ReplaceAll(v, `\\`, `\`)
|
||||||
|
return v, tail
|
||||||
|
}
|
||||||
|
return v, tail
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNextArrayValueMaybeQuoted(s string) (string, string) {
|
||||||
|
idx := 0
|
||||||
|
for {
|
||||||
|
n := strings.IndexAny(s[idx:], `,"'[{(`)
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
// The last item
|
// The last item
|
||||||
return s, ""
|
return s, ""
|
||||||
}
|
}
|
||||||
return s[:n], s[n:]
|
idx += n
|
||||||
|
ch := s[idx]
|
||||||
|
if ch == ',' {
|
||||||
|
// The next item
|
||||||
|
return s[:idx], s[idx:]
|
||||||
|
}
|
||||||
|
idx++
|
||||||
|
m := indexCloseQuote(s[idx:], closeQuotes[ch])
|
||||||
|
idx += m
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find the end of quoted string
|
func indexCloseQuote(s string, closeQuote byte) int {
|
||||||
end := 1
|
if closeQuote == '"' || closeQuote == '\'' {
|
||||||
ss := s[1:]
|
idx := 0
|
||||||
|
for {
|
||||||
|
n := strings.IndexByte(s[idx:], closeQuote)
|
||||||
|
if n < 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
idx += n
|
||||||
|
if n := getTrailingBackslashesCount(s[:idx]); n%2 == 1 {
|
||||||
|
// The quote is escaped with backslash. Skip it
|
||||||
|
idx++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return idx + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idx := 0
|
||||||
for {
|
for {
|
||||||
n := strings.IndexByte(ss, '"')
|
n := strings.IndexAny(s[idx:], `"'[{()}]`)
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
// Cannot find trailing quote. Return the whole string till the end.
|
return 0
|
||||||
return s, ""
|
|
||||||
}
|
}
|
||||||
end += n + 1
|
idx += n
|
||||||
// Verify whether the trailing quote is escaped with backslash.
|
ch := s[idx]
|
||||||
backslashes := 0
|
if ch == closeQuote {
|
||||||
for n > backslashes && ss[n-backslashes-1] == '\\' {
|
return idx + 1
|
||||||
backslashes++
|
|
||||||
}
|
}
|
||||||
if backslashes&1 == 0 {
|
idx++
|
||||||
// The trailing quote isn't escaped.
|
m := indexCloseQuote(s[idx:], closeQuotes[ch])
|
||||||
break
|
if m == 0 {
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
// The trailing quote is escaped. Continue searching for the next quote.
|
idx += m
|
||||||
ss = ss[n+1:]
|
|
||||||
}
|
}
|
||||||
v := s[:end]
|
}
|
||||||
vUnquoted, err := strconv.Unquote(v)
|
|
||||||
if err == nil {
|
func getTrailingBackslashesCount(s string) int {
|
||||||
v = vUnquoted
|
n := len(s)
|
||||||
|
for n > 0 && s[n-1] == '\\' {
|
||||||
|
n--
|
||||||
}
|
}
|
||||||
return v, s[end:]
|
return len(s) - n
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOptionalArg returns optional arg under the given argIdx.
|
// GetOptionalArg returns optional arg under the given argIdx.
|
||||||
|
|||||||
@@ -53,15 +53,54 @@ func TestArrayString_Set(t *testing.T) {
|
|||||||
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", a, expectedValues)
|
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", a, expectedValues)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Zero args
|
||||||
f("", nil)
|
f("", nil)
|
||||||
|
|
||||||
|
// Single arg
|
||||||
f(`foo`, []string{`foo`})
|
f(`foo`, []string{`foo`})
|
||||||
f(`foo,b ar,baz`, []string{`foo`, `b ar`, `baz`})
|
f(`fo"o`, []string{`fo"o`})
|
||||||
f(`foo,b\"'ar,"baz,d`, []string{`foo`, `b\"'ar`, `"baz,d`})
|
f(`fo'o`, []string{`fo'o`})
|
||||||
f(`,foo,,ba"r,`, []string{``, `foo`, ``, `ba"r`, ``})
|
f(`fo{o`, []string{`fo{o`})
|
||||||
|
f(`fo[o`, []string{`fo[o`})
|
||||||
|
f(`fo(o`, []string{`fo(o`})
|
||||||
|
|
||||||
|
// Single arg with Prometheus label filters
|
||||||
|
f(`foo{bar="baz",x="y"}`, []string{`foo{bar="baz",x="y"}`})
|
||||||
|
f(`foo{bar="ba}z",x="y"}`, []string{`foo{bar="ba}z",x="y"}`})
|
||||||
|
f(`foo{bar='baz',x="y"}`, []string{`foo{bar='baz',x="y"}`})
|
||||||
|
f(`foo{bar='baz',x='y'}`, []string{`foo{bar='baz',x='y'}`})
|
||||||
|
f(`foo{bar='ba}z',x='y'}`, []string{`foo{bar='ba}z',x='y'}`})
|
||||||
|
f(`{foo="ba[r",baz='a'}`, []string{`{foo="ba[r",baz='a'}`})
|
||||||
|
|
||||||
|
// Single arg with JSON
|
||||||
|
f(`[1,2,3]`, []string{`[1,2,3]`})
|
||||||
|
f(`{"foo":"ba,r",baz:x}`, []string{`{"foo":"ba,r",baz:x}`})
|
||||||
|
|
||||||
|
// Single quoted arg
|
||||||
|
f(`"foo"`, []string{`foo`})
|
||||||
|
f(`"fo,'o"`, []string{`fo,'o`})
|
||||||
|
f(`"f\\o,\'\"o"`, []string{`f\o,\'"o`})
|
||||||
|
f(`"foo{bar='baz',x='y'}"`, []string{`foo{bar='baz',x='y'}`})
|
||||||
|
f(`'foo'`, []string{`foo`})
|
||||||
|
f(`'fo,"o'`, []string{`fo,"o`})
|
||||||
|
f(`'f\\o,\'\"o'`, []string{`f\o,'\"o`})
|
||||||
|
f(`'foo{bar="baz",x="y"}'`, []string{`foo{bar="baz",x="y"}`})
|
||||||
|
|
||||||
|
// Multiple args
|
||||||
|
f(`foo,bar,baz`, []string{`foo`, `bar`, `baz`})
|
||||||
|
f(`"foo",'bar',{[(ba'",z"`, []string{`foo`, `bar`, `{[(ba'",z"`})
|
||||||
|
f(`foo,b"'ar,"baz,d`, []string{`foo`, `b"'ar,"baz`, `d`})
|
||||||
|
f(`{foo="b,ar"},baz{x="y",z="d"}`, []string{`{foo="b,ar"}`, `baz{x="y",z="d"}`})
|
||||||
|
|
||||||
|
// Empty args
|
||||||
f(`""`, []string{``})
|
f(`""`, []string{``})
|
||||||
f(`"foo,b\nar"`, []string{`foo,b` + "\n" + `ar`})
|
f(`''`, []string{``})
|
||||||
f(`"foo","bar",baz`, []string{`foo`, `bar`, `baz`})
|
f(`,`, []string{``, ``})
|
||||||
f(`,fo,"\"b, a'\\",,r,`, []string{``, `fo`, `"b, a'\`, ``, `r`, ``})
|
f(`,foo,,ba"r,`, []string{``, `foo`, ``, `ba"r`, ``})
|
||||||
|
|
||||||
|
// Special chars inside double quotes
|
||||||
|
f(`"foo,b\nar"`, []string{"foo,b\nar"})
|
||||||
|
f(`"foo\x23bar"`, []string{"foo\x23bar"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayString_GetOptionalArg(t *testing.T) {
|
func TestArrayString_GetOptionalArg(t *testing.T) {
|
||||||
@@ -100,6 +139,7 @@ func TestArrayString_String(t *testing.T) {
|
|||||||
f(",foo,")
|
f(",foo,")
|
||||||
f(`", foo","b\"ar",`)
|
f(`", foo","b\"ar",`)
|
||||||
f(`,"\nfoo\\",bar`)
|
f(`,"\nfoo\\",bar`)
|
||||||
|
f(`"foo{bar=~\"baz\",a!=\"b\"}","{a='b,{[(c'}"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayDuration(t *testing.T) {
|
func TestArrayDuration(t *testing.T) {
|
||||||
|
|||||||
12
lib/fs/fs.go
12
lib/fs/fs.go
@@ -262,7 +262,7 @@ func MustRemoveTemporaryDirs(dir string) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dirName := fi.Name()
|
dirName := fi.Name()
|
||||||
if strings.Contains(dirName, ".must-remove.") {
|
if IsScheduledForRemoval(dirName) {
|
||||||
fullPath := dir + "/" + dirName
|
fullPath := dir + "/" + dirName
|
||||||
MustRemoveAll(fullPath)
|
MustRemoveAll(fullPath)
|
||||||
}
|
}
|
||||||
@@ -441,6 +441,12 @@ func ReadFileOrHTTP(path string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
data, err := io.ReadAll(resp.Body)
|
data, err := io.ReadAll(resp.Body)
|
||||||
_ = resp.Body.Close()
|
_ = resp.Body.Close()
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
if len(data) > 4*1024 {
|
||||||
|
data = data[:4*1024]
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unexpected status code when fetching %q: %d, expecting %d; response: %q", path, resp.StatusCode, http.StatusOK, data)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot read %q: %s", path, err)
|
return nil, fmt.Errorf("cannot read %q: %s", path, err)
|
||||||
}
|
}
|
||||||
@@ -467,3 +473,7 @@ func isHTTPURL(targetURL string) bool {
|
|||||||
return err == nil && (parsed.Scheme == "http" || parsed.Scheme == "https") && parsed.Host != ""
|
return err == nil && (parsed.Scheme == "http" || parsed.Scheme == "https") && parsed.Host != ""
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsScheduledForRemoval(name string) bool {
|
||||||
|
return strings.Contains(name, ".must-remove.")
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"github.com/VictoriaMetrics/metrics"
|
||||||
@@ -27,8 +28,13 @@ type MustReadAtCloser interface {
|
|||||||
|
|
||||||
// ReaderAt implements rand-access reader.
|
// ReaderAt implements rand-access reader.
|
||||||
type ReaderAt struct {
|
type ReaderAt struct {
|
||||||
|
readCalls uint64
|
||||||
|
readBytes uint64
|
||||||
|
|
||||||
f *os.File
|
f *os.File
|
||||||
mmapData []byte
|
mmapData []byte
|
||||||
|
|
||||||
|
useLocalStats bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustReadAt reads len(p) bytes at off from r.
|
// MustReadAt reads len(p) bytes at off from r.
|
||||||
@@ -56,8 +62,13 @@ func (r *ReaderAt) MustReadAt(p []byte, off int64) {
|
|||||||
// But production workload proved this is OK in most cases, so use it without fear :)
|
// But production workload proved this is OK in most cases, so use it without fear :)
|
||||||
copy(p, src)
|
copy(p, src)
|
||||||
}
|
}
|
||||||
readCalls.Inc()
|
if r.useLocalStats {
|
||||||
readBytes.Add(len(p))
|
atomic.AddUint64(&r.readCalls, 1)
|
||||||
|
atomic.AddUint64(&r.readBytes, uint64(len(p)))
|
||||||
|
} else {
|
||||||
|
readCalls.Inc()
|
||||||
|
readBytes.Add(len(p))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustClose closes r.
|
// MustClose closes r.
|
||||||
@@ -71,9 +82,28 @@ func (r *ReaderAt) MustClose() {
|
|||||||
}
|
}
|
||||||
MustClose(r.f)
|
MustClose(r.f)
|
||||||
r.f = nil
|
r.f = nil
|
||||||
|
|
||||||
|
if r.useLocalStats {
|
||||||
|
readCalls.Add(int(r.readCalls))
|
||||||
|
readBytes.Add(int(r.readBytes))
|
||||||
|
r.readCalls = 0
|
||||||
|
r.readBytes = 0
|
||||||
|
r.useLocalStats = false
|
||||||
|
}
|
||||||
readersCount.Dec()
|
readersCount.Dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetUseLocalStats switches to local stats collection instead of global stats collection.
|
||||||
|
//
|
||||||
|
// This function must be called before the first call to MustReadAt().
|
||||||
|
//
|
||||||
|
// Collecting local stats may improve performance on systems with big number of CPU cores,
|
||||||
|
// since the locally collected stats is pushed to global stats only at MustClose() call
|
||||||
|
// instead of pushing it at every MustReadAt call.
|
||||||
|
func (r *ReaderAt) SetUseLocalStats() {
|
||||||
|
r.useLocalStats = true
|
||||||
|
}
|
||||||
|
|
||||||
// MustFadviseSequentialRead hints the OS that f is read mostly sequentially.
|
// MustFadviseSequentialRead hints the OS that f is read mostly sequentially.
|
||||||
//
|
//
|
||||||
// if prefetch is set, then the OS is hinted to prefetch f data.
|
// if prefetch is set, then the OS is hinted to prefetch f data.
|
||||||
|
|||||||
@@ -320,6 +320,11 @@ func handlerWrapper(s *server, w http.ResponseWriter, r *http.Request, rh Reques
|
|||||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1833
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1833
|
||||||
fmt.Fprintf(w, "VictoriaMetrics is Ready.\n")
|
fmt.Fprintf(w, "VictoriaMetrics is Ready.\n")
|
||||||
return
|
return
|
||||||
|
case "/robots.txt":
|
||||||
|
// This prevents search engines from indexing contents
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4128
|
||||||
|
fmt.Fprintf(w, "User-agent: *\nDisallow: /\n")
|
||||||
|
return
|
||||||
default:
|
default:
|
||||||
if strings.HasPrefix(r.URL.Path, "/debug/pprof/") {
|
if strings.HasPrefix(r.URL.Path, "/debug/pprof/") {
|
||||||
pprofRequests.Inc()
|
pprofRequests.Inc()
|
||||||
|
|||||||
@@ -662,35 +662,20 @@ func (tb *Table) flushInmemoryItems() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tb *Table) flushInmemoryParts(isFinal bool) {
|
func (tb *Table) flushInmemoryParts(isFinal bool) {
|
||||||
for {
|
currentTime := time.Now()
|
||||||
currentTime := time.Now()
|
var pws []*partWrapper
|
||||||
var pws []*partWrapper
|
|
||||||
|
|
||||||
tb.partsLock.Lock()
|
tb.partsLock.Lock()
|
||||||
for _, pw := range tb.inmemoryParts {
|
for _, pw := range tb.inmemoryParts {
|
||||||
if !pw.isInMerge && (isFinal || pw.flushToDiskDeadline.Before(currentTime)) {
|
if !pw.isInMerge && (isFinal || pw.flushToDiskDeadline.Before(currentTime)) {
|
||||||
pw.isInMerge = true
|
pw.isInMerge = true
|
||||||
pws = append(pws, pw)
|
pws = append(pws, pw)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tb.partsLock.Unlock()
|
}
|
||||||
|
tb.partsLock.Unlock()
|
||||||
|
|
||||||
if err := tb.mergePartsOptimal(pws); err != nil {
|
if err := tb.mergePartsOptimal(pws); err != nil {
|
||||||
logger.Panicf("FATAL: cannot merge in-memory parts: %s", err)
|
logger.Panicf("FATAL: cannot merge in-memory parts: %s", err)
|
||||||
}
|
|
||||||
if !isFinal {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tb.partsLock.Lock()
|
|
||||||
n := len(tb.inmemoryParts)
|
|
||||||
tb.partsLock.Unlock()
|
|
||||||
if n == 0 {
|
|
||||||
// All the in-memory parts were flushed to disk.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Some parts weren't flushed to disk because they were being merged.
|
|
||||||
// Sleep for a while and try flushing them again.
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,7 +773,18 @@ func (tb *Table) notifyBackgroundMergers() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var flushConcurrencyCh = make(chan struct{}, cgroup.AvailableCPUs())
|
var flushConcurrencyLimit = func() int {
|
||||||
|
n := cgroup.AvailableCPUs()
|
||||||
|
if n < 2 {
|
||||||
|
// Allow at least 2 concurrent flushers on systems with a single CPU core
|
||||||
|
// in order to guarantee that in-memory data flushes and background merges can be continued
|
||||||
|
// when a single flusher is busy with the long merge.
|
||||||
|
n = 2
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}()
|
||||||
|
|
||||||
|
var flushConcurrencyCh = make(chan struct{}, flushConcurrencyLimit)
|
||||||
|
|
||||||
func needAssistedMerge(pws []*partWrapper, maxParts int) bool {
|
func needAssistedMerge(pws []*partWrapper, maxParts int) bool {
|
||||||
if len(pws) < maxParts {
|
if len(pws) < maxParts {
|
||||||
@@ -927,10 +923,8 @@ func newPartWrapperFromInmemoryPart(mp *inmemoryPart, flushToDiskDeadline time.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tb *Table) startMergeWorkers() {
|
func (tb *Table) startMergeWorkers() {
|
||||||
// Start a merge worker per available CPU core.
|
|
||||||
// The actual number of concurrent merges is limited inside mergeWorker() below.
|
// The actual number of concurrent merges is limited inside mergeWorker() below.
|
||||||
workersCount := cgroup.AvailableCPUs()
|
for i := 0; i < cap(mergeWorkersLimitCh); i++ {
|
||||||
for i := 0; i < workersCount; i++ {
|
|
||||||
tb.wg.Add(1)
|
tb.wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
tb.mergeWorker()
|
tb.mergeWorker()
|
||||||
@@ -1153,14 +1147,6 @@ func (tb *Table) mergeParts(pws []*partWrapper, stopCh <-chan struct{}, isFinal
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot atomically register the created part: %w", err)
|
return fmt.Errorf("cannot atomically register the created part: %w", err)
|
||||||
}
|
}
|
||||||
tb.swapSrcWithDstParts(pws, pwNew, dstPartType)
|
|
||||||
|
|
||||||
d := time.Since(startTime)
|
|
||||||
if d <= 30*time.Second {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log stats for long merges.
|
|
||||||
dstItemsCount := uint64(0)
|
dstItemsCount := uint64(0)
|
||||||
dstBlocksCount := uint64(0)
|
dstBlocksCount := uint64(0)
|
||||||
dstSize := uint64(0)
|
dstSize := uint64(0)
|
||||||
@@ -1172,6 +1158,15 @@ func (tb *Table) mergeParts(pws []*partWrapper, stopCh <-chan struct{}, isFinal
|
|||||||
dstSize = pDst.size
|
dstSize = pDst.size
|
||||||
dstPartPath = pDst.path
|
dstPartPath = pDst.path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tb.swapSrcWithDstParts(pws, pwNew, dstPartType)
|
||||||
|
|
||||||
|
d := time.Since(startTime)
|
||||||
|
if d <= 30*time.Second {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log stats for long merges.
|
||||||
durationSecs := d.Seconds()
|
durationSecs := d.Seconds()
|
||||||
itemsPerSec := int(float64(srcItemsCount) / durationSecs)
|
itemsPerSec := int(float64(srcItemsCount) / durationSecs)
|
||||||
logger.Infof("merged (%d parts, %d items, %d blocks, %d bytes) into (1 part, %d items, %d blocks, %d bytes) in %.3f seconds at %d items/sec to %q",
|
logger.Infof("merged (%d parts, %d items, %d blocks, %d bytes) into (1 part, %d items, %d blocks, %d bytes) in %.3f seconds at %d items/sec to %q",
|
||||||
@@ -1406,7 +1401,18 @@ func (tb *Table) nextMergeIdx() uint64 {
|
|||||||
return atomic.AddUint64(&tb.mergeIdx, 1)
|
return atomic.AddUint64(&tb.mergeIdx, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var mergeWorkersLimitCh = make(chan struct{}, cgroup.AvailableCPUs())
|
var mergeWorkersLimitCh = make(chan struct{}, getWorkersCount())
|
||||||
|
|
||||||
|
func getWorkersCount() int {
|
||||||
|
n := cgroup.AvailableCPUs()
|
||||||
|
if n < 4 {
|
||||||
|
// Allow at least 4 merge workers on systems with small CPUs count
|
||||||
|
// in order to guarantee that background merges can be continued
|
||||||
|
// when multiple workers are busy with big merges.
|
||||||
|
n = 4
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
func openParts(path string) ([]*partWrapper, error) {
|
func openParts(path string) ([]*partWrapper, error) {
|
||||||
// The path can be missing after restoring from backup, so create it if needed.
|
// The path can be missing after restoring from backup, so create it if needed.
|
||||||
@@ -1824,5 +1830,5 @@ func removeParts(pws []*partWrapper, partsToRemove map[*partWrapper]bool) ([]*pa
|
|||||||
func isSpecialDir(name string) bool {
|
func isSpecialDir(name string) bool {
|
||||||
// Snapshots and cache dirs aren't used anymore.
|
// Snapshots and cache dirs aren't used anymore.
|
||||||
// Keep them here for backwards compatibility.
|
// Keep them here for backwards compatibility.
|
||||||
return name == "tmp" || name == "txn" || name == "snapshots" || name == "cache"
|
return name == "tmp" || name == "txn" || name == "snapshots" || name == "cache" || fs.IsScheduledForRemoval(name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,16 +129,12 @@ func TestTableCreateSnapshotAt(t *testing.T) {
|
|||||||
if err := os.RemoveAll(path); err != nil {
|
if err := os.RemoveAll(path); err != nil {
|
||||||
t.Fatalf("cannot remove %q: %s", path, err)
|
t.Fatalf("cannot remove %q: %s", path, err)
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
_ = os.RemoveAll(path)
|
|
||||||
}()
|
|
||||||
|
|
||||||
var isReadOnly uint32
|
var isReadOnly uint32
|
||||||
tb, err := OpenTable(path, nil, nil, &isReadOnly)
|
tb, err := OpenTable(path, nil, nil, &isReadOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot open %q: %s", path, err)
|
t.Fatalf("cannot open %q: %s", path, err)
|
||||||
}
|
}
|
||||||
defer tb.MustClose()
|
|
||||||
|
|
||||||
// Write a lot of items into the table, so background merges would start.
|
// Write a lot of items into the table, so background merges would start.
|
||||||
const itemsCount = 3e5
|
const itemsCount = 3e5
|
||||||
@@ -146,7 +142,14 @@ func TestTableCreateSnapshotAt(t *testing.T) {
|
|||||||
item := []byte(fmt.Sprintf("item %d", i))
|
item := []byte(fmt.Sprintf("item %d", i))
|
||||||
tb.AddItems([][]byte{item})
|
tb.AddItems([][]byte{item})
|
||||||
}
|
}
|
||||||
tb.DebugFlush()
|
|
||||||
|
// Close and open the table in order to flush all the data to disk before creating snapshots.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4272#issuecomment-1550221840
|
||||||
|
tb.MustClose()
|
||||||
|
tb, err = OpenTable(path, nil, nil, &isReadOnly)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("cannot open %q: %s", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
// Create multiple snapshots.
|
// Create multiple snapshots.
|
||||||
snapshot1 := path + "-test-snapshot1"
|
snapshot1 := path + "-test-snapshot1"
|
||||||
@@ -157,30 +160,22 @@ func TestTableCreateSnapshotAt(t *testing.T) {
|
|||||||
if err := tb.CreateSnapshotAt(snapshot2); err != nil {
|
if err := tb.CreateSnapshotAt(snapshot2); err != nil {
|
||||||
t.Fatalf("cannot create snapshot2: %s", err)
|
t.Fatalf("cannot create snapshot2: %s", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
_ = os.RemoveAll(snapshot1)
|
|
||||||
_ = os.RemoveAll(snapshot2)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Verify snapshots contain all the data.
|
// Verify snapshots contain all the data.
|
||||||
tb1, err := OpenTable(snapshot1, nil, nil, &isReadOnly)
|
tb1, err := OpenTable(snapshot1, nil, nil, &isReadOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot open %q: %s", path, err)
|
t.Fatalf("cannot open %q: %s", path, err)
|
||||||
}
|
}
|
||||||
defer tb1.MustClose()
|
|
||||||
|
|
||||||
tb2, err := OpenTable(snapshot2, nil, nil, &isReadOnly)
|
tb2, err := OpenTable(snapshot2, nil, nil, &isReadOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot open %q: %s", path, err)
|
t.Fatalf("cannot open %q: %s", path, err)
|
||||||
}
|
}
|
||||||
defer tb2.MustClose()
|
|
||||||
|
|
||||||
var ts, ts1, ts2 TableSearch
|
var ts, ts1, ts2 TableSearch
|
||||||
ts.Init(tb)
|
ts.Init(tb)
|
||||||
ts1.Init(tb1)
|
ts1.Init(tb1)
|
||||||
defer ts1.MustClose()
|
|
||||||
ts2.Init(tb2)
|
ts2.Init(tb2)
|
||||||
defer ts2.MustClose()
|
|
||||||
for i := 0; i < itemsCount; i++ {
|
for i := 0; i < itemsCount; i++ {
|
||||||
key := []byte(fmt.Sprintf("item %d", i))
|
key := []byte(fmt.Sprintf("item %d", i))
|
||||||
if err := ts.FirstItemWithPrefix(key); err != nil {
|
if err := ts.FirstItemWithPrefix(key); err != nil {
|
||||||
@@ -202,6 +197,17 @@ func TestTableCreateSnapshotAt(t *testing.T) {
|
|||||||
t.Fatalf("unexpected item found for key=%q in snapshot2; got %q", key, ts2.Item)
|
t.Fatalf("unexpected item found for key=%q in snapshot2; got %q", key, ts2.Item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ts1.MustClose()
|
||||||
|
ts2.MustClose()
|
||||||
|
|
||||||
|
// Close and remove tables.
|
||||||
|
tb2.MustClose()
|
||||||
|
tb1.MustClose()
|
||||||
|
tb.MustClose()
|
||||||
|
|
||||||
|
_ = os.RemoveAll(snapshot2)
|
||||||
|
_ = os.RemoveAll(snapshot1)
|
||||||
|
_ = os.RemoveAll(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTableAddItemsConcurrent(t *testing.T) {
|
func TestTableAddItemsConcurrent(t *testing.T) {
|
||||||
|
|||||||
@@ -71,9 +71,14 @@ func readProxyProto(r io.Reader) (net.Addr, error) {
|
|||||||
if version != 2 {
|
if version != 2 {
|
||||||
return nil, fmt.Errorf("unsupported proxy protocol version, only v2 protocol version is supported, got: %d", version)
|
return nil, fmt.Errorf("unsupported proxy protocol version, only v2 protocol version is supported, got: %d", version)
|
||||||
}
|
}
|
||||||
if proto != 1 {
|
// check for supported proto:
|
||||||
// Only TCP is supported (aka STREAM).
|
switch {
|
||||||
return nil, fmt.Errorf("the proxy protocol implementation doesn't support proto %d; expecting 1", proto)
|
case proto == 0 && command == 0:
|
||||||
|
// 0 - UNSPEC with LOCAL command 0. Common use case for load balancer health checks.
|
||||||
|
case proto == 1:
|
||||||
|
// 1 - TCP (aka STREAM).
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("the proxy protocol implementation doesn't support proto %d and command: %d; expecting proto 1 or proto 0 with command 0", proto, command)
|
||||||
}
|
}
|
||||||
// The length of the remainder of the header including any TLVs in network byte order
|
// The length of the remainder of the header including any TLVs in network byte order
|
||||||
// 0, 1, 2
|
// 0, 1, 2
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -78,6 +79,8 @@ type TCPListener struct {
|
|||||||
connMetrics
|
connMetrics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var proxyProtocolReadErrorLogger = logger.WithThrottler("proxyProtocolReadError", 5*time.Second)
|
||||||
|
|
||||||
// Accept accepts connections from the addr passed to NewTCPListener.
|
// Accept accepts connections from the addr passed to NewTCPListener.
|
||||||
func (ln *TCPListener) Accept() (net.Conn, error) {
|
func (ln *TCPListener) Accept() (net.Conn, error) {
|
||||||
for {
|
for {
|
||||||
@@ -94,10 +97,15 @@ func (ln *TCPListener) Accept() (net.Conn, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if ln.useProxyProtocol {
|
if ln.useProxyProtocol {
|
||||||
conn, err = newProxyProtocolConn(conn)
|
pConn, err := newProxyProtocolConn(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
if !errors.Is(err, io.EOF) {
|
||||||
|
proxyProtocolReadErrorLogger.Errorf("cannot read proxy proto conn for TCP addr %q: %s", ln.Addr(), err)
|
||||||
|
}
|
||||||
|
_ = conn.Close()
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
conn = pConn
|
||||||
}
|
}
|
||||||
ln.conns.Inc()
|
ln.conns.Inc()
|
||||||
sc := &statConn{
|
sc := &statConn{
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ func FinalizeLabels(dst, src []prompbmarshal.Label) []prompbmarshal.Label {
|
|||||||
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
||||||
func (prc *parsedRelabelConfig) apply(labels []prompbmarshal.Label, labelsOffset int) []prompbmarshal.Label {
|
func (prc *parsedRelabelConfig) apply(labels []prompbmarshal.Label, labelsOffset int) []prompbmarshal.Label {
|
||||||
src := labels[labelsOffset:]
|
src := labels[labelsOffset:]
|
||||||
if !prc.If.Match(labels) {
|
if !prc.If.Match(src) {
|
||||||
if prc.Action == "keep" {
|
if prc.Action == "keep" {
|
||||||
// Drop the target on `if` mismatch for `action: keep`
|
// Drop the target on `if` mismatch for `action: keep`
|
||||||
return labels[:labelsOffset]
|
return labels[:labelsOffset]
|
||||||
@@ -619,15 +619,28 @@ func fillLabelReferences(dst []byte, replacement string, labels []prompbmarshal.
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// SanitizeName replaces unsupported by Prometheus chars in metric names and label names with _.
|
// SanitizeLabelName replaces unsupported by Prometheus chars in label names with _.
|
||||||
//
|
//
|
||||||
// See https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
|
// See https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
|
||||||
func SanitizeName(name string) string {
|
func SanitizeLabelName(name string) string {
|
||||||
return promSanitizer.Transform(name)
|
return labelNameSanitizer.Transform(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
var promSanitizer = bytesutil.NewFastStringTransformer(func(s string) string {
|
var labelNameSanitizer = bytesutil.NewFastStringTransformer(func(s string) string {
|
||||||
return unsupportedPromChars.ReplaceAllString(s, "_")
|
return unsupportedLabelNameChars.ReplaceAllString(s, "_")
|
||||||
})
|
})
|
||||||
|
|
||||||
var unsupportedPromChars = regexp.MustCompile(`[^a-zA-Z0-9_:]`)
|
var unsupportedLabelNameChars = regexp.MustCompile(`[^a-zA-Z0-9_]`)
|
||||||
|
|
||||||
|
// SanitizeMetricName replaces unsupported by Prometheus chars in metric names with _.
|
||||||
|
//
|
||||||
|
// See https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
|
||||||
|
func SanitizeMetricName(value string) string {
|
||||||
|
return metricNameSanitizer.Transform(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
var metricNameSanitizer = bytesutil.NewFastStringTransformer(func(s string) string {
|
||||||
|
return unsupportedMetricNameChars.ReplaceAllString(s, "_")
|
||||||
|
})
|
||||||
|
|
||||||
|
var unsupportedMetricNameChars = regexp.MustCompile(`[^a-zA-Z0-9_:]`)
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import (
|
|||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promutils"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSanitizeName(t *testing.T) {
|
func TestSanitizeMetricName(t *testing.T) {
|
||||||
f := func(s, resultExpected string) {
|
f := func(s, resultExpected string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
result := SanitizeName(s)
|
result := SanitizeMetricName(s)
|
||||||
if result != resultExpected {
|
if result != resultExpected {
|
||||||
t.Fatalf("unexpected result for SanitizeName(%q) at iteration %d; got %q; want %q", s, i, result, resultExpected)
|
t.Fatalf("unexpected result for SanitizeMetricName(%q) at iteration %d; got %q; want %q", s, i, result, resultExpected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,22 @@ func TestSanitizeName(t *testing.T) {
|
|||||||
f("foo...bar", "foo___bar")
|
f("foo...bar", "foo___bar")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSanitizeLabelName(t *testing.T) {
|
||||||
|
f := func(s, resultExpected string) {
|
||||||
|
t.Helper()
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
result := SanitizeLabelName(s)
|
||||||
|
if result != resultExpected {
|
||||||
|
t.Fatalf("unexpected result for SanitizeLabelName(%q) at iteration %d; got %q; want %q", s, i, result, resultExpected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f("", "")
|
||||||
|
f("a", "a")
|
||||||
|
f("foo.bar/baz:a", "foo_bar_baz_a")
|
||||||
|
f("foo...bar", "foo___bar")
|
||||||
|
}
|
||||||
|
|
||||||
func TestLabelsToString(t *testing.T) {
|
func TestLabelsToString(t *testing.T) {
|
||||||
f := func(labels []prompbmarshal.Label, sExpected string) {
|
f := func(labels []prompbmarshal.Label, sExpected string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|||||||
@@ -8,20 +8,39 @@ import (
|
|||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkSanitizeName(b *testing.B) {
|
func BenchmarkSanitizeMetricName(b *testing.B) {
|
||||||
for _, name := range []string{"", "foo", "foo-bar-baz", "http_requests_total"} {
|
for _, name := range []string{"", "foo", "foo-bar-baz", "http_requests_total"} {
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
benchmarkSanitizeName(b, name)
|
benchmarkSanitizeMetricName(b, name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func benchmarkSanitizeName(b *testing.B, name string) {
|
func benchmarkSanitizeMetricName(b *testing.B, name string) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.SetBytes(1)
|
b.SetBytes(1)
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
sanitizedName := SanitizeName(name)
|
sanitizedName := SanitizeMetricName(name)
|
||||||
|
GlobalSink += len(sanitizedName)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSanitizeLabelName(b *testing.B) {
|
||||||
|
for _, name := range []string{"", "foo", "foo-bar-baz", "http_requests_total"} {
|
||||||
|
b.Run(name, func(b *testing.B) {
|
||||||
|
benchmarkSanitizeLabelName(b, name)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func benchmarkSanitizeLabelName(b *testing.B, name string) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.SetBytes(1)
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
sanitizedName := SanitizeLabelName(name)
|
||||||
GlobalSink += len(sanitizedName)
|
GlobalSink += len(sanitizedName)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||||
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promscrape/discoveryutils"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/proxy"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/proxy"
|
||||||
"github.com/VictoriaMetrics/fasthttp"
|
"github.com/VictoriaMetrics/fasthttp"
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"github.com/VictoriaMetrics/metrics"
|
||||||
@@ -262,7 +263,11 @@ func (c *client) ReadData(dst []byte) ([]byte, error) {
|
|||||||
// This should reduce memory uage when scraping big targets.
|
// This should reduce memory uage when scraping big targets.
|
||||||
dst = resp.SwapBody(dst)
|
dst = resp.SwapBody(dst)
|
||||||
}
|
}
|
||||||
err := doRequestWithPossibleRetry(c.hc, req, resp, deadline)
|
|
||||||
|
ctx, cancel := context.WithDeadline(c.ctx, deadline)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
err := doRequestWithPossibleRetry(ctx, c.hc, req, resp)
|
||||||
statusCode := resp.StatusCode()
|
statusCode := resp.StatusCode()
|
||||||
redirectsCount := 0
|
redirectsCount := 0
|
||||||
for err == nil && isStatusRedirect(statusCode) {
|
for err == nil && isStatusRedirect(statusCode) {
|
||||||
@@ -282,7 +287,7 @@ func (c *client) ReadData(dst []byte) ([]byte, error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
req.URI().UpdateBytes(location)
|
req.URI().UpdateBytes(location)
|
||||||
err = doRequestWithPossibleRetry(c.hc, req, resp, deadline)
|
err = doRequestWithPossibleRetry(ctx, c.hc, req, resp)
|
||||||
statusCode = resp.StatusCode()
|
statusCode = resp.StatusCode()
|
||||||
redirectsCount++
|
redirectsCount++
|
||||||
}
|
}
|
||||||
@@ -349,32 +354,45 @@ var (
|
|||||||
scrapeRetries = metrics.NewCounter(`vm_promscrape_scrape_retries_total`)
|
scrapeRetries = metrics.NewCounter(`vm_promscrape_scrape_retries_total`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func doRequestWithPossibleRetry(hc *fasthttp.HostClient, req *fasthttp.Request, resp *fasthttp.Response, deadline time.Time) error {
|
func doRequestWithPossibleRetry(ctx context.Context, hc *fasthttp.HostClient, req *fasthttp.Request, resp *fasthttp.Response) error {
|
||||||
sleepTime := time.Second
|
|
||||||
scrapeRequests.Inc()
|
scrapeRequests.Inc()
|
||||||
for {
|
|
||||||
// Use DoDeadline instead of Do even if hc.ReadTimeout is already set in order to guarantee the given deadline
|
var reqErr error
|
||||||
// across multiple retries.
|
// Return true if the request execution is completed and retry is not required
|
||||||
err := hc.DoDeadline(req, resp, deadline)
|
attempt := func() bool {
|
||||||
if err == nil {
|
// Use DoCtx instead of Do in order to support context cancellation
|
||||||
|
reqErr = hc.DoCtx(ctx, req, resp)
|
||||||
|
if reqErr == nil {
|
||||||
statusCode := resp.StatusCode()
|
statusCode := resp.StatusCode()
|
||||||
if statusCode != fasthttp.StatusTooManyRequests {
|
if statusCode != fasthttp.StatusTooManyRequests {
|
||||||
return nil
|
return true
|
||||||
}
|
}
|
||||||
} else if err != fasthttp.ErrConnectionClosed && !strings.Contains(err.Error(), "broken pipe") {
|
} else if reqErr != fasthttp.ErrConnectionClosed && !strings.Contains(reqErr.Error(), "broken pipe") {
|
||||||
return err
|
return true
|
||||||
}
|
}
|
||||||
// Retry request after exponentially increased sleep.
|
return false
|
||||||
maxSleepTime := time.Until(deadline)
|
}
|
||||||
if sleepTime > maxSleepTime {
|
|
||||||
return fmt.Errorf("the server closes all the connection attempts: %w", err)
|
if attempt() {
|
||||||
|
return reqErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first attempt was unsuccessful. Use exponential backoff for further attempts.
|
||||||
|
// Perform the second attempt immediately after the first attempt - this should help
|
||||||
|
// in cases when the remote side closes the keep-alive connection before the first attempt.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3293
|
||||||
|
sleepTime := time.Second
|
||||||
|
// It is expected that the deadline is already set to ctx, so the loop below
|
||||||
|
// should eventually finish if all the attempt() calls are unsuccessful.
|
||||||
|
for {
|
||||||
|
scrapeRetries.Inc()
|
||||||
|
if attempt() {
|
||||||
|
return reqErr
|
||||||
}
|
}
|
||||||
sleepTime += sleepTime
|
sleepTime += sleepTime
|
||||||
if sleepTime > maxSleepTime {
|
if !discoveryutils.SleepCtx(ctx, sleepTime) {
|
||||||
sleepTime = maxSleepTime
|
return reqErr
|
||||||
}
|
}
|
||||||
time.Sleep(sleepTime)
|
|
||||||
scrapeRetries.Inc()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ type ScrapeConfig struct {
|
|||||||
ScrapeTimeout *promutils.Duration `yaml:"scrape_timeout,omitempty"`
|
ScrapeTimeout *promutils.Duration `yaml:"scrape_timeout,omitempty"`
|
||||||
MetricsPath string `yaml:"metrics_path,omitempty"`
|
MetricsPath string `yaml:"metrics_path,omitempty"`
|
||||||
HonorLabels bool `yaml:"honor_labels,omitempty"`
|
HonorLabels bool `yaml:"honor_labels,omitempty"`
|
||||||
HonorTimestamps *bool `yaml:"honor_timestamps,omitempty"`
|
HonorTimestamps bool `yaml:"honor_timestamps,omitempty"`
|
||||||
FollowRedirects *bool `yaml:"follow_redirects,omitempty"`
|
FollowRedirects *bool `yaml:"follow_redirects,omitempty"`
|
||||||
Scheme string `yaml:"scheme,omitempty"`
|
Scheme string `yaml:"scheme,omitempty"`
|
||||||
Params map[string][]string `yaml:"params,omitempty"`
|
Params map[string][]string `yaml:"params,omitempty"`
|
||||||
@@ -706,21 +706,11 @@ func (cfg *Config) getEurekaSDScrapeWork(prev []*ScrapeWork) []*ScrapeWork {
|
|||||||
|
|
||||||
// getFileSDScrapeWork returns `file_sd_configs` ScrapeWork from cfg.
|
// getFileSDScrapeWork returns `file_sd_configs` ScrapeWork from cfg.
|
||||||
func (cfg *Config) getFileSDScrapeWork(prev []*ScrapeWork) []*ScrapeWork {
|
func (cfg *Config) getFileSDScrapeWork(prev []*ScrapeWork) []*ScrapeWork {
|
||||||
// Create a map for the previous scrape work.
|
|
||||||
swsMapPrev := make(map[string][]*ScrapeWork)
|
|
||||||
for _, sw := range prev {
|
|
||||||
filepath := sw.Labels.Get("__vm_filepath")
|
|
||||||
if len(filepath) == 0 {
|
|
||||||
logger.Panicf("BUG: missing `__vm_filepath` label")
|
|
||||||
} else {
|
|
||||||
swsMapPrev[filepath] = append(swsMapPrev[filepath], sw)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst := make([]*ScrapeWork, 0, len(prev))
|
dst := make([]*ScrapeWork, 0, len(prev))
|
||||||
for _, sc := range cfg.ScrapeConfigs {
|
for _, sc := range cfg.ScrapeConfigs {
|
||||||
for j := range sc.FileSDConfigs {
|
for j := range sc.FileSDConfigs {
|
||||||
sdc := &sc.FileSDConfigs[j]
|
sdc := &sc.FileSDConfigs[j]
|
||||||
dst = sdc.appendScrapeWork(dst, swsMapPrev, cfg.baseDir, sc.swc)
|
dst = sdc.appendScrapeWork(dst, cfg.baseDir, sc.swc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dst
|
return dst
|
||||||
@@ -931,10 +921,7 @@ func getScrapeWorkConfig(sc *ScrapeConfig, baseDir string, globalCfg *GlobalConf
|
|||||||
scrapeTimeout = scrapeInterval
|
scrapeTimeout = scrapeInterval
|
||||||
}
|
}
|
||||||
honorLabels := sc.HonorLabels
|
honorLabels := sc.HonorLabels
|
||||||
honorTimestamps := true
|
honorTimestamps := sc.HonorTimestamps
|
||||||
if sc.HonorTimestamps != nil {
|
|
||||||
honorTimestamps = *sc.HonorTimestamps
|
|
||||||
}
|
|
||||||
denyRedirects := false
|
denyRedirects := false
|
||||||
if sc.FollowRedirects != nil {
|
if sc.FollowRedirects != nil {
|
||||||
denyRedirects = !*sc.FollowRedirects
|
denyRedirects = !*sc.FollowRedirects
|
||||||
@@ -1090,7 +1077,7 @@ func appendScrapeWorkForTargetLabels(dst []*ScrapeWork, swc *scrapeWorkConfig, t
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdc *FileSDConfig) appendScrapeWork(dst []*ScrapeWork, swsMapPrev map[string][]*ScrapeWork, baseDir string, swc *scrapeWorkConfig) []*ScrapeWork {
|
func (sdc *FileSDConfig) appendScrapeWork(dst []*ScrapeWork, baseDir string, swc *scrapeWorkConfig) []*ScrapeWork {
|
||||||
metaLabels := promutils.GetLabels()
|
metaLabels := promutils.GetLabels()
|
||||||
defer promutils.PutLabels(metaLabels)
|
defer promutils.PutLabels(metaLabels)
|
||||||
for _, file := range sdc.Files {
|
for _, file := range sdc.Files {
|
||||||
@@ -1101,7 +1088,7 @@ func (sdc *FileSDConfig) appendScrapeWork(dst []*ScrapeWork, swsMapPrev map[stri
|
|||||||
paths, err = filepath.Glob(pathPattern)
|
paths, err = filepath.Glob(pathPattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Do not return this error, since other files may contain valid scrape configs.
|
// Do not return this error, since other files may contain valid scrape configs.
|
||||||
logger.Errorf("invalid pattern %q in `files` section: %s; skipping it", file, err)
|
logger.Errorf("invalid pattern %q in `file_sd_config->files` section of job_name=%q: %s; skipping it", file, swc.jobName, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1109,13 +1096,7 @@ func (sdc *FileSDConfig) appendScrapeWork(dst []*ScrapeWork, swsMapPrev map[stri
|
|||||||
stcs, err := loadStaticConfigs(path)
|
stcs, err := loadStaticConfigs(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Do not return this error, since other paths may contain valid scrape configs.
|
// Do not return this error, since other paths may contain valid scrape configs.
|
||||||
if sws := swsMapPrev[path]; sws != nil {
|
logger.Errorf("cannot load file %q for job_name=%q at `file_sd_configs`: %s; skipping this file", path, swc.jobName, err)
|
||||||
// Re-use the previous valid scrape work for this path.
|
|
||||||
logger.Errorf("keeping the previously loaded `static_configs` from %q because of error when re-loading the file: %s", path, err)
|
|
||||||
dst = append(dst, sws...)
|
|
||||||
} else {
|
|
||||||
logger.Errorf("skipping loading `static_configs` from %q because of error: %s", path, err)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pathShort := path
|
pathShort := path
|
||||||
@@ -1127,7 +1108,6 @@ func (sdc *FileSDConfig) appendScrapeWork(dst []*ScrapeWork, swsMapPrev map[stri
|
|||||||
}
|
}
|
||||||
metaLabels.Reset()
|
metaLabels.Reset()
|
||||||
metaLabels.Add("__meta_filepath", pathShort)
|
metaLabels.Add("__meta_filepath", pathShort)
|
||||||
metaLabels.Add("__vm_filepath", path) // This label is needed for internal promscrape logic
|
|
||||||
for i := range stcs {
|
for i := range stcs {
|
||||||
dst = stcs[i].appendScrapeWork(dst, swc, metaLabels)
|
dst = stcs[i].appendScrapeWork(dst, swc, metaLabels)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ scrape_configs:
|
|||||||
scrape_configs:
|
scrape_configs:
|
||||||
- job_name: foo
|
- job_name: foo
|
||||||
honor_labels: true
|
honor_labels: true
|
||||||
honor_timestamps: false
|
honor_timestamps: true
|
||||||
scheme: https
|
scheme: https
|
||||||
params:
|
params:
|
||||||
foo:
|
foo:
|
||||||
@@ -243,10 +243,9 @@ scrape_configs:
|
|||||||
resetNonEssentialFields(sws)
|
resetNonEssentialFields(sws)
|
||||||
swsExpected := []*ScrapeWork{
|
swsExpected := []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://host1:80/metric/path1?x=y",
|
ScrapeURL: "http://host1:80/metric/path1?x=y",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "host1:80",
|
"instance": "host1:80",
|
||||||
"job": "abc",
|
"job": "abc",
|
||||||
@@ -256,10 +255,9 @@ scrape_configs:
|
|||||||
jobNameOriginal: "abc",
|
jobNameOriginal: "abc",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ScrapeURL: "https://host2:443/metric/path2?x=y",
|
ScrapeURL: "https://host2:443/metric/path2?x=y",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "host2:443",
|
"instance": "host2:443",
|
||||||
"job": "abc",
|
"job": "abc",
|
||||||
@@ -269,10 +267,9 @@ scrape_configs:
|
|||||||
jobNameOriginal: "abc",
|
jobNameOriginal: "abc",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://host3:1234/metric/path3?arg1=value1&x=y",
|
ScrapeURL: "http://host3:1234/metric/path3?arg1=value1&x=y",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "host3:1234",
|
"instance": "host3:1234",
|
||||||
"job": "abc",
|
"job": "abc",
|
||||||
@@ -282,10 +279,9 @@ scrape_configs:
|
|||||||
jobNameOriginal: "abc",
|
jobNameOriginal: "abc",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ScrapeURL: "https://host4:1234/foo/bar?x=y",
|
ScrapeURL: "https://host4:1234/foo/bar?x=y",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "host4:1234",
|
"instance": "host4:1234",
|
||||||
"job": "abc",
|
"job": "abc",
|
||||||
@@ -330,10 +326,9 @@ scrape_configs:
|
|||||||
sws := cfg.getStaticScrapeWork()
|
sws := cfg.getStaticScrapeWork()
|
||||||
resetNonEssentialFields(sws)
|
resetNonEssentialFields(sws)
|
||||||
swsExpected := []*ScrapeWork{{
|
swsExpected := []*ScrapeWork{{
|
||||||
ScrapeURL: "http://black:9115/probe?module=dns_udp_example&target=8.8.8.8",
|
ScrapeURL: "http://black:9115/probe?module=dns_udp_example&target=8.8.8.8",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "8.8.8.8",
|
"instance": "8.8.8.8",
|
||||||
"job": "blackbox",
|
"job": "blackbox",
|
||||||
@@ -739,16 +734,6 @@ func TestGetFileSDScrapeWorkSuccess(t *testing.T) {
|
|||||||
}
|
}
|
||||||
resetNonEssentialFields(sws)
|
resetNonEssentialFields(sws)
|
||||||
|
|
||||||
// Remove `__vm_filepath` label, since its value depends on the current working dir.
|
|
||||||
for _, sw := range sws {
|
|
||||||
labels := sw.Labels.GetLabels()
|
|
||||||
for j := range labels {
|
|
||||||
label := &labels[j]
|
|
||||||
if label.Name == "__vm_filepath" {
|
|
||||||
label.Value = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(sws, expectedSws) {
|
if !reflect.DeepEqual(sws, expectedSws) {
|
||||||
t.Fatalf("unexpected scrapeWork; got\n%+v\nwant\n%+v", sws, expectedSws)
|
t.Fatalf("unexpected scrapeWork; got\n%+v\nwant\n%+v", sws, expectedSws)
|
||||||
}
|
}
|
||||||
@@ -767,45 +752,39 @@ scrape_configs:
|
|||||||
- files: ["testdata/file_sd.json", "testdata/file_sd*.yml"]
|
- files: ["testdata/file_sd.json", "testdata/file_sd*.yml"]
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://host1:80/abc/de",
|
ScrapeURL: "http://host1:80/abc/de",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"__vm_filepath": "",
|
"instance": "host1:80",
|
||||||
"instance": "host1:80",
|
"job": "foo",
|
||||||
"job": "foo",
|
"qwe": "rty",
|
||||||
"qwe": "rty",
|
|
||||||
}),
|
}),
|
||||||
AuthConfig: &promauth.Config{},
|
AuthConfig: &promauth.Config{},
|
||||||
ProxyAuthConfig: &promauth.Config{},
|
ProxyAuthConfig: &promauth.Config{},
|
||||||
jobNameOriginal: "foo",
|
jobNameOriginal: "foo",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://host2:80/abc/de",
|
ScrapeURL: "http://host2:80/abc/de",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"__vm_filepath": "",
|
"instance": "host2:80",
|
||||||
"instance": "host2:80",
|
"job": "foo",
|
||||||
"job": "foo",
|
"qwe": "rty",
|
||||||
"qwe": "rty",
|
|
||||||
}),
|
}),
|
||||||
AuthConfig: &promauth.Config{},
|
AuthConfig: &promauth.Config{},
|
||||||
ProxyAuthConfig: &promauth.Config{},
|
ProxyAuthConfig: &promauth.Config{},
|
||||||
jobNameOriginal: "foo",
|
jobNameOriginal: "foo",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://localhost:9090/abc/de",
|
ScrapeURL: "http://localhost:9090/abc/de",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"__vm_filepath": "",
|
"instance": "localhost:9090",
|
||||||
"instance": "localhost:9090",
|
"job": "foo",
|
||||||
"job": "foo",
|
"yml": "test",
|
||||||
"yml": "test",
|
|
||||||
}),
|
}),
|
||||||
AuthConfig: &promauth.Config{},
|
AuthConfig: &promauth.Config{},
|
||||||
ProxyAuthConfig: &promauth.Config{},
|
ProxyAuthConfig: &promauth.Config{},
|
||||||
@@ -834,10 +813,9 @@ scrape_configs:
|
|||||||
- targets: ["foo.bar:1234"]
|
- targets: ["foo.bar:1234"]
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://foo.bar:1234/metrics",
|
ScrapeURL: "http://foo.bar:1234/metrics",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foo.bar:1234",
|
"instance": "foo.bar:1234",
|
||||||
"job": "foo",
|
"job": "foo",
|
||||||
@@ -858,10 +836,9 @@ scrape_configs:
|
|||||||
- targets: ["foo.bar:1234"]
|
- targets: ["foo.bar:1234"]
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://foo.bar:1234/metrics",
|
ScrapeURL: "http://foo.bar:1234/metrics",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foo.bar:1234",
|
"instance": "foo.bar:1234",
|
||||||
"job": "foo",
|
"job": "foo",
|
||||||
@@ -886,7 +863,7 @@ scrape_configs:
|
|||||||
metrics_path: /foo/bar
|
metrics_path: /foo/bar
|
||||||
scheme: https
|
scheme: https
|
||||||
honor_labels: true
|
honor_labels: true
|
||||||
honor_timestamps: false
|
honor_timestamps: true
|
||||||
follow_redirects: false
|
follow_redirects: false
|
||||||
params:
|
params:
|
||||||
p: ["x&y", "="]
|
p: ["x&y", "="]
|
||||||
@@ -912,7 +889,7 @@ scrape_configs:
|
|||||||
ScrapeInterval: 54 * time.Second,
|
ScrapeInterval: 54 * time.Second,
|
||||||
ScrapeTimeout: 5 * time.Second,
|
ScrapeTimeout: 5 * time.Second,
|
||||||
HonorLabels: true,
|
HonorLabels: true,
|
||||||
HonorTimestamps: false,
|
HonorTimestamps: true,
|
||||||
DenyRedirects: true,
|
DenyRedirects: true,
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foo.bar:443",
|
"instance": "foo.bar:443",
|
||||||
@@ -929,7 +906,7 @@ scrape_configs:
|
|||||||
ScrapeInterval: 54 * time.Second,
|
ScrapeInterval: 54 * time.Second,
|
||||||
ScrapeTimeout: 5 * time.Second,
|
ScrapeTimeout: 5 * time.Second,
|
||||||
HonorLabels: true,
|
HonorLabels: true,
|
||||||
HonorTimestamps: false,
|
HonorTimestamps: true,
|
||||||
DenyRedirects: true,
|
DenyRedirects: true,
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "aaa:443",
|
"instance": "aaa:443",
|
||||||
@@ -942,10 +919,9 @@ scrape_configs:
|
|||||||
jobNameOriginal: "foo",
|
jobNameOriginal: "foo",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://1.2.3.4:80/metrics",
|
ScrapeURL: "http://1.2.3.4:80/metrics",
|
||||||
ScrapeInterval: 8 * time.Second,
|
ScrapeInterval: 8 * time.Second,
|
||||||
ScrapeTimeout: 8 * time.Second,
|
ScrapeTimeout: 8 * time.Second,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "1.2.3.4:80",
|
"instance": "1.2.3.4:80",
|
||||||
"job": "qwer",
|
"job": "qwer",
|
||||||
@@ -958,10 +934,9 @@ scrape_configs:
|
|||||||
jobNameOriginal: "qwer",
|
jobNameOriginal: "qwer",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://foobar:80/metrics",
|
ScrapeURL: "http://foobar:80/metrics",
|
||||||
ScrapeInterval: 8 * time.Second,
|
ScrapeInterval: 8 * time.Second,
|
||||||
ScrapeTimeout: 8 * time.Second,
|
ScrapeTimeout: 8 * time.Second,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foobar:80",
|
"instance": "foobar:80",
|
||||||
"job": "asdf",
|
"job": "asdf",
|
||||||
@@ -1008,10 +983,9 @@ scrape_configs:
|
|||||||
- targets: ["foo.bar:1234", "drop-this-target"]
|
- targets: ["foo.bar:1234", "drop-this-target"]
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://foo.bar:1234/metrics?x=keep_me",
|
ScrapeURL: "http://foo.bar:1234/metrics?x=keep_me",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"hash": "82",
|
"hash": "82",
|
||||||
"instance": "foo.bar:1234",
|
"instance": "foo.bar:1234",
|
||||||
@@ -1052,10 +1026,9 @@ scrape_configs:
|
|||||||
- targets: ["foo.bar:1234"]
|
- targets: ["foo.bar:1234"]
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "mailto://foo.bar:1234/abc.de?a=b",
|
ScrapeURL: "mailto://foo.bar:1234/abc.de?a=b",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "fake.addr",
|
"instance": "fake.addr",
|
||||||
"job": "https",
|
"job": "https",
|
||||||
@@ -1087,10 +1060,9 @@ scrape_configs:
|
|||||||
- targets: ["foo.bar:1234", "xyz"]
|
- targets: ["foo.bar:1234", "xyz"]
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://foo.bar:1234/metrics",
|
ScrapeURL: "http://foo.bar:1234/metrics",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foo.bar:1234",
|
"instance": "foo.bar:1234",
|
||||||
"job": "3",
|
"job": "3",
|
||||||
@@ -1111,10 +1083,9 @@ scrape_configs:
|
|||||||
- targets: ["foo.bar:1234"]
|
- targets: ["foo.bar:1234"]
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://foo.bar:1234/metrics",
|
ScrapeURL: "http://foo.bar:1234/metrics",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foo.bar:1234",
|
"instance": "foo.bar:1234",
|
||||||
"job": "foo",
|
"job": "foo",
|
||||||
@@ -1131,10 +1102,9 @@ scrape_configs:
|
|||||||
- targets: ["foo.bar:1234"]
|
- targets: ["foo.bar:1234"]
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://foo.bar:1234/metrics",
|
ScrapeURL: "http://foo.bar:1234/metrics",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foo.bar:1234",
|
"instance": "foo.bar:1234",
|
||||||
"job": "foo",
|
"job": "foo",
|
||||||
@@ -1151,10 +1121,9 @@ scrape_configs:
|
|||||||
- targets: ["foo.bar:1234"]
|
- targets: ["foo.bar:1234"]
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://foo.bar:1234/metrics",
|
ScrapeURL: "http://foo.bar:1234/metrics",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foo.bar:1234",
|
"instance": "foo.bar:1234",
|
||||||
"job": "foo",
|
"job": "foo",
|
||||||
@@ -1185,10 +1154,9 @@ scrape_configs:
|
|||||||
job: yyy
|
job: yyy
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://pp:80/metrics?a=c&a=xy",
|
ScrapeURL: "http://pp:80/metrics?a=c&a=xy",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
"instance": "pp:80",
|
"instance": "pp:80",
|
||||||
@@ -1252,10 +1220,9 @@ scrape_configs:
|
|||||||
replacement: true
|
replacement: true
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://127.0.0.1:9116/snmp?module=if_mib&target=192.168.1.2",
|
ScrapeURL: "http://127.0.0.1:9116/snmp?module=if_mib&target=192.168.1.2",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "192.168.1.2",
|
"instance": "192.168.1.2",
|
||||||
"job": "snmp",
|
"job": "snmp",
|
||||||
@@ -1282,10 +1249,9 @@ scrape_configs:
|
|||||||
target_label: __metrics_path__
|
target_label: __metrics_path__
|
||||||
`, []*ScrapeWork{
|
`, []*ScrapeWork{
|
||||||
{
|
{
|
||||||
ScrapeURL: "http://foo.bar:1234/metricspath",
|
ScrapeURL: "http://foo.bar:1234/metricspath",
|
||||||
ScrapeInterval: defaultScrapeInterval,
|
ScrapeInterval: defaultScrapeInterval,
|
||||||
ScrapeTimeout: defaultScrapeTimeout,
|
ScrapeTimeout: defaultScrapeTimeout,
|
||||||
HonorTimestamps: true,
|
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foo.bar:1234",
|
"instance": "foo.bar:1234",
|
||||||
"job": "path wo slash",
|
"job": "path wo slash",
|
||||||
@@ -1313,7 +1279,6 @@ scrape_configs:
|
|||||||
ScrapeTimeout: time.Hour * 24,
|
ScrapeTimeout: time.Hour * 24,
|
||||||
ScrapeAlignInterval: time.Hour * 24,
|
ScrapeAlignInterval: time.Hour * 24,
|
||||||
ScrapeOffset: time.Hour * 24 * 2,
|
ScrapeOffset: time.Hour * 24 * 2,
|
||||||
HonorTimestamps: true,
|
|
||||||
NoStaleMarkers: true,
|
NoStaleMarkers: true,
|
||||||
Labels: promutils.NewLabelsFromMap(map[string]string{
|
Labels: promutils.NewLabelsFromMap(map[string]string{
|
||||||
"instance": "foo.bar:1234",
|
"instance": "foo.bar:1234",
|
||||||
@@ -1353,16 +1318,14 @@ func TestScrapeConfigClone(t *testing.T) {
|
|||||||
|
|
||||||
f(&ScrapeConfig{})
|
f(&ScrapeConfig{})
|
||||||
|
|
||||||
bFalse := false
|
|
||||||
var ie promrelabel.IfExpression
|
var ie promrelabel.IfExpression
|
||||||
if err := ie.Parse(`{foo=~"bar",baz!="z"}`); err != nil {
|
if err := ie.Parse(`{foo=~"bar",baz!="z"}`); err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
f(&ScrapeConfig{
|
f(&ScrapeConfig{
|
||||||
JobName: "foo",
|
JobName: "foo",
|
||||||
ScrapeInterval: promutils.NewDuration(time.Second * 47),
|
ScrapeInterval: promutils.NewDuration(time.Second * 47),
|
||||||
HonorLabels: true,
|
HonorLabels: true,
|
||||||
HonorTimestamps: &bFalse,
|
|
||||||
Params: map[string][]string{
|
Params: map[string][]string{
|
||||||
"foo": {"bar", "baz"},
|
"foo": {"bar", "baz"},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -199,12 +199,17 @@ func getRefreshTokenFunc(sdc *SDConfig, ac, proxyAC *promauth.Config, env *cloud
|
|||||||
q := endpointURL.Query()
|
q := endpointURL.Query()
|
||||||
|
|
||||||
msiSecret := os.Getenv("MSI_SECRET")
|
msiSecret := os.Getenv("MSI_SECRET")
|
||||||
|
identityHeader := os.Getenv("IDENTITY_HEADER")
|
||||||
clientIDParam := "client_id"
|
clientIDParam := "client_id"
|
||||||
apiVersion := "2018-02-01"
|
apiVersion := "2018-02-01"
|
||||||
if msiSecret != "" {
|
if msiSecret != "" {
|
||||||
clientIDParam = "clientid"
|
clientIDParam = "clientid"
|
||||||
apiVersion = "2017-09-01"
|
apiVersion = "2017-09-01"
|
||||||
}
|
}
|
||||||
|
if identityHeader != "" {
|
||||||
|
clientIDParam = "client_id"
|
||||||
|
apiVersion = "2019-08-01"
|
||||||
|
}
|
||||||
q.Set("api-version", apiVersion)
|
q.Set("api-version", apiVersion)
|
||||||
q.Set(clientIDParam, sdc.ClientID)
|
q.Set(clientIDParam, sdc.ClientID)
|
||||||
q.Set("resource", env.ResourceManagerEndpoint)
|
q.Set("resource", env.ResourceManagerEndpoint)
|
||||||
@@ -214,6 +219,9 @@ func getRefreshTokenFunc(sdc *SDConfig, ac, proxyAC *promauth.Config, env *cloud
|
|||||||
modifyRequest = func(request *http.Request) {
|
modifyRequest = func(request *http.Request) {
|
||||||
if msiSecret != "" {
|
if msiSecret != "" {
|
||||||
request.Header.Set("secret", msiSecret)
|
request.Header.Set("secret", msiSecret)
|
||||||
|
if identityHeader != "" {
|
||||||
|
request.Header.Set("X-IDENTITY-HEADER", msiSecret)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
request.Header.Set("Metadata", "true")
|
request.Header.Set("Metadata", "true")
|
||||||
}
|
}
|
||||||
@@ -235,15 +243,38 @@ func getRefreshTokenFunc(sdc *SDConfig, ac, proxyAC *promauth.Config, env *cloud
|
|||||||
if err := json.Unmarshal(data, &tr); err != nil {
|
if err := json.Unmarshal(data, &tr); err != nil {
|
||||||
return "", 0, fmt.Errorf("cannot parse token auth response %q: %w", data, err)
|
return "", 0, fmt.Errorf("cannot parse token auth response %q: %w", data, err)
|
||||||
}
|
}
|
||||||
expiresInSeconds, err := strconv.ParseInt(tr.ExpiresIn, 10, 64)
|
|
||||||
|
expiresInSeconds, err := parseTokenExpiry(tr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, fmt.Errorf("cannot parse expiresIn param in token auth %q: %w", tr.ExpiresIn, err)
|
return "", 0, err
|
||||||
}
|
}
|
||||||
return tr.AccessToken, time.Second * time.Duration(expiresInSeconds), nil
|
return tr.AccessToken, time.Second * time.Duration(expiresInSeconds), nil
|
||||||
}
|
}
|
||||||
return refreshToken, nil
|
return refreshToken, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseTokenExpiry returns token expiry in seconds
|
||||||
|
func parseTokenExpiry(tr tokenResponse) (int64, error) {
|
||||||
|
var expiresInSeconds int64
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if tr.ExpiresIn == "" {
|
||||||
|
var expiresOnSeconds int64
|
||||||
|
expiresOnSeconds, err = strconv.ParseInt(tr.ExpiresOn, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("cannot parse expiresOn=%q in auth token response: %w", tr.ExpiresOn, err)
|
||||||
|
}
|
||||||
|
expiresInSeconds = expiresOnSeconds - time.Now().Unix()
|
||||||
|
} else {
|
||||||
|
expiresInSeconds, err = strconv.ParseInt(tr.ExpiresIn, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("cannot parse expiresIn=%q auth token response: %w", tr.ExpiresIn, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expiresInSeconds, nil
|
||||||
|
}
|
||||||
|
|
||||||
// mustGetAuthToken returns auth token
|
// mustGetAuthToken returns auth token
|
||||||
// in case of error, logs error and return empty token
|
// in case of error, logs error and return empty token
|
||||||
func (ac *apiConfig) mustGetAuthToken() string {
|
func (ac *apiConfig) mustGetAuthToken() string {
|
||||||
@@ -270,4 +301,5 @@ func (ac *apiConfig) mustGetAuthToken() string {
|
|||||||
type tokenResponse struct {
|
type tokenResponse struct {
|
||||||
AccessToken string `json:"access_token"`
|
AccessToken string `json:"access_token"`
|
||||||
ExpiresIn string `json:"expires_in"`
|
ExpiresIn string `json:"expires_in"`
|
||||||
|
ExpiresOn string `json:"expires_on"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,11 @@ func (sdc *SDConfig) GetLabels(baseDir string) ([]*promutils.Labels, error) {
|
|||||||
|
|
||||||
// MustStop stops further usage for sdc.
|
// MustStop stops further usage for sdc.
|
||||||
func (sdc *SDConfig) MustStop() {
|
func (sdc *SDConfig) MustStop() {
|
||||||
configMap.Delete(sdc)
|
v := configMap.Delete(sdc)
|
||||||
|
if v != nil {
|
||||||
|
cfg := v.(*apiConfig)
|
||||||
|
cfg.c.Stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendMachineLabels(vms []virtualMachine, port int, sdc *SDConfig) []*promutils.Labels {
|
func appendMachineLabels(vms []virtualMachine, port int, sdc *SDConfig) []*promutils.Labels {
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ func TestGetVirtualMachinesSuccess(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error at client create: %s", err)
|
t.Fatalf("unexpected error at client create: %s", err)
|
||||||
}
|
}
|
||||||
|
defer c.Stop()
|
||||||
ac := &apiConfig{
|
ac := &apiConfig{
|
||||||
c: c,
|
c: c,
|
||||||
subscriptionID: "some-id",
|
subscriptionID: "some-id",
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
|||||||
}
|
}
|
||||||
dc, err := getDatacenter(client, sdc.Datacenter)
|
dc, err := getDatacenter(client, sdc.Datacenter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
client.Stop()
|
||||||
return nil, fmt.Errorf("cannot obtain consul datacenter: %w", err)
|
return nil, fmt.Errorf("cannot obtain consul datacenter: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -155,5 +155,9 @@ func addDropletLabels(droplets []droplet, defaultPort int) []*promutils.Labels {
|
|||||||
|
|
||||||
// MustStop stops further usage for sdc.
|
// MustStop stops further usage for sdc.
|
||||||
func (sdc *SDConfig) MustStop() {
|
func (sdc *SDConfig) MustStop() {
|
||||||
configMap.Delete(sdc)
|
v := configMap.Delete(sdc)
|
||||||
|
if v != nil {
|
||||||
|
cfg := v.(*apiConfig)
|
||||||
|
cfg.client.Stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,5 +47,9 @@ func (sdc *SDConfig) GetLabels(baseDir string) ([]*promutils.Labels, error) {
|
|||||||
|
|
||||||
// MustStop stops further usage for sdc.
|
// MustStop stops further usage for sdc.
|
||||||
func (sdc *SDConfig) MustStop() {
|
func (sdc *SDConfig) MustStop() {
|
||||||
configMap.Delete(sdc)
|
v := configMap.Delete(sdc)
|
||||||
|
if v != nil {
|
||||||
|
cfg := v.(*apiConfig)
|
||||||
|
cfg.client.Stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,5 +56,9 @@ func (sdc *SDConfig) GetLabels(baseDir string) ([]*promutils.Labels, error) {
|
|||||||
|
|
||||||
// MustStop stops further usage for sdc.
|
// MustStop stops further usage for sdc.
|
||||||
func (sdc *SDConfig) MustStop() {
|
func (sdc *SDConfig) MustStop() {
|
||||||
configMap.Delete(sdc)
|
v := configMap.Delete(sdc)
|
||||||
|
if v != nil {
|
||||||
|
cfg := v.(*apiConfig)
|
||||||
|
cfg.client.Stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,11 @@ func (sdc *SDConfig) GetLabels(baseDir string) ([]*promutils.Labels, error) {
|
|||||||
|
|
||||||
// MustStop stops further usage for sdc.
|
// MustStop stops further usage for sdc.
|
||||||
func (sdc *SDConfig) MustStop() {
|
func (sdc *SDConfig) MustStop() {
|
||||||
configMap.Delete(sdc)
|
v := configMap.Delete(sdc)
|
||||||
|
if v != nil {
|
||||||
|
cfg := v.(*apiConfig)
|
||||||
|
cfg.client.Stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addInstanceLabels(apps *applications) []*promutils.Labels {
|
func addInstanceLabels(apps *applications) []*promutils.Labels {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ func newAPIConfig(sdc *SDConfig) (*apiConfig, error) {
|
|||||||
if len(project) == 0 {
|
if len(project) == 0 {
|
||||||
proj, err := getCurrentProject()
|
proj, err := getCurrentProject()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
client.CloseIdleConnections()
|
||||||
return nil, fmt.Errorf("cannot determine the current project; make sure `vmagent` runs inside GCE; error: %w", err)
|
return nil, fmt.Errorf("cannot determine the current project; make sure `vmagent` runs inside GCE; error: %w", err)
|
||||||
}
|
}
|
||||||
project = proj
|
project = proj
|
||||||
@@ -52,6 +53,7 @@ func newAPIConfig(sdc *SDConfig) (*apiConfig, error) {
|
|||||||
// Autodetect the current zone.
|
// Autodetect the current zone.
|
||||||
zone, err := getCurrentZone()
|
zone, err := getCurrentZone()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
client.CloseIdleConnections()
|
||||||
return nil, fmt.Errorf("cannot determine the current zone; make sure `vmagent` runs inside GCE; error: %w", err)
|
return nil, fmt.Errorf("cannot determine the current zone; make sure `vmagent` runs inside GCE; error: %w", err)
|
||||||
}
|
}
|
||||||
zones = append(zones, zone)
|
zones = append(zones, zone)
|
||||||
@@ -62,6 +64,7 @@ func newAPIConfig(sdc *SDConfig) (*apiConfig, error) {
|
|||||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3202
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3202
|
||||||
zs, err := getZonesForProject(client, project)
|
zs, err := getZonesForProject(client, project)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
client.CloseIdleConnections()
|
||||||
return nil, fmt.Errorf("cannot obtain zones for project %q: %w", project, err)
|
return nil, fmt.Errorf("cannot obtain zones for project %q: %w", project, err)
|
||||||
}
|
}
|
||||||
zones = zs
|
zones = zs
|
||||||
|
|||||||
@@ -73,5 +73,9 @@ func (sdc *SDConfig) GetLabels(baseDir string) ([]*promutils.Labels, error) {
|
|||||||
|
|
||||||
// MustStop stops further usage for sdc.
|
// MustStop stops further usage for sdc.
|
||||||
func (sdc *SDConfig) MustStop() {
|
func (sdc *SDConfig) MustStop() {
|
||||||
configMap.Delete(sdc)
|
v := configMap.Delete(sdc)
|
||||||
|
if v != nil {
|
||||||
|
cfg := v.(*apiConfig)
|
||||||
|
cfg.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,5 +56,9 @@ func addHTTPTargetLabels(src []httpGroupTarget, sourceURL string) []*promutils.L
|
|||||||
|
|
||||||
// MustStop stops further usage for sdc.
|
// MustStop stops further usage for sdc.
|
||||||
func (sdc *SDConfig) MustStop() {
|
func (sdc *SDConfig) MustStop() {
|
||||||
configMap.Delete(sdc)
|
v := configMap.Delete(sdc)
|
||||||
|
if v != nil {
|
||||||
|
cfg := v.(*apiConfig)
|
||||||
|
cfg.client.Stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,6 +134,11 @@ func (eps *Endpoints) getTargetLabels(gw *groupWatcher) []*promutils.Labels {
|
|||||||
m.Add("__address__", addr)
|
m.Add("__address__", addr)
|
||||||
p.appendCommonLabels(m, gw)
|
p.appendCommonLabels(m, gw)
|
||||||
p.appendContainerLabels(m, c, &cp)
|
p.appendContainerLabels(m, c, &cp)
|
||||||
|
|
||||||
|
// Prometheus sets endpoints_name and namespace labels for all endpoints
|
||||||
|
// Even if port is not matching service port.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4154
|
||||||
|
p.appendEndpointLabels(m, eps)
|
||||||
if svc != nil {
|
if svc != nil {
|
||||||
svc.appendCommonLabels(m)
|
svc.appendCommonLabels(m)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -292,7 +292,10 @@ func TestGetEndpointsLabels(t *testing.T) {
|
|||||||
"__meta_kubernetes_service_type": "service-type",
|
"__meta_kubernetes_service_type": "service-type",
|
||||||
}),
|
}),
|
||||||
promutils.NewLabelsFromMap(map[string]string{
|
promutils.NewLabelsFromMap(map[string]string{
|
||||||
"__address__": "192.168.15.1:8428",
|
"__address__": "192.168.15.1:8428",
|
||||||
|
"__meta_kubernetes_endpoint_address_target_kind": "Pod",
|
||||||
|
"__meta_kubernetes_endpoint_address_target_name": "test-pod",
|
||||||
|
"__meta_kubernetes_endpoints_name": "test-eps",
|
||||||
"__meta_kubernetes_namespace": "default",
|
"__meta_kubernetes_namespace": "default",
|
||||||
"__meta_kubernetes_node_label_node_label": "xyz",
|
"__meta_kubernetes_node_label_node_label": "xyz",
|
||||||
"__meta_kubernetes_node_labelpresent_node_label": "true",
|
"__meta_kubernetes_node_labelpresent_node_label": "true",
|
||||||
|
|||||||
@@ -83,6 +83,11 @@ func (eps *EndpointSlice) getTargetLabels(gw *groupWatcher) []*promutils.Labels
|
|||||||
m.Add("__address__", addr)
|
m.Add("__address__", addr)
|
||||||
p.appendCommonLabels(m, gw)
|
p.appendCommonLabels(m, gw)
|
||||||
p.appendContainerLabels(m, c, &cp)
|
p.appendContainerLabels(m, c, &cp)
|
||||||
|
|
||||||
|
// Prometheus sets endpoints_name and namespace labels for all endpoints
|
||||||
|
// Even if port is not matching service port.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4154
|
||||||
|
p.appendEndpointSliceLabels(m, eps)
|
||||||
if svc != nil {
|
if svc != nil {
|
||||||
svc.appendCommonLabels(m)
|
svc.appendCommonLabels(m)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -426,26 +426,32 @@ func TestGetEndpointsliceLabels(t *testing.T) {
|
|||||||
"__meta_kubernetes_service_type": "service-type",
|
"__meta_kubernetes_service_type": "service-type",
|
||||||
}),
|
}),
|
||||||
promutils.NewLabelsFromMap(map[string]string{
|
promutils.NewLabelsFromMap(map[string]string{
|
||||||
"__address__": "192.168.15.1:8428",
|
"__address__": "192.168.15.1:8428",
|
||||||
"__meta_kubernetes_namespace": "default",
|
"__meta_kubernetes_endpointslice_address_target_kind": "Pod",
|
||||||
"__meta_kubernetes_node_label_node_label": "xyz",
|
"__meta_kubernetes_endpointslice_address_target_name": "test-pod",
|
||||||
"__meta_kubernetes_node_labelpresent_node_label": "true",
|
"__meta_kubernetes_endpointslice_address_type": "foobar",
|
||||||
"__meta_kubernetes_node_name": "test-node",
|
"__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "test-svc",
|
||||||
"__meta_kubernetes_pod_container_image": "test-image",
|
"__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
|
||||||
"__meta_kubernetes_pod_container_name": "metrics",
|
"__meta_kubernetes_endpointslice_name": "test-eps",
|
||||||
"__meta_kubernetes_pod_container_port_name": "http-metrics",
|
"__meta_kubernetes_namespace": "default",
|
||||||
"__meta_kubernetes_pod_container_port_number": "8428",
|
"__meta_kubernetes_node_label_node_label": "xyz",
|
||||||
"__meta_kubernetes_pod_container_port_protocol": "foobar",
|
"__meta_kubernetes_node_labelpresent_node_label": "true",
|
||||||
"__meta_kubernetes_pod_host_ip": "4.5.6.7",
|
"__meta_kubernetes_node_name": "test-node",
|
||||||
"__meta_kubernetes_pod_ip": "192.168.15.1",
|
"__meta_kubernetes_pod_container_image": "test-image",
|
||||||
"__meta_kubernetes_pod_name": "test-pod",
|
"__meta_kubernetes_pod_container_name": "metrics",
|
||||||
"__meta_kubernetes_pod_node_name": "test-node",
|
"__meta_kubernetes_pod_container_port_name": "http-metrics",
|
||||||
"__meta_kubernetes_pod_phase": "abc",
|
"__meta_kubernetes_pod_container_port_number": "8428",
|
||||||
"__meta_kubernetes_pod_ready": "unknown",
|
"__meta_kubernetes_pod_container_port_protocol": "foobar",
|
||||||
"__meta_kubernetes_pod_uid": "pod-uid",
|
"__meta_kubernetes_pod_host_ip": "4.5.6.7",
|
||||||
"__meta_kubernetes_service_cluster_ip": "1.2.3.4",
|
"__meta_kubernetes_pod_ip": "192.168.15.1",
|
||||||
"__meta_kubernetes_service_name": "test-svc",
|
"__meta_kubernetes_pod_name": "test-pod",
|
||||||
"__meta_kubernetes_service_type": "service-type",
|
"__meta_kubernetes_pod_node_name": "test-node",
|
||||||
|
"__meta_kubernetes_pod_phase": "abc",
|
||||||
|
"__meta_kubernetes_pod_ready": "unknown",
|
||||||
|
"__meta_kubernetes_pod_uid": "pod-uid",
|
||||||
|
"__meta_kubernetes_service_cluster_ip": "1.2.3.4",
|
||||||
|
"__meta_kubernetes_service_name": "test-svc",
|
||||||
|
"__meta_kubernetes_service_type": "service-type",
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -178,6 +178,21 @@ func (p *Pod) appendContainerLabels(m *promutils.Labels, c Container, cp *Contai
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Pod) appendEndpointLabels(m *promutils.Labels, eps *Endpoints) {
|
||||||
|
m.Add("__meta_kubernetes_endpoints_name", eps.Metadata.Name)
|
||||||
|
m.Add("__meta_kubernetes_endpoint_address_target_kind", "Pod")
|
||||||
|
m.Add("__meta_kubernetes_endpoint_address_target_name", p.Metadata.Name)
|
||||||
|
eps.Metadata.registerLabelsAndAnnotations("__meta_kubernetes_endpoints", m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pod) appendEndpointSliceLabels(m *promutils.Labels, eps *EndpointSlice) {
|
||||||
|
m.Add("__meta_kubernetes_endpointslice_name", eps.Metadata.Name)
|
||||||
|
m.Add("__meta_kubernetes_endpointslice_address_target_kind", "Pod")
|
||||||
|
m.Add("__meta_kubernetes_endpointslice_address_target_name", p.Metadata.Name)
|
||||||
|
m.Add("__meta_kubernetes_endpointslice_address_type", eps.AddressType)
|
||||||
|
eps.Metadata.registerLabelsAndAnnotations("__meta_kubernetes_endpointslice", m)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Pod) appendCommonLabels(m *promutils.Labels, gw *groupWatcher) {
|
func (p *Pod) appendCommonLabels(m *promutils.Labels, gw *groupWatcher) {
|
||||||
if gw.attachNodeMetadata {
|
if gw.attachNodeMetadata {
|
||||||
m.Add("__meta_kubernetes_node_name", p.Spec.NodeName)
|
m.Add("__meta_kubernetes_node_name", p.Spec.NodeName)
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
|||||||
}
|
}
|
||||||
ac, err := opts.NewConfig()
|
ac, err := opts.NewConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cfg.client.CloseIdleConnections()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cfg.client.Transport = &http.Transport{
|
cfg.client.Transport = &http.Transport{
|
||||||
@@ -107,6 +108,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
|||||||
sdcAuth = readCredentialsFromEnv()
|
sdcAuth = readCredentialsFromEnv()
|
||||||
}
|
}
|
||||||
if strings.HasSuffix(sdcAuth.IdentityEndpoint, "v2.0") {
|
if strings.HasSuffix(sdcAuth.IdentityEndpoint, "v2.0") {
|
||||||
|
cfg.client.CloseIdleConnections()
|
||||||
return nil, errors.New("identity_endpoint v2.0 is not supported")
|
return nil, errors.New("identity_endpoint v2.0 is not supported")
|
||||||
}
|
}
|
||||||
// trim .0 from v3.0 for prometheus cfg compatibility
|
// trim .0 from v3.0 for prometheus cfg compatibility
|
||||||
@@ -114,11 +116,13 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
|||||||
|
|
||||||
parsedURL, err := url.Parse(sdcAuth.IdentityEndpoint)
|
parsedURL, err := url.Parse(sdcAuth.IdentityEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cfg.client.CloseIdleConnections()
|
||||||
return nil, fmt.Errorf("cannot parse identity_endpoint: %s as url, err: %w", sdcAuth.IdentityEndpoint, err)
|
return nil, fmt.Errorf("cannot parse identity_endpoint: %s as url, err: %w", sdcAuth.IdentityEndpoint, err)
|
||||||
}
|
}
|
||||||
cfg.endpoint = parsedURL
|
cfg.endpoint = parsedURL
|
||||||
tokenReq, err := buildAuthRequestBody(&sdcAuth)
|
tokenReq, err := buildAuthRequestBody(&sdcAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cfg.client.CloseIdleConnections()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cfg.authTokenReq = tokenReq
|
cfg.authTokenReq = tokenReq
|
||||||
|
|||||||
@@ -57,5 +57,9 @@ func (sdc *SDConfig) GetLabels(baseDir string) ([]*promutils.Labels, error) {
|
|||||||
|
|
||||||
// MustStop stops further usage for sdc.
|
// MustStop stops further usage for sdc.
|
||||||
func (sdc *SDConfig) MustStop() {
|
func (sdc *SDConfig) MustStop() {
|
||||||
configMap.Delete(sdc)
|
v := configMap.Delete(sdc)
|
||||||
|
if v != nil {
|
||||||
|
cfg := v.(*apiConfig)
|
||||||
|
cfg.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,12 @@ type HTTPClient struct {
|
|||||||
ReadTimeout time.Duration
|
ReadTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hc *HTTPClient) stop() {
|
||||||
|
// Close idle connections to server in order to free up resources.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4724
|
||||||
|
hc.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
|
||||||
var defaultDialer = &net.Dialer{}
|
var defaultDialer = &net.Dialer{}
|
||||||
|
|
||||||
// NewClient returns new Client for the given args.
|
// NewClient returns new Client for the given args.
|
||||||
@@ -225,7 +231,7 @@ func (c *Client) getAPIResponseWithParamsAndClientCtx(ctx context.Context, clien
|
|||||||
modifyRequest(req)
|
modifyRequest(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := doRequestWithPossibleRetry(client, req, deadline)
|
resp, err := doRequestWithPossibleRetry(client, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot fetch %q: %w", requestURL, err)
|
return nil, fmt.Errorf("cannot fetch %q: %w", requestURL, err)
|
||||||
}
|
}
|
||||||
@@ -254,33 +260,52 @@ func (c *Client) APIServer() string {
|
|||||||
// Stop cancels all in-flight requests
|
// Stop cancels all in-flight requests
|
||||||
func (c *Client) Stop() {
|
func (c *Client) Stop() {
|
||||||
c.clientCancel()
|
c.clientCancel()
|
||||||
|
c.client.stop()
|
||||||
|
c.blockingClient.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRequestWithPossibleRetry(hc *HTTPClient, req *http.Request, deadline time.Time) (*http.Response, error) {
|
func doRequestWithPossibleRetry(hc *HTTPClient, req *http.Request) (*http.Response, error) {
|
||||||
sleepTime := time.Second
|
|
||||||
discoveryRequests.Inc()
|
discoveryRequests.Inc()
|
||||||
|
|
||||||
for {
|
var (
|
||||||
resp, err := hc.client.Do(req)
|
reqErr error
|
||||||
if err == nil {
|
resp *http.Response
|
||||||
|
)
|
||||||
|
// Return true if the request execution is completed and retry is not required
|
||||||
|
attempt := func() bool {
|
||||||
|
resp, reqErr = hc.client.Do(req)
|
||||||
|
if reqErr == nil {
|
||||||
statusCode := resp.StatusCode
|
statusCode := resp.StatusCode
|
||||||
if statusCode != http.StatusTooManyRequests {
|
if statusCode != http.StatusTooManyRequests {
|
||||||
return resp, nil
|
return true
|
||||||
}
|
}
|
||||||
} else if err != net.ErrClosed && !strings.Contains(err.Error(), "broken pipe") {
|
} else if reqErr != net.ErrClosed && !strings.Contains(reqErr.Error(), "broken pipe") {
|
||||||
return nil, err
|
return true
|
||||||
}
|
}
|
||||||
// Retry request after exponentially increased sleep.
|
return false
|
||||||
maxSleepTime := time.Until(deadline)
|
}
|
||||||
if sleepTime > maxSleepTime {
|
|
||||||
return nil, fmt.Errorf("the server closes all the connection attempts: %w", err)
|
if attempt() {
|
||||||
|
return resp, reqErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first attempt was unsuccessful. Use exponential backoff for further attempts.
|
||||||
|
// Perform the second attempt immediately after the first attempt - this should help
|
||||||
|
// in cases when the remote side closes the keep-alive connection before the first attempt.
|
||||||
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3293
|
||||||
|
sleepTime := time.Second
|
||||||
|
// It is expected that the deadline is already set to req.Context(), so the loop below
|
||||||
|
// should eventually finish if all the attempt() calls are unsuccessful.
|
||||||
|
ctx := req.Context()
|
||||||
|
for {
|
||||||
|
discoveryRetries.Inc()
|
||||||
|
if attempt() {
|
||||||
|
return resp, reqErr
|
||||||
}
|
}
|
||||||
sleepTime += sleepTime
|
sleepTime += sleepTime
|
||||||
if sleepTime > maxSleepTime {
|
if !SleepCtx(ctx, sleepTime) {
|
||||||
sleepTime = maxSleepTime
|
return resp, reqErr
|
||||||
}
|
}
|
||||||
time.Sleep(sleepTime)
|
|
||||||
discoveryRetries.Inc()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,3 +313,17 @@ var (
|
|||||||
discoveryRequests = metrics.NewCounter(`vm_promscrape_discovery_requests_total`)
|
discoveryRequests = metrics.NewCounter(`vm_promscrape_discovery_requests_total`)
|
||||||
discoveryRetries = metrics.NewCounter(`vm_promscrape_discovery_retries_total`)
|
discoveryRetries = metrics.NewCounter(`vm_promscrape_discovery_retries_total`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SleepCtx sleeps for sleepDuration.
|
||||||
|
//
|
||||||
|
// It immediately returns false on ctx cancel or deadline, without waiting for sleepDuration.
|
||||||
|
func SleepCtx(ctx context.Context, sleepDuration time.Duration) bool {
|
||||||
|
t := timerpool.Get(sleepDuration)
|
||||||
|
defer timerpool.Put(t)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return false
|
||||||
|
case <-t.C:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ func runScraper(configFile string, pushData func(at *auth.Token, wr *prompbmarsh
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metrics.RegisterSet(configMetricsSet)
|
||||||
|
|
||||||
// Register SIGHUP handler for config reload before loadConfig.
|
// Register SIGHUP handler for config reload before loadConfig.
|
||||||
// This guarantees that the config will be re-read if the signal arrives just after loadConfig.
|
// This guarantees that the config will be re-read if the signal arrives just after loadConfig.
|
||||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1240
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1240
|
||||||
@@ -157,6 +159,7 @@ func runScraper(configFile string, pushData func(at *auth.Token, wr *prompbmarsh
|
|||||||
goto waitForChans
|
goto waitForChans
|
||||||
}
|
}
|
||||||
if bytes.Equal(data, dataNew) {
|
if bytes.Equal(data, dataNew) {
|
||||||
|
configSuccess.Set(1)
|
||||||
logger.Infof("nothing changed in %q", configFile)
|
logger.Infof("nothing changed in %q", configFile)
|
||||||
goto waitForChans
|
goto waitForChans
|
||||||
}
|
}
|
||||||
@@ -174,6 +177,7 @@ func runScraper(configFile string, pushData func(at *auth.Token, wr *prompbmarsh
|
|||||||
goto waitForChans
|
goto waitForChans
|
||||||
}
|
}
|
||||||
if bytes.Equal(data, dataNew) {
|
if bytes.Equal(data, dataNew) {
|
||||||
|
configSuccess.Set(1)
|
||||||
// Nothing changed since the previous loadConfig
|
// Nothing changed since the previous loadConfig
|
||||||
goto waitForChans
|
goto waitForChans
|
||||||
}
|
}
|
||||||
@@ -198,10 +202,11 @@ func runScraper(configFile string, pushData func(at *auth.Token, wr *prompbmarsh
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
configReloads = metrics.NewCounter(`vm_promscrape_config_reloads_total`)
|
configMetricsSet = metrics.NewSet()
|
||||||
configReloadErrors = metrics.NewCounter(`vm_promscrape_config_reloads_errors_total`)
|
configReloads = configMetricsSet.NewCounter(`vm_promscrape_config_reloads_total`)
|
||||||
configSuccess = metrics.NewCounter(`vm_promscrape_config_last_reload_successful`)
|
configReloadErrors = configMetricsSet.NewCounter(`vm_promscrape_config_reloads_errors_total`)
|
||||||
configTimestamp = metrics.NewCounter(`vm_promscrape_config_last_reload_success_timestamp_seconds`)
|
configSuccess = configMetricsSet.NewCounter(`vm_promscrape_config_last_reload_successful`)
|
||||||
|
configTimestamp = configMetricsSet.NewCounter(`vm_promscrape_config_last_reload_success_timestamp_seconds`)
|
||||||
)
|
)
|
||||||
|
|
||||||
type scrapeConfigs struct {
|
type scrapeConfigs struct {
|
||||||
|
|||||||
@@ -255,8 +255,7 @@ func (x *Labels) RemoveLabelsWithDoubleUnderscorePrefix() {
|
|||||||
dst := x.Labels[:0]
|
dst := x.Labels[:0]
|
||||||
for _, label := range src {
|
for _, label := range src {
|
||||||
name := label.Name
|
name := label.Name
|
||||||
// A hack: do not delete __vm_filepath label, since it is used by internal logic for FileSDConfig.
|
if strings.HasPrefix(name, "__") {
|
||||||
if strings.HasPrefix(name, "__") && name != "__vm_filepath" {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dst = append(dst, label)
|
dst = append(dst, label)
|
||||||
|
|||||||
@@ -172,6 +172,55 @@ func TestLabelsRemoveLabelsWithDoubleUnderscorePrefix(t *testing.T) {
|
|||||||
}
|
}
|
||||||
f(`{}`, `{}`)
|
f(`{}`, `{}`)
|
||||||
f(`{foo="bar"}`, `{foo="bar"}`)
|
f(`{foo="bar"}`, `{foo="bar"}`)
|
||||||
f(`{__meta_foo="bar",a="b",__name__="foo",__vm_filepath="aa"}`, `{a="b",__vm_filepath="aa"}`)
|
f(`{__meta_foo="bar",a="b",__name__="foo",__vm_filepath="aa"}`, `{a="b"}`)
|
||||||
f(`{__meta_foo="bdffr",foo="bar",__meta_xxx="basd"}`, `{foo="bar"}`)
|
f(`{__meta_foo="bdffr",foo="bar",__meta_xxx="basd"}`, `{foo="bar"}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewLabelsFromStringSuccess(t *testing.T) {
|
||||||
|
f := func(s, resultExpected string) {
|
||||||
|
t.Helper()
|
||||||
|
labels, err := NewLabelsFromString(s)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
result := labels.String()
|
||||||
|
if result != resultExpected {
|
||||||
|
t.Fatalf("unexpected result;\ngot\n%s\nwant\n%s", result, resultExpected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f("{}", "{}")
|
||||||
|
f("foo", `{__name__="foo"}`)
|
||||||
|
f(`foo{bar="baz"}`, `{__name__="foo",bar="baz"}`)
|
||||||
|
f(`foo {bar="baz", a="b"}`, `{__name__="foo",bar="baz",a="b"}`)
|
||||||
|
f(`{foo="bar", baz="a"}`, `{foo="bar",baz="a"}`)
|
||||||
|
f(`{__name__="aaa"}`, `{__name__="aaa"}`)
|
||||||
|
f(`{__name__="abc",de="fg"}`, `{__name__="abc",de="fg"}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewLabelsFromStringFailure(t *testing.T) {
|
||||||
|
f := func(s string) {
|
||||||
|
t.Helper()
|
||||||
|
labels, err := NewLabelsFromString(s)
|
||||||
|
if labels != nil {
|
||||||
|
t.Fatalf("unexpected non-nil labels: %s", labels)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expecting non-nil error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f("")
|
||||||
|
f("foo bar")
|
||||||
|
f(`foo{`)
|
||||||
|
f(`foo{bar`)
|
||||||
|
f(`foo{bar=`)
|
||||||
|
f(`foo{bar="`)
|
||||||
|
f(`foo{bar="baz`)
|
||||||
|
f(`foo{bar="baz"`)
|
||||||
|
f(`foo{bar="baz",`)
|
||||||
|
f(`foo{"bar"="baz"}`)
|
||||||
|
f(`{"bar":"baz"}`)
|
||||||
|
f(`{bar:"baz"}`)
|
||||||
|
f(`{bar=~"baz"}`)
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func getPushgatewayLabels(path string) ([]prompbmarshal.Label, error) {
|
|||||||
s = s[n+1:]
|
s = s[n+1:]
|
||||||
}
|
}
|
||||||
if isBase64 {
|
if isBase64 {
|
||||||
data, err := base64.URLEncoding.DecodeString(value)
|
data, err := base64.RawURLEncoding.DecodeString(strings.TrimRight(value, "="))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot base64-decode value=%q for label=%q: %w", value, name, err)
|
return nil, fmt.Errorf("cannot base64-decode value=%q for label=%q: %w", value, name, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ func TestGetPushgatewayLabelsSuccess(t *testing.T) {
|
|||||||
f("/foo/metrics/job@base64/Zm9v", `{job="foo"}`)
|
f("/foo/metrics/job@base64/Zm9v", `{job="foo"}`)
|
||||||
f("/foo/metrics/job/x/a/foo/aaa/bar", `{a="foo",aaa="bar",job="x"}`)
|
f("/foo/metrics/job/x/a/foo/aaa/bar", `{a="foo",aaa="bar",job="x"}`)
|
||||||
f("/foo/metrics/job/x/a@base64/Zm9v", `{a="foo",job="x"}`)
|
f("/foo/metrics/job/x/a@base64/Zm9v", `{a="foo",job="x"}`)
|
||||||
|
f("/metrics/job/test/region@base64/YXotc291dGhlYXN0LTEtZjAxL3d6eS1hei1zb3V0aGVhc3QtMQ", `{job="test",region="az-southeast-1-f01/wzy-az-southeast-1"}`)
|
||||||
|
f("/metrics/job/test/empty@base64/=", `{job="test"}`)
|
||||||
|
f("/metrics/job/test/test@base64/PT0vPT0", `{job="test",test="==/=="}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetPushgatewayLabelsFailure(t *testing.T) {
|
func TestGetPushgatewayLabelsFailure(t *testing.T) {
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isEOFLikeError(err error) bool {
|
func isEOFLikeError(err error) bool {
|
||||||
if errors.Is(err, io.EOF) {
|
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
s := err.Error()
|
s := err.Error()
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user