mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-15 01:54:06 -08:00
Merge pull request #95 from grafana/update-prometheus-2022-01-03
Update prometheus to `a961062c37f1675d5925d8b74ddda0a6322ed82d`
This commit is contained in:
commit
5205ff1a81
|
@ -2,7 +2,7 @@
|
||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
orbs:
|
orbs:
|
||||||
prometheus: prometheus/prometheus@0.14.0
|
prometheus: prometheus/prometheus@0.15.0
|
||||||
go: circleci/go@1.7.0
|
go: circleci/go@1.7.0
|
||||||
win: circleci/windows@2.3.0
|
win: circleci/windows@2.3.0
|
||||||
|
|
||||||
|
@ -12,9 +12,9 @@ executors:
|
||||||
golang:
|
golang:
|
||||||
docker:
|
docker:
|
||||||
- image: quay.io/prometheus/golang-builder:1.17-base
|
- image: quay.io/prometheus/golang-builder:1.17-base
|
||||||
golang_115:
|
golang_oldest:
|
||||||
docker:
|
docker:
|
||||||
- image: quay.io/prometheus/golang-builder:1.15-base
|
- image: quay.io/prometheus/golang-builder:1.16-base
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test_go:
|
test_go:
|
||||||
|
@ -89,10 +89,11 @@ jobs:
|
||||||
GOGC: "20"
|
GOGC: "20"
|
||||||
GOOPTS: "-p 2"
|
GOOPTS: "-p 2"
|
||||||
|
|
||||||
test_tsdb_go115:
|
test_golang_oldest:
|
||||||
executor: golang_115
|
executor: golang_oldest
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
- run: make build
|
||||||
- run: go test ./tsdb/...
|
- run: go test ./tsdb/...
|
||||||
- run: go test ./tsdb/ -test.tsdb-isolation=false
|
- run: go test ./tsdb/ -test.tsdb-isolation=false
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ workflows:
|
||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
only: /.*/
|
only: /.*/
|
||||||
- test_tsdb_go115:
|
- test_golang_oldest:
|
||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
only: /.*/
|
only: /.*/
|
||||||
|
|
1
.github/dependabot.yml
vendored
1
.github/dependabot.yml
vendored
|
@ -6,6 +6,7 @@ updates:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
directory: "/web/ui"
|
directory: "/web/ui"
|
||||||
|
open-pull-requests-limit: 0
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
|
|
35
CHANGELOG.md
35
CHANGELOG.md
|
@ -1,18 +1,12 @@
|
||||||
## 2.32.0-rc.0 / 2021-12-01
|
## 2.32.1 / 2021-12-17
|
||||||
|
|
||||||
This list of changes is relative to [v2.32.0-beta.0](https://github.com/prometheus/prometheus/releases/tag/v2.32.0-beta.0), which was a special 2.32 beta release to pre-publish the Prometheus Agent features.
|
* [BUGFIX] Scrape: Fix reporting metrics when sample limit is reached during the report. #9996
|
||||||
|
* [BUGFIX] Scrape: Ensure that scrape interval and scrape timeout are always set. #10023
|
||||||
|
* [BUGFIX] TSDB: Expose and fix bug in iterators' `Seek()` method. #10030
|
||||||
|
|
||||||
* [FEATURE] TSDB: Add support for forwarding exemplars in Agent mode. #9664
|
## 2.32.0 / 2021-12-09
|
||||||
* [FEATURE] UI: Adapt web UI for Prometheus Agent mode. #9851
|
|
||||||
* [ENHANCEMENT] Linode SD: Tune API request page sizes. #9779
|
|
||||||
* [BUGFIX] TSDB: Fix panic when checkpoint directory is empty. #9687
|
|
||||||
* [BUGFIX] TSDB: Fix panic, out of order chunks, and race warning during WAL replay. #9856
|
|
||||||
* [BUGFIX] UI: Correctly render links for targets with IPv6 addresses that contain a Zone ID. #9853
|
|
||||||
* [BUGFIX] Promtool: Fix checking of `authorization.credentials_file` and `bearer_token_file` fields. #9883
|
|
||||||
|
|
||||||
## 2.32.0-beta.0 / 2021-11-16
|
This release introduces the Prometheus Agent, a new mode of operation for
|
||||||
|
|
||||||
This beta release introduces the Prometheus Agent, a new mode of operation for
|
|
||||||
Prometheus optimized for remote-write only scenarios. In this mode, Prometheus
|
Prometheus optimized for remote-write only scenarios. In this mode, Prometheus
|
||||||
does not generate blocks on the local filesystem and is not queryable locally.
|
does not generate blocks on the local filesystem and is not queryable locally.
|
||||||
Enable with `--enable-feature=agent`.
|
Enable with `--enable-feature=agent`.
|
||||||
|
@ -20,7 +14,7 @@ Enable with `--enable-feature=agent`.
|
||||||
Learn more about the Prometheus Agent in our [blog post](https://prometheus.io/blog/2021/11/16/agent/).
|
Learn more about the Prometheus Agent in our [blog post](https://prometheus.io/blog/2021/11/16/agent/).
|
||||||
|
|
||||||
* [CHANGE] remote-write: Change default max retry time from 100ms to 5 seconds. #9634
|
* [CHANGE] remote-write: Change default max retry time from 100ms to 5 seconds. #9634
|
||||||
* [FEATURE] Agent: New mode of operation optimized for remote-write only scenarios, without local storage. Enable with `--enable-feature=agent`. #8785
|
* [FEATURE] Agent: New mode of operation optimized for remote-write only scenarios, without local storage. Enable with `--enable-feature=agent`. #8785 #9851 #9664 #9939 #9941 #9943
|
||||||
* [FEATURE] Promtool: Add `promtool check service-discovery` command. #8970
|
* [FEATURE] Promtool: Add `promtool check service-discovery` command. #8970
|
||||||
* [FEATURE] UI: Add search in metrics dropdown. #9629
|
* [FEATURE] UI: Add search in metrics dropdown. #9629
|
||||||
* [FEATURE] Templates: Add parseDuration to template functions. #8817
|
* [FEATURE] Templates: Add parseDuration to template functions. #8817
|
||||||
|
@ -32,8 +26,19 @@ Learn more about the Prometheus Agent in our [blog post](https://prometheus.io/b
|
||||||
* [ENHANCEMENT] TSDB: Optimize query by skipping unneeded sorting in TSDB. #9673
|
* [ENHANCEMENT] TSDB: Optimize query by skipping unneeded sorting in TSDB. #9673
|
||||||
* [ENHANCEMENT] Templates: Support int and uint as datatypes for template formatting. #9680
|
* [ENHANCEMENT] Templates: Support int and uint as datatypes for template formatting. #9680
|
||||||
* [ENHANCEMENT] UI: Prefer `rate` over `rad`, `delta` over `deg`, and `count` over `cos` in autocomplete. #9688
|
* [ENHANCEMENT] UI: Prefer `rate` over `rad`, `delta` over `deg`, and `count` over `cos` in autocomplete. #9688
|
||||||
|
* [ENHANCEMENT] Linode SD: Tune API request page sizes. #9779
|
||||||
* [BUGFIX] TSDB: Add more size checks when writing individual sections in the index. #9710
|
* [BUGFIX] TSDB: Add more size checks when writing individual sections in the index. #9710
|
||||||
* [BUGFIX] PromQL: Make `deriv()` return zero values for constant series. #9728
|
* [BUGFIX] PromQL: Make `deriv()` return zero values for constant series. #9728
|
||||||
|
* [BUGFIX] TSDB: Fix panic when checkpoint directory is empty. #9687
|
||||||
|
* [BUGFIX] TSDB: Fix panic, out of order chunks, and race warning during WAL replay. #9856
|
||||||
|
* [BUGFIX] UI: Correctly render links for targets with IPv6 addresses that contain a Zone ID. #9853
|
||||||
|
* [BUGFIX] Promtool: Fix checking of `authorization.credentials_file` and `bearer_token_file` fields. #9883
|
||||||
|
* [BUGFIX] Uyuni SD: Fix null pointer exception during initialization. #9924 #9950
|
||||||
|
* [BUGFIX] TSDB: Fix queries after a failed snapshot replay. #9980
|
||||||
|
|
||||||
|
## 2.31.2 / 2021-12-09
|
||||||
|
|
||||||
|
* [BUGFIX] TSDB: Fix queries after a failed snapshot replay. #9980
|
||||||
|
|
||||||
## 2.31.1 / 2021-11-05
|
## 2.31.1 / 2021-11-05
|
||||||
|
|
||||||
|
@ -65,6 +70,10 @@ Learn more about the Prometheus Agent in our [blog post](https://prometheus.io/b
|
||||||
* [BUGFIX] TSDB: Fix memory leak in samples deletion. #9151
|
* [BUGFIX] TSDB: Fix memory leak in samples deletion. #9151
|
||||||
* [BUGFIX] UI: Use consistent margin-bottom for all alert kinds. #9318
|
* [BUGFIX] UI: Use consistent margin-bottom for all alert kinds. #9318
|
||||||
|
|
||||||
|
## 2.30.4 / 2021-12-09
|
||||||
|
|
||||||
|
* [BUGFIX] TSDB: Fix queries after a failed snapshot replay. #9980
|
||||||
|
|
||||||
## 2.30.3 / 2021-10-05
|
## 2.30.3 / 2021-10-05
|
||||||
|
|
||||||
* [BUGFIX] TSDB: Fix panic on failed snapshot replay. #9438
|
* [BUGFIX] TSDB: Fix panic on failed snapshot replay. #9438
|
||||||
|
|
|
@ -56,7 +56,7 @@ Prometheus will now be reachable at http://localhost:9090/.
|
||||||
### Building from source
|
### Building from source
|
||||||
|
|
||||||
To build Prometheus from source code, You need:
|
To build Prometheus from source code, You need:
|
||||||
* Go [version 1.14 or greater](https://golang.org/doc/install).
|
* Go [version 1.16 or greater](https://golang.org/doc/install).
|
||||||
* NodeJS [version 16 or greater](https://nodejs.org/).
|
* NodeJS [version 16 or greater](https://nodejs.org/).
|
||||||
* npm [version 7 or greater](https://www.npmjs.com/).
|
* npm [version 7 or greater](https://www.npmjs.com/).
|
||||||
|
|
||||||
|
|
|
@ -381,7 +381,7 @@ func main() {
|
||||||
serverOnlyFlag(a, "query.max-samples", "Maximum number of samples a single query can load into memory. Note that queries will fail if they try to load more samples than this into memory, so this also limits the number of samples a query can return.").
|
serverOnlyFlag(a, "query.max-samples", "Maximum number of samples a single query can load into memory. Note that queries will fail if they try to load more samples than this into memory, so this also limits the number of samples a query can return.").
|
||||||
Default("50000000").IntVar(&cfg.queryMaxSamples)
|
Default("50000000").IntVar(&cfg.queryMaxSamples)
|
||||||
|
|
||||||
a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: exemplar-storage, expand-external-labels, memory-snapshot-on-shutdown, promql-at-modifier, promql-negative-offset, remote-write-receiver, extra-scrape-metrics, new-service-discovery-manager. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details.").
|
a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: agent, exemplar-storage, expand-external-labels, memory-snapshot-on-shutdown, promql-at-modifier, promql-negative-offset, remote-write-receiver, extra-scrape-metrics, new-service-discovery-manager. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details.").
|
||||||
Default("").StringsVar(&cfg.featureList)
|
Default("").StringsVar(&cfg.featureList)
|
||||||
|
|
||||||
promlogflag.AddFlags(a, &cfg.promlogConfig)
|
promlogflag.AddFlags(a, &cfg.promlogConfig)
|
||||||
|
|
|
@ -56,6 +56,13 @@ import (
|
||||||
"github.com/prometheus/prometheus/scrape"
|
"github.com/prometheus/prometheus/scrape"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
successExitCode = 0
|
||||||
|
failureExitCode = 1
|
||||||
|
// Exit code 3 is used for "one or more lint issues detected".
|
||||||
|
lintErrExitCode = 3
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := kingpin.New(filepath.Base(os.Args[0]), "Tooling for the Prometheus monitoring system.").UsageWriter(os.Stdout)
|
app := kingpin.New(filepath.Base(os.Args[0]), "Tooling for the Prometheus monitoring system.").UsageWriter(os.Stdout)
|
||||||
app.Version(version.Print("promtool"))
|
app.Version(version.Print("promtool"))
|
||||||
|
@ -298,9 +305,9 @@ func CheckConfig(agentMode, checkSyntaxOnly bool, files ...string) int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if failed {
|
if failed {
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckWebConfig validates web configuration files.
|
// CheckWebConfig validates web configuration files.
|
||||||
|
@ -316,9 +323,9 @@ func CheckWebConfig(files ...string) int {
|
||||||
fmt.Fprintln(os.Stderr, f, "SUCCESS")
|
fmt.Fprintln(os.Stderr, f, "SUCCESS")
|
||||||
}
|
}
|
||||||
if failed {
|
if failed {
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkFileExists(fn string) error {
|
func checkFileExists(fn string) error {
|
||||||
|
@ -521,9 +528,9 @@ func CheckRules(files ...string) int {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
if failed {
|
if failed {
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkRules(filename string) (int, []error) {
|
func checkRules(filename string) (int, []error) {
|
||||||
|
@ -531,7 +538,7 @@ func checkRules(filename string) (int, []error) {
|
||||||
|
|
||||||
rgs, errs := rulefmt.ParseFile(filename)
|
rgs, errs := rulefmt.ParseFile(filename)
|
||||||
if errs != nil {
|
if errs != nil {
|
||||||
return 0, errs
|
return successExitCode, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
numRules := 0
|
numRules := 0
|
||||||
|
@ -627,7 +634,7 @@ func CheckMetrics() int {
|
||||||
problems, err := l.Lint()
|
problems, err := l.Lint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error while linting:", err)
|
fmt.Fprintln(os.Stderr, "error while linting:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range problems {
|
for _, p := range problems {
|
||||||
|
@ -635,10 +642,10 @@ func CheckMetrics() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(problems) > 0 {
|
if len(problems) > 0 {
|
||||||
return 3
|
return lintErrExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryInstant performs an instant query against a Prometheus server.
|
// QueryInstant performs an instant query against a Prometheus server.
|
||||||
|
@ -654,7 +661,7 @@ func QueryInstant(url *url.URL, query, evalTime string, p printer) int {
|
||||||
c, err := api.NewClient(config)
|
c, err := api.NewClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
eTime := time.Now()
|
eTime := time.Now()
|
||||||
|
@ -662,7 +669,7 @@ func QueryInstant(url *url.URL, query, evalTime string, p printer) int {
|
||||||
eTime, err = parseTime(evalTime)
|
eTime, err = parseTime(evalTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error parsing evaluation time:", err)
|
fmt.Fprintln(os.Stderr, "error parsing evaluation time:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,7 +685,7 @@ func QueryInstant(url *url.URL, query, evalTime string, p printer) int {
|
||||||
|
|
||||||
p.printValue(val)
|
p.printValue(val)
|
||||||
|
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryRange performs a range query against a Prometheus server.
|
// QueryRange performs a range query against a Prometheus server.
|
||||||
|
@ -703,7 +710,7 @@ func QueryRange(url *url.URL, headers map[string]string, query, start, end strin
|
||||||
c, err := api.NewClient(config)
|
c, err := api.NewClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
var stime, etime time.Time
|
var stime, etime time.Time
|
||||||
|
@ -714,7 +721,7 @@ func QueryRange(url *url.URL, headers map[string]string, query, start, end strin
|
||||||
etime, err = parseTime(end)
|
etime, err = parseTime(end)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error parsing end time:", err)
|
fmt.Fprintln(os.Stderr, "error parsing end time:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,13 +731,13 @@ func QueryRange(url *url.URL, headers map[string]string, query, start, end strin
|
||||||
stime, err = parseTime(start)
|
stime, err = parseTime(start)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error parsing start time:", err)
|
fmt.Fprintln(os.Stderr, "error parsing start time:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !stime.Before(etime) {
|
if !stime.Before(etime) {
|
||||||
fmt.Fprintln(os.Stderr, "start time is not before end time")
|
fmt.Fprintln(os.Stderr, "start time is not before end time")
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
if step == 0 {
|
if step == 0 {
|
||||||
|
@ -751,7 +758,7 @@ func QueryRange(url *url.URL, headers map[string]string, query, start, end strin
|
||||||
}
|
}
|
||||||
|
|
||||||
p.printValue(val)
|
p.printValue(val)
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuerySeries queries for a series against a Prometheus server.
|
// QuerySeries queries for a series against a Prometheus server.
|
||||||
|
@ -767,13 +774,13 @@ func QuerySeries(url *url.URL, matchers []string, start, end string, p printer)
|
||||||
c, err := api.NewClient(config)
|
c, err := api.NewClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
stime, etime, err := parseStartTimeAndEndTime(start, end)
|
stime, etime, err := parseStartTimeAndEndTime(start, end)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run query against client.
|
// Run query against client.
|
||||||
|
@ -787,7 +794,7 @@ func QuerySeries(url *url.URL, matchers []string, start, end string, p printer)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.printSeries(val)
|
p.printSeries(val)
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryLabels queries for label values against a Prometheus server.
|
// QueryLabels queries for label values against a Prometheus server.
|
||||||
|
@ -803,13 +810,13 @@ func QueryLabels(url *url.URL, name, start, end string, p printer) int {
|
||||||
c, err := api.NewClient(config)
|
c, err := api.NewClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
stime, etime, err := parseStartTimeAndEndTime(start, end)
|
stime, etime, err := parseStartTimeAndEndTime(start, end)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run query against client.
|
// Run query against client.
|
||||||
|
@ -826,7 +833,7 @@ func QueryLabels(url *url.URL, name, start, end string, p printer) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
p.printLabelValues(val)
|
p.printLabelValues(val)
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleAPIError(err error) int {
|
func handleAPIError(err error) int {
|
||||||
|
@ -837,7 +844,7 @@ func handleAPIError(err error) int {
|
||||||
fmt.Fprintln(os.Stderr, "query error:", err)
|
fmt.Fprintln(os.Stderr, "query error:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseStartTimeAndEndTime(start, end string) (time.Time, time.Time, error) {
|
func parseStartTimeAndEndTime(start, end string) (time.Time, time.Time, error) {
|
||||||
|
@ -929,9 +936,9 @@ func debugPprof(url string) int {
|
||||||
endPointGroups: pprofEndpoints,
|
endPointGroups: pprofEndpoints,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error completing debug command:", err)
|
fmt.Fprintln(os.Stderr, "error completing debug command:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugMetrics(url string) int {
|
func debugMetrics(url string) int {
|
||||||
|
@ -941,9 +948,9 @@ func debugMetrics(url string) int {
|
||||||
endPointGroups: metricsEndpoints,
|
endPointGroups: metricsEndpoints,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error completing debug command:", err)
|
fmt.Fprintln(os.Stderr, "error completing debug command:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugAll(url string) int {
|
func debugAll(url string) int {
|
||||||
|
@ -953,9 +960,9 @@ func debugAll(url string) int {
|
||||||
endPointGroups: allEndpoints,
|
endPointGroups: allEndpoints,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error completing debug command:", err)
|
fmt.Fprintln(os.Stderr, "error completing debug command:", err)
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
type printer interface {
|
type printer interface {
|
||||||
|
|
|
@ -43,7 +43,7 @@ func CheckSD(sdConfigFiles, sdJobName string, sdTimeout time.Duration) int {
|
||||||
cfg, err := config.LoadFile(sdConfigFiles, false, false, logger)
|
cfg, err := config.LoadFile(sdConfigFiles, false, false, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "Cannot load config", err)
|
fmt.Fprintln(os.Stderr, "Cannot load config", err)
|
||||||
return 2
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
var scrapeConfig *config.ScrapeConfig
|
var scrapeConfig *config.ScrapeConfig
|
||||||
|
@ -63,7 +63,7 @@ func CheckSD(sdConfigFiles, sdJobName string, sdTimeout time.Duration) int {
|
||||||
for _, job := range jobs {
|
for _, job := range jobs {
|
||||||
fmt.Fprintf(os.Stderr, "\t%s\n", job)
|
fmt.Fprintf(os.Stderr, "\t%s\n", job)
|
||||||
}
|
}
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
targetGroupChan := make(chan []*targetgroup.Group)
|
targetGroupChan := make(chan []*targetgroup.Group)
|
||||||
|
@ -74,7 +74,7 @@ func CheckSD(sdConfigFiles, sdJobName string, sdTimeout time.Duration) int {
|
||||||
d, err := cfg.NewDiscoverer(discovery.DiscovererOptions{Logger: logger})
|
d, err := cfg.NewDiscoverer(discovery.DiscovererOptions{Logger: logger})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "Could not create new discoverer", err)
|
fmt.Fprintln(os.Stderr, "Could not create new discoverer", err)
|
||||||
return 2
|
return failureExitCode
|
||||||
}
|
}
|
||||||
go d.Run(ctx, targetGroupChan)
|
go d.Run(ctx, targetGroupChan)
|
||||||
}
|
}
|
||||||
|
@ -100,11 +100,11 @@ outerLoop:
|
||||||
res, err := json.MarshalIndent(results, "", " ")
|
res, err := json.MarshalIndent(results, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Could not marshal result json: %s", err)
|
fmt.Fprintf(os.Stderr, "Could not marshal result json: %s", err)
|
||||||
return 2
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%s", res)
|
fmt.Printf("%s", res)
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSDCheckResult(targetGroups []*targetgroup.Group, scrapeConfig *config.ScrapeConfig) []sdCheckResult {
|
func getSDCheckResult(targetGroups []*targetgroup.Group, scrapeConfig *config.ScrapeConfig) []sdCheckResult {
|
||||||
|
|
|
@ -15,6 +15,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
|
|
||||||
|
@ -37,6 +38,8 @@ func TestSDCheckResult(t *testing.T) {
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
scrapeConfig := &config.ScrapeConfig{
|
scrapeConfig := &config.ScrapeConfig{
|
||||||
|
ScrapeInterval: model.Duration(1 * time.Minute),
|
||||||
|
ScrapeTimeout: model.Duration(10 * time.Second),
|
||||||
RelabelConfigs: []*relabel.Config{{
|
RelabelConfigs: []*relabel.Config{{
|
||||||
SourceLabels: model.LabelNames{"foo"},
|
SourceLabels: model.LabelNames{"foo"},
|
||||||
Action: relabel.Replace,
|
Action: relabel.Replace,
|
||||||
|
@ -50,14 +53,14 @@ func TestSDCheckResult(t *testing.T) {
|
||||||
{
|
{
|
||||||
DiscoveredLabels: labels.Labels{
|
DiscoveredLabels: labels.Labels{
|
||||||
labels.Label{Name: "__address__", Value: "localhost:8080"},
|
labels.Label{Name: "__address__", Value: "localhost:8080"},
|
||||||
labels.Label{Name: "__scrape_interval__", Value: "0s"},
|
labels.Label{Name: "__scrape_interval__", Value: "1m"},
|
||||||
labels.Label{Name: "__scrape_timeout__", Value: "0s"},
|
labels.Label{Name: "__scrape_timeout__", Value: "10s"},
|
||||||
labels.Label{Name: "foo", Value: "bar"},
|
labels.Label{Name: "foo", Value: "bar"},
|
||||||
},
|
},
|
||||||
Labels: labels.Labels{
|
Labels: labels.Labels{
|
||||||
labels.Label{Name: "__address__", Value: "localhost:8080"},
|
labels.Label{Name: "__address__", Value: "localhost:8080"},
|
||||||
labels.Label{Name: "__scrape_interval__", Value: "0s"},
|
labels.Label{Name: "__scrape_interval__", Value: "1m"},
|
||||||
labels.Label{Name: "__scrape_timeout__", Value: "0s"},
|
labels.Label{Name: "__scrape_timeout__", Value: "10s"},
|
||||||
labels.Label{Name: "foo", Value: "bar"},
|
labels.Label{Name: "foo", Value: "bar"},
|
||||||
labels.Label{Name: "instance", Value: "localhost:8080"},
|
labels.Label{Name: "instance", Value: "localhost:8080"},
|
||||||
labels.Label{Name: "newfoo", Value: "bar"},
|
labels.Label{Name: "newfoo", Value: "bar"},
|
||||||
|
|
34
cmd/promtool/testdata/long-period.yml
vendored
Normal file
34
cmd/promtool/testdata/long-period.yml
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# Evaluate once every 100d to avoid this taking too long.
|
||||||
|
evaluation_interval: 100d
|
||||||
|
|
||||||
|
rule_files:
|
||||||
|
- rules.yml
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- interval: 100d
|
||||||
|
input_series:
|
||||||
|
- series: test
|
||||||
|
# Max time in time.Duration is 106751d from 1970 (2^63/10^9), i.e. 2262.
|
||||||
|
# We use the nearest 100 days to that to ensure the unit tests can fully
|
||||||
|
# cover the expected range.
|
||||||
|
values: '0+1x1067'
|
||||||
|
|
||||||
|
promql_expr_test:
|
||||||
|
- expr: timestamp(test)
|
||||||
|
eval_time: 0m
|
||||||
|
exp_samples:
|
||||||
|
- value: 0
|
||||||
|
- expr: test
|
||||||
|
eval_time: 100d # one evaluation_interval.
|
||||||
|
exp_samples:
|
||||||
|
- labels: test
|
||||||
|
value: 1
|
||||||
|
- expr: timestamp(test)
|
||||||
|
eval_time: 106700d
|
||||||
|
exp_samples:
|
||||||
|
- value: 9218880000 # 106700d -> seconds.
|
||||||
|
- expr: fixed_data
|
||||||
|
eval_time: 106700d
|
||||||
|
exp_samples:
|
||||||
|
- labels: fixed_data
|
||||||
|
value: 1
|
|
@ -56,9 +56,9 @@ func RulesUnitTest(queryOpts promql.LazyLoaderOpts, files ...string) int {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
if failed {
|
if failed {
|
||||||
return 1
|
return failureExitCode
|
||||||
}
|
}
|
||||||
return 0
|
return successExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func ruleUnitTest(filename string, queryOpts promql.LazyLoaderOpts) []error {
|
func ruleUnitTest(filename string, queryOpts promql.LazyLoaderOpts) []error {
|
||||||
|
|
|
@ -36,6 +36,13 @@ func TestRulesUnitTest(t *testing.T) {
|
||||||
},
|
},
|
||||||
want: 0,
|
want: 0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Long evaluation interval",
|
||||||
|
args: args{
|
||||||
|
files: []string{"./testdata/long-period.yml"},
|
||||||
|
},
|
||||||
|
want: 0,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Bad input series",
|
name: "Bad input series",
|
||||||
args: args{
|
args: args{
|
||||||
|
|
|
@ -615,3 +615,86 @@ func TestEndpointsDiscoveryNamespaces(t *testing.T) {
|
||||||
},
|
},
|
||||||
}.Run(t)
|
}.Run(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEndpointsDiscoveryOwnNamespace(t *testing.T) {
|
||||||
|
epOne := makeEndpoints()
|
||||||
|
epOne.Namespace = "own-ns"
|
||||||
|
|
||||||
|
epTwo := makeEndpoints()
|
||||||
|
epTwo.Namespace = "non-own-ns"
|
||||||
|
|
||||||
|
podOne := &v1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "testpod",
|
||||||
|
Namespace: "own-ns",
|
||||||
|
UID: types.UID("deadbeef"),
|
||||||
|
},
|
||||||
|
Spec: v1.PodSpec{
|
||||||
|
NodeName: "testnode",
|
||||||
|
Containers: []v1.Container{
|
||||||
|
{
|
||||||
|
Name: "p1",
|
||||||
|
Ports: []v1.ContainerPort{
|
||||||
|
{
|
||||||
|
Name: "mainport",
|
||||||
|
ContainerPort: 9000,
|
||||||
|
Protocol: v1.ProtocolTCP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: v1.PodStatus{
|
||||||
|
HostIP: "2.3.4.5",
|
||||||
|
PodIP: "4.3.2.1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
podTwo := podOne.DeepCopy()
|
||||||
|
podTwo.Namespace = "non-own-ns"
|
||||||
|
|
||||||
|
objs := []runtime.Object{
|
||||||
|
epOne,
|
||||||
|
epTwo,
|
||||||
|
podOne,
|
||||||
|
podTwo,
|
||||||
|
}
|
||||||
|
|
||||||
|
n, _ := makeDiscovery(RoleEndpoint, NamespaceDiscovery{IncludeOwnNamespace: true}, objs...)
|
||||||
|
|
||||||
|
k8sDiscoveryTest{
|
||||||
|
discovery: n,
|
||||||
|
expectedMaxItems: 1,
|
||||||
|
expectedRes: map[string]*targetgroup.Group{
|
||||||
|
"endpoints/own-ns/testendpoints": {
|
||||||
|
Targets: []model.LabelSet{
|
||||||
|
{
|
||||||
|
"__address__": "1.2.3.4:9000",
|
||||||
|
"__meta_kubernetes_endpoint_hostname": "testendpoint1",
|
||||||
|
"__meta_kubernetes_endpoint_node_name": "foobar",
|
||||||
|
"__meta_kubernetes_endpoint_port_name": "testport",
|
||||||
|
"__meta_kubernetes_endpoint_port_protocol": "TCP",
|
||||||
|
"__meta_kubernetes_endpoint_ready": "true",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__address__": "2.3.4.5:9001",
|
||||||
|
"__meta_kubernetes_endpoint_port_name": "testport",
|
||||||
|
"__meta_kubernetes_endpoint_port_protocol": "TCP",
|
||||||
|
"__meta_kubernetes_endpoint_ready": "true",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__address__": "2.3.4.5:9001",
|
||||||
|
"__meta_kubernetes_endpoint_port_name": "testport",
|
||||||
|
"__meta_kubernetes_endpoint_port_protocol": "TCP",
|
||||||
|
"__meta_kubernetes_endpoint_ready": "false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"__meta_kubernetes_namespace": "own-ns",
|
||||||
|
"__meta_kubernetes_endpoints_name": "testendpoints",
|
||||||
|
},
|
||||||
|
Source: "endpoints/own-ns/testendpoints",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}.Run(t)
|
||||||
|
}
|
||||||
|
|
|
@ -630,3 +630,87 @@ func TestEndpointSliceDiscoveryNamespaces(t *testing.T) {
|
||||||
},
|
},
|
||||||
}.Run(t)
|
}.Run(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEndpointSliceDiscoveryOwnNamespace(t *testing.T) {
|
||||||
|
epOne := makeEndpointSlice()
|
||||||
|
epOne.Namespace = "own-ns"
|
||||||
|
|
||||||
|
epTwo := makeEndpointSlice()
|
||||||
|
epTwo.Namespace = "non-own-ns"
|
||||||
|
|
||||||
|
podOne := &v1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "testpod",
|
||||||
|
Namespace: "own-ns",
|
||||||
|
UID: types.UID("deadbeef"),
|
||||||
|
},
|
||||||
|
Spec: v1.PodSpec{
|
||||||
|
NodeName: "testnode",
|
||||||
|
Containers: []v1.Container{
|
||||||
|
{
|
||||||
|
Name: "p1",
|
||||||
|
Ports: []v1.ContainerPort{
|
||||||
|
{
|
||||||
|
Name: "mainport",
|
||||||
|
ContainerPort: 9000,
|
||||||
|
Protocol: v1.ProtocolTCP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: v1.PodStatus{
|
||||||
|
HostIP: "2.3.4.5",
|
||||||
|
PodIP: "4.3.2.1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
podTwo := podOne.DeepCopy()
|
||||||
|
podTwo.Namespace = "non-own-ns"
|
||||||
|
|
||||||
|
objs := []runtime.Object{
|
||||||
|
epOne,
|
||||||
|
epTwo,
|
||||||
|
podOne,
|
||||||
|
podTwo,
|
||||||
|
}
|
||||||
|
n, _ := makeDiscovery(RoleEndpointSlice, NamespaceDiscovery{IncludeOwnNamespace: true}, objs...)
|
||||||
|
|
||||||
|
k8sDiscoveryTest{
|
||||||
|
discovery: n,
|
||||||
|
expectedMaxItems: 1,
|
||||||
|
expectedRes: map[string]*targetgroup.Group{
|
||||||
|
"endpointslice/own-ns/testendpoints": {
|
||||||
|
Targets: []model.LabelSet{
|
||||||
|
{
|
||||||
|
"__address__": "1.2.3.4:9000",
|
||||||
|
"__meta_kubernetes_endpointslice_endpoint_hostname": "testendpoint1",
|
||||||
|
"__meta_kubernetes_endpointslice_port": "9000",
|
||||||
|
"__meta_kubernetes_endpointslice_port_name": "testport",
|
||||||
|
"__meta_kubernetes_endpointslice_port_protocol": "TCP",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__address__": "2.3.4.5:9000",
|
||||||
|
"__meta_kubernetes_endpointslice_endpoint_conditions_ready": "true",
|
||||||
|
"__meta_kubernetes_endpointslice_port": "9000",
|
||||||
|
"__meta_kubernetes_endpointslice_port_name": "testport",
|
||||||
|
"__meta_kubernetes_endpointslice_port_protocol": "TCP",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__address__": "3.4.5.6:9000",
|
||||||
|
"__meta_kubernetes_endpointslice_endpoint_conditions_ready": "false",
|
||||||
|
"__meta_kubernetes_endpointslice_port": "9000",
|
||||||
|
"__meta_kubernetes_endpointslice_port_name": "testport",
|
||||||
|
"__meta_kubernetes_endpointslice_port_protocol": "TCP",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"__meta_kubernetes_endpointslice_address_type": "IPv4",
|
||||||
|
"__meta_kubernetes_endpointslice_name": "testendpoints",
|
||||||
|
"__meta_kubernetes_namespace": "own-ns",
|
||||||
|
},
|
||||||
|
Source: "endpointslice/own-ns/testendpoints",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}.Run(t)
|
||||||
|
}
|
||||||
|
|
|
@ -323,3 +323,21 @@ func TestIngressDiscoveryNamespacesV1beta1(t *testing.T) {
|
||||||
expectedRes: expected,
|
expectedRes: expected,
|
||||||
}.Run(t)
|
}.Run(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIngressDiscoveryOwnNamespace(t *testing.T) {
|
||||||
|
n, c := makeDiscovery(RoleIngress, NamespaceDiscovery{IncludeOwnNamespace: true})
|
||||||
|
|
||||||
|
expected := expectedTargetGroups("own-ns", TLSNo)
|
||||||
|
k8sDiscoveryTest{
|
||||||
|
discovery: n,
|
||||||
|
afterStart: func() {
|
||||||
|
for _, ns := range []string{"own-ns", "non-own-ns"} {
|
||||||
|
obj := makeIngress(TLSNo)
|
||||||
|
obj.Namespace = ns
|
||||||
|
c.NetworkingV1().Ingresses(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
expectedMaxItems: 1,
|
||||||
|
expectedRes: expected,
|
||||||
|
}.Run(t)
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ package kubernetes
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -48,7 +49,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// kubernetesMetaLabelPrefix is the meta prefix used for all meta labels.
|
// metaLabelPrefix is the meta prefix used for all meta labels.
|
||||||
// in this discovery.
|
// in this discovery.
|
||||||
metaLabelPrefix = model.MetaLabelPrefix + "kubernetes_"
|
metaLabelPrefix = model.MetaLabelPrefix + "kubernetes_"
|
||||||
namespaceLabel = metaLabelPrefix + "namespace"
|
namespaceLabel = metaLabelPrefix + "namespace"
|
||||||
|
@ -230,7 +231,8 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
// NamespaceDiscovery is the configuration for discovering
|
// NamespaceDiscovery is the configuration for discovering
|
||||||
// Kubernetes namespaces.
|
// Kubernetes namespaces.
|
||||||
type NamespaceDiscovery struct {
|
type NamespaceDiscovery struct {
|
||||||
Names []string `yaml:"names"`
|
IncludeOwnNamespace bool `yaml:"own_namespace"`
|
||||||
|
Names []string `yaml:"names"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||||
|
@ -250,13 +252,21 @@ type Discovery struct {
|
||||||
namespaceDiscovery *NamespaceDiscovery
|
namespaceDiscovery *NamespaceDiscovery
|
||||||
discoverers []discovery.Discoverer
|
discoverers []discovery.Discoverer
|
||||||
selectors roleSelector
|
selectors roleSelector
|
||||||
|
ownNamespace string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discovery) getNamespaces() []string {
|
func (d *Discovery) getNamespaces() []string {
|
||||||
namespaces := d.namespaceDiscovery.Names
|
namespaces := d.namespaceDiscovery.Names
|
||||||
if len(namespaces) == 0 {
|
includeOwnNamespace := d.namespaceDiscovery.IncludeOwnNamespace
|
||||||
namespaces = []string{apiv1.NamespaceAll}
|
|
||||||
|
if len(namespaces) == 0 && !includeOwnNamespace {
|
||||||
|
return []string{apiv1.NamespaceAll}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if includeOwnNamespace {
|
||||||
|
return append(namespaces, d.ownNamespace)
|
||||||
|
}
|
||||||
|
|
||||||
return namespaces
|
return namespaces
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,6 +309,12 @@ func New(l log.Logger, conf *SDConfig) (*Discovery, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ownNamespace, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not determine the pod's namespace: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return &Discovery{
|
return &Discovery{
|
||||||
client: c,
|
client: c,
|
||||||
logger: l,
|
logger: l,
|
||||||
|
@ -306,6 +322,7 @@ func New(l log.Logger, conf *SDConfig) (*Discovery, error) {
|
||||||
namespaceDiscovery: &conf.NamespaceDiscovery,
|
namespaceDiscovery: &conf.NamespaceDiscovery,
|
||||||
discoverers: make([]discovery.Discoverer, 0),
|
discoverers: make([]discovery.Discoverer, 0),
|
||||||
selectors: mapSelector(conf.Selectors),
|
selectors: mapSelector(conf.Selectors),
|
||||||
|
ownNamespace: string(ownNamespace),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ func makeDiscoveryWithVersion(role Role, nsDiscovery NamespaceDiscovery, k8sVer
|
||||||
logger: log.NewNopLogger(),
|
logger: log.NewNopLogger(),
|
||||||
role: role,
|
role: role,
|
||||||
namespaceDiscovery: &nsDiscovery,
|
namespaceDiscovery: &nsDiscovery,
|
||||||
|
ownNamespace: "own-ns",
|
||||||
}, clientset
|
}, clientset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -389,3 +389,21 @@ func TestPodDiscoveryNamespaces(t *testing.T) {
|
||||||
expectedRes: expected,
|
expectedRes: expected,
|
||||||
}.Run(t)
|
}.Run(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPodDiscoveryOwnNamespace(t *testing.T) {
|
||||||
|
n, c := makeDiscovery(RolePod, NamespaceDiscovery{IncludeOwnNamespace: true})
|
||||||
|
|
||||||
|
expected := expectedPodTargetGroups("own-ns")
|
||||||
|
k8sDiscoveryTest{
|
||||||
|
discovery: n,
|
||||||
|
beforeRun: func() {
|
||||||
|
for _, ns := range []string{"own-ns", "non-own-ns"} {
|
||||||
|
pod := makePods()
|
||||||
|
pod.Namespace = ns
|
||||||
|
c.CoreV1().Pods(pod.Namespace).Create(context.Background(), pod, metav1.CreateOptions{})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
expectedMaxItems: 1,
|
||||||
|
expectedRes: expected,
|
||||||
|
}.Run(t)
|
||||||
|
}
|
||||||
|
|
|
@ -254,3 +254,87 @@ func TestServiceDiscoveryNamespaces(t *testing.T) {
|
||||||
},
|
},
|
||||||
}.Run(t)
|
}.Run(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServiceDiscoveryOwnNamespace(t *testing.T) {
|
||||||
|
n, c := makeDiscovery(RoleService, NamespaceDiscovery{IncludeOwnNamespace: true})
|
||||||
|
|
||||||
|
k8sDiscoveryTest{
|
||||||
|
discovery: n,
|
||||||
|
afterStart: func() {
|
||||||
|
for _, ns := range []string{"own-ns", "non-own-ns"} {
|
||||||
|
obj := makeService()
|
||||||
|
obj.Namespace = ns
|
||||||
|
c.CoreV1().Services(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
expectedMaxItems: 1,
|
||||||
|
expectedRes: map[string]*targetgroup.Group{
|
||||||
|
"svc/own-ns/testservice": {
|
||||||
|
Targets: []model.LabelSet{
|
||||||
|
{
|
||||||
|
"__meta_kubernetes_service_port_protocol": "TCP",
|
||||||
|
"__address__": "testservice.own-ns.svc:30900",
|
||||||
|
"__meta_kubernetes_service_type": "ClusterIP",
|
||||||
|
"__meta_kubernetes_service_cluster_ip": "10.0.0.1",
|
||||||
|
"__meta_kubernetes_service_port_name": "testport",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"__meta_kubernetes_service_name": "testservice",
|
||||||
|
"__meta_kubernetes_namespace": "own-ns",
|
||||||
|
},
|
||||||
|
Source: "svc/own-ns/testservice",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}.Run(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServiceDiscoveryAllNamespaces(t *testing.T) {
|
||||||
|
n, c := makeDiscovery(RoleService, NamespaceDiscovery{})
|
||||||
|
|
||||||
|
k8sDiscoveryTest{
|
||||||
|
discovery: n,
|
||||||
|
afterStart: func() {
|
||||||
|
for _, ns := range []string{"own-ns", "non-own-ns"} {
|
||||||
|
obj := makeService()
|
||||||
|
obj.Namespace = ns
|
||||||
|
c.CoreV1().Services(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
expectedMaxItems: 2,
|
||||||
|
expectedRes: map[string]*targetgroup.Group{
|
||||||
|
"svc/own-ns/testservice": {
|
||||||
|
Targets: []model.LabelSet{
|
||||||
|
{
|
||||||
|
"__meta_kubernetes_service_port_protocol": "TCP",
|
||||||
|
"__address__": "testservice.own-ns.svc:30900",
|
||||||
|
"__meta_kubernetes_service_type": "ClusterIP",
|
||||||
|
"__meta_kubernetes_service_cluster_ip": "10.0.0.1",
|
||||||
|
"__meta_kubernetes_service_port_name": "testport",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"__meta_kubernetes_service_name": "testservice",
|
||||||
|
"__meta_kubernetes_namespace": "own-ns",
|
||||||
|
},
|
||||||
|
Source: "svc/own-ns/testservice",
|
||||||
|
},
|
||||||
|
"svc/non-own-ns/testservice": {
|
||||||
|
Targets: []model.LabelSet{
|
||||||
|
{
|
||||||
|
"__meta_kubernetes_service_port_protocol": "TCP",
|
||||||
|
"__address__": "testservice.non-own-ns.svc:30900",
|
||||||
|
"__meta_kubernetes_service_type": "ClusterIP",
|
||||||
|
"__meta_kubernetes_service_cluster_ip": "10.0.0.1",
|
||||||
|
"__meta_kubernetes_service_port_name": "testport",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Labels: model.LabelSet{
|
||||||
|
"__meta_kubernetes_service_name": "testservice",
|
||||||
|
"__meta_kubernetes_namespace": "non-own-ns",
|
||||||
|
},
|
||||||
|
Source: "svc/non-own-ns/testservice",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}.Run(t)
|
||||||
|
}
|
||||||
|
|
|
@ -1607,15 +1607,15 @@ Available meta labels:
|
||||||
* `__meta_kubernetes_endpointslice_name`: The name of endpointslice object.
|
* `__meta_kubernetes_endpointslice_name`: The name of endpointslice object.
|
||||||
* For all targets discovered directly from the endpointslice list (those not additionally inferred
|
* For all targets discovered directly from the endpointslice list (those not additionally inferred
|
||||||
from underlying pods), the following labels are attached:
|
from underlying pods), the following labels are attached:
|
||||||
* `__meta_kubernetes_endpointslice_address_target_kind`: Kind of the referenced object.
|
* `__meta_kubernetes_endpointslice_address_target_kind`: Kind of the referenced object.
|
||||||
* `__meta_kubernetes_endpointslice_address_target_name`: Name of referenced object.
|
* `__meta_kubernetes_endpointslice_address_target_name`: Name of referenced object.
|
||||||
* `__meta_kubernetes_endpointslice_address_type`: The ip protocol family of the address of the target.
|
* `__meta_kubernetes_endpointslice_address_type`: The ip protocol family of the address of the target.
|
||||||
* `__meta_kubernetes_endpointslice_endpoint_conditions_ready`: Set to `true` or `false` for the referenced endpoint's ready state.
|
* `__meta_kubernetes_endpointslice_endpoint_conditions_ready`: Set to `true` or `false` for the referenced endpoint's ready state.
|
||||||
* `__meta_kubernetes_endpointslice_endpoint_topology_kubernetes_io_hostname`: Name of the node hosting the referenced endpoint.
|
* `__meta_kubernetes_endpointslice_endpoint_topology_kubernetes_io_hostname`: Name of the node hosting the referenced endpoint.
|
||||||
* `__meta_kubernetes_endpointslice_endpoint_topology_present_kubernetes_io_hostname`: Flag that shows if the referenced object has a kubernetes.io/hostname annotation.
|
* `__meta_kubernetes_endpointslice_endpoint_topology_present_kubernetes_io_hostname`: Flag that shows if the referenced object has a kubernetes.io/hostname annotation.
|
||||||
* `__meta_kubernetes_endpointslice_port`: Port of the referenced endpoint.
|
* `__meta_kubernetes_endpointslice_port`: Port of the referenced endpoint.
|
||||||
* `__meta_kubernetes_endpointslice_port_name`: Named port of the referenced endpoint.
|
* `__meta_kubernetes_endpointslice_port_name`: Named port of the referenced endpoint.
|
||||||
* `__meta_kubernetes_endpointslice_port_protocol`: Protocol of the referenced endpoint.
|
* `__meta_kubernetes_endpointslice_port_protocol`: Protocol of the referenced endpoint.
|
||||||
* If the endpoints belong to a service, all labels of the `role: service` discovery are attached.
|
* If the endpoints belong to a service, all labels of the `role: service` discovery are attached.
|
||||||
* For all targets backed by a pod, all labels of the `role: pod` discovery are attached.
|
* For all targets backed by a pod, all labels of the `role: pod` discovery are attached.
|
||||||
|
|
||||||
|
@ -1694,6 +1694,7 @@ tls_config:
|
||||||
|
|
||||||
# Optional namespace discovery. If omitted, all namespaces are used.
|
# Optional namespace discovery. If omitted, all namespaces are used.
|
||||||
namespaces:
|
namespaces:
|
||||||
|
own_namespace: <bool>
|
||||||
names:
|
names:
|
||||||
[ - <string> ]
|
[ - <string> ]
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ versions.
|
||||||
| title | string | string | [strings.Title](https://golang.org/pkg/strings/#Title), capitalises first character of each word.|
|
| title | string | string | [strings.Title](https://golang.org/pkg/strings/#Title), capitalises first character of each word.|
|
||||||
| toUpper | string | string | [strings.ToUpper](https://golang.org/pkg/strings/#ToUpper), converts all characters to upper case.|
|
| toUpper | string | string | [strings.ToUpper](https://golang.org/pkg/strings/#ToUpper), converts all characters to upper case.|
|
||||||
| toLower | string | string | [strings.ToLower](https://golang.org/pkg/strings/#ToLower), converts all characters to lower case.|
|
| toLower | string | string | [strings.ToLower](https://golang.org/pkg/strings/#ToLower), converts all characters to lower case.|
|
||||||
|
| stripPort | string | string | [net.SplitHostPort](https://pkg.go.dev/net#SplitHostPort), splits string into host and port, then returns only host.|
|
||||||
| match | pattern, text | boolean | [regexp.MatchString](https://golang.org/pkg/regexp/#MatchString) Tests for a unanchored regexp match. |
|
| match | pattern, text | boolean | [regexp.MatchString](https://golang.org/pkg/regexp/#MatchString) Tests for a unanchored regexp match. |
|
||||||
| reReplaceAll | pattern, replacement, text | string | [Regexp.ReplaceAllString](https://golang.org/pkg/regexp/#Regexp.ReplaceAllString) Regexp substitution, unanchored. |
|
| reReplaceAll | pattern, replacement, text | string | [Regexp.ReplaceAllString](https://golang.org/pkg/regexp/#Regexp.ReplaceAllString) Regexp substitution, unanchored. |
|
||||||
| graphLink | expr | string | Returns path to graph view in the [expression browser](https://prometheus.io/docs/visualization/browser/) for the expression. |
|
| graphLink | expr | string | Returns path to graph view in the [expression browser](https://prometheus.io/docs/visualization/browser/) for the expression. |
|
||||||
|
|
34
go.mod
34
go.mod
|
@ -1,23 +1,23 @@
|
||||||
module github.com/prometheus/prometheus
|
module github.com/prometheus/prometheus
|
||||||
|
|
||||||
go 1.14
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Azure/azure-sdk-for-go v59.4.0+incompatible
|
github.com/Azure/azure-sdk-for-go v60.3.0+incompatible
|
||||||
github.com/Azure/go-autorest/autorest v0.11.22
|
github.com/Azure/go-autorest/autorest v0.11.23
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.17
|
github.com/Azure/go-autorest/autorest/adal v0.9.18
|
||||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
||||||
github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a
|
github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a
|
||||||
github.com/aws/aws-sdk-go v1.42.20
|
github.com/aws/aws-sdk-go v1.42.25
|
||||||
github.com/cespare/xxhash/v2 v2.1.2
|
github.com/cespare/xxhash/v2 v2.1.2
|
||||||
github.com/containerd/containerd v1.5.7 // indirect
|
github.com/containerd/containerd v1.5.7 // indirect
|
||||||
github.com/dennwc/varint v1.0.0
|
github.com/dennwc/varint v1.0.0
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245
|
github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245
|
||||||
github.com/digitalocean/godo v1.73.0
|
github.com/digitalocean/godo v1.73.0
|
||||||
github.com/docker/docker v20.10.11+incompatible
|
github.com/docker/docker v20.10.12+incompatible
|
||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
github.com/edsrzf/mmap-go v1.0.0
|
github.com/edsrzf/mmap-go v1.1.0
|
||||||
github.com/envoyproxy/go-control-plane v0.10.1
|
github.com/envoyproxy/go-control-plane v0.10.1
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.6.2
|
github.com/envoyproxy/protoc-gen-validate v0.6.2
|
||||||
github.com/fsnotify/fsnotify v1.5.1
|
github.com/fsnotify/fsnotify v1.5.1
|
||||||
|
@ -28,15 +28,15 @@ require (
|
||||||
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/google/pprof v0.0.0-20211122183932-1daafda22083
|
github.com/google/pprof v0.0.0-20211122183932-1daafda22083
|
||||||
github.com/gophercloud/gophercloud v0.23.0
|
github.com/gophercloud/gophercloud v0.24.0
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||||
github.com/hashicorp/consul/api v1.11.0
|
github.com/hashicorp/consul/api v1.12.0
|
||||||
github.com/hetznercloud/hcloud-go v1.33.1
|
github.com/hetznercloud/hcloud-go v1.33.1
|
||||||
github.com/influxdata/influxdb v1.9.5
|
github.com/influxdata/influxdb v1.9.5
|
||||||
github.com/json-iterator/go v1.1.12
|
github.com/json-iterator/go v1.1.12
|
||||||
github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b
|
github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b
|
||||||
github.com/linode/linodego v1.2.1
|
github.com/linode/linodego v1.2.1
|
||||||
github.com/miekg/dns v1.1.43
|
github.com/miekg/dns v1.1.45
|
||||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f
|
||||||
|
@ -50,23 +50,23 @@ require (
|
||||||
github.com/prometheus/client_model v0.2.0
|
github.com/prometheus/client_model v0.2.0
|
||||||
github.com/prometheus/common v0.32.1
|
github.com/prometheus/common v0.32.1
|
||||||
github.com/prometheus/common/sigv4 v0.1.0
|
github.com/prometheus/common/sigv4 v0.1.0
|
||||||
github.com/prometheus/exporter-toolkit v0.7.0
|
github.com/prometheus/exporter-toolkit v0.7.1
|
||||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44
|
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/uber/jaeger-client-go v2.29.1+incompatible
|
github.com/uber/jaeger-client-go v2.30.0+incompatible
|
||||||
github.com/uber/jaeger-lib v2.4.1+incompatible
|
github.com/uber/jaeger-lib v2.4.1+incompatible
|
||||||
go.uber.org/atomic v1.9.0
|
go.uber.org/atomic v1.9.0
|
||||||
go.uber.org/goleak v1.1.12
|
go.uber.org/goleak v1.1.12
|
||||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9
|
golang.org/x/net v0.0.0-20211209124913-491a49abca63
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
|
||||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11
|
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11
|
||||||
golang.org/x/tools v0.1.8
|
golang.org/x/tools v0.1.8
|
||||||
google.golang.org/api v0.61.0
|
google.golang.org/api v0.63.0
|
||||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12
|
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa
|
||||||
google.golang.org/protobuf v1.27.1
|
google.golang.org/protobuf v1.27.1
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
|
@ -75,7 +75,7 @@ require (
|
||||||
k8s.io/apimachinery v0.22.4
|
k8s.io/apimachinery v0.22.4
|
||||||
k8s.io/client-go v0.22.4
|
k8s.io/client-go v0.22.4
|
||||||
k8s.io/klog v1.0.0
|
k8s.io/klog v1.0.0
|
||||||
k8s.io/klog/v2 v2.20.0
|
k8s.io/klog/v2 v2.30.0
|
||||||
)
|
)
|
||||||
|
|
||||||
replace (
|
replace (
|
||||||
|
|
85
go.sum
85
go.sum
|
@ -26,8 +26,9 @@ cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWc
|
||||||
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
|
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
|
||||||
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
|
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
|
||||||
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
|
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
|
||||||
cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
|
|
||||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||||
|
cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY=
|
||||||
|
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
|
||||||
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=
|
||||||
|
@ -51,8 +52,8 @@ collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
|
||||||
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 v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||||
github.com/Azure/azure-sdk-for-go v41.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
github.com/Azure/azure-sdk-for-go v41.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||||
github.com/Azure/azure-sdk-for-go v59.4.0+incompatible h1:gDA8odnngdNd3KYHL2NoK1j9vpWBgEnFSjKKLpkC8Aw=
|
github.com/Azure/azure-sdk-for-go v60.3.0+incompatible h1:u6EXgnASaUOh38GXCwEpRs+u2bbfJpJpXeB42kU2cjg=
|
||||||
github.com/Azure/azure-sdk-for-go v59.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
github.com/Azure/azure-sdk-for-go v60.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||||
|
@ -64,8 +65,8 @@ github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUd
|
||||||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||||
github.com/Azure/go-autorest/autorest v0.11.9/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
github.com/Azure/go-autorest/autorest v0.11.9/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||||
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
||||||
github.com/Azure/go-autorest/autorest v0.11.22 h1:bXiQwDjrRmBQOE67bwlvUKAC1EU1yZTPQ38c+bstZws=
|
github.com/Azure/go-autorest/autorest v0.11.23 h1:bRQWsW25/YkoxnIqXMPF94JW33qWDcrPMZ3bINaAruU=
|
||||||
github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs=
|
github.com/Azure/go-autorest/autorest v0.11.23/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||||
|
@ -73,8 +74,8 @@ github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQW
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.17 h1:esOPl2dhcz9P3jqBSJ8tPGEj2EqzPPT6zfyuloiogKY=
|
github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.17/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.3/go.mod h1:4bJZhUhcq8LB20TruwHbAQsmUs2Xh+QR7utuJpLXX3A=
|
github.com/Azure/go-autorest/autorest/azure/auth v0.5.3/go.mod h1:4bJZhUhcq8LB20TruwHbAQsmUs2Xh+QR7utuJpLXX3A=
|
||||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM=
|
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM=
|
||||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||||
|
@ -187,8 +188,8 @@ github.com/aws/aws-sdk-go v1.30.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZve
|
||||||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||||
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.40.11/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
github.com/aws/aws-sdk-go v1.40.11/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||||
github.com/aws/aws-sdk-go v1.42.20 h1:nQkkmTWK5N2Ao1iVzoOx1HTIxwbSWErxyZ1eiwLJWc4=
|
github.com/aws/aws-sdk-go v1.42.25 h1:BbdvHAi+t9LRiaYUyd53noq9jcaAcfzOhSVbKfr6Avs=
|
||||||
github.com/aws/aws-sdk-go v1.42.20/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
github.com/aws/aws-sdk-go v1.42.25/go.mod h1:gyRszuZ/icHmHAVE4gc/r+cfCmhA1AD+vqfWbgI+eHs=
|
||||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||||
github.com/benbjohnson/immutable v0.2.1/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI=
|
github.com/benbjohnson/immutable v0.2.1/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI=
|
||||||
github.com/benbjohnson/tmpl v1.0.0/go.mod h1:igT620JFIi44B6awvU9IsDhR77IXWtFigTLil/RPdps=
|
github.com/benbjohnson/tmpl v1.0.0/go.mod h1:igT620JFIi44B6awvU9IsDhR77IXWtFigTLil/RPdps=
|
||||||
|
@ -348,7 +349,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
|
||||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||||
|
@ -381,8 +381,8 @@ github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TT
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v20.10.11+incompatible h1:OqzI/g/W54LczvhnccGqniFoQghHx3pklbLuhfXpqGo=
|
github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U=
|
||||||
github.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||||
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||||
|
@ -401,8 +401,9 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
|
||||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
||||||
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
|
||||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
|
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
|
||||||
|
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
|
||||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||||
|
@ -739,8 +740,8 @@ github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9
|
||||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||||
github.com/gophercloud/gophercloud v0.10.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
|
github.com/gophercloud/gophercloud v0.10.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
|
||||||
github.com/gophercloud/gophercloud v0.23.0 h1:I3P10oKlGu3DHP9PrEWMr1ya+/+3Rc9uRHNkRZ9wO7g=
|
github.com/gophercloud/gophercloud v0.24.0 h1:jDsIMGJ1KZpAjYfQgGI2coNQj5Q83oPzuiGJRFWgMzw=
|
||||||
github.com/gophercloud/gophercloud v0.23.0/go.mod h1:MRw6uyLj8uCGbIvBlqL7QW67t0QtNZnzydUzewo1Ioc=
|
github.com/gophercloud/gophercloud v0.24.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||||
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||||
|
@ -763,8 +764,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||||
github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU=
|
github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU=
|
||||||
github.com/hashicorp/consul/api v1.11.0 h1:Hw/G8TtRvOElqxVIhBzXciiSTbapq8hZ2XKZsXk5ZCE=
|
github.com/hashicorp/consul/api v1.12.0 h1:k3y1FYv6nuKyNTqj6w9gXOx5r5CfLj/k/euUeBXj1OY=
|
||||||
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
|
||||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||||
github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
|
github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
|
||||||
github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU=
|
github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU=
|
||||||
|
@ -808,16 +809,17 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
|
||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||||
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
|
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
|
||||||
|
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
|
||||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||||
github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||||
github.com/hashicorp/memberlist v0.2.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
github.com/hashicorp/memberlist v0.2.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||||
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
|
||||||
github.com/hashicorp/memberlist v0.2.4 h1:OOhYzSvFnkFQXm1ysE8RjXTHsqSRDyP4emusC9K7DYg=
|
|
||||||
github.com/hashicorp/memberlist v0.2.4/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
github.com/hashicorp/memberlist v0.2.4/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||||
|
github.com/hashicorp/memberlist v0.3.0 h1:8+567mCcFDnS5ADl7lrpxPMWiFCElyUEeW0gtj34fMA=
|
||||||
|
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||||
github.com/hashicorp/serf v0.9.0/go.mod h1:YL0HO+FifKOW2u1ke99DGVu1zhcpZzNwrLIqBC7vbYU=
|
github.com/hashicorp/serf v0.9.0/go.mod h1:YL0HO+FifKOW2u1ke99DGVu1zhcpZzNwrLIqBC7vbYU=
|
||||||
github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM=
|
github.com/hashicorp/serf v0.9.6 h1:uuEX1kLR6aoda1TBttmJQKDLZE1Ob7KN0NPdE7EtCDc=
|
||||||
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||||
github.com/hetznercloud/hcloud-go v1.33.1 h1:W1HdO2bRLTKU4WsyqAasDSpt54fYO4WNckWYfH5AuCQ=
|
github.com/hetznercloud/hcloud-go v1.33.1 h1:W1HdO2bRLTKU4WsyqAasDSpt54fYO4WNckWYfH5AuCQ=
|
||||||
github.com/hetznercloud/hcloud-go v1.33.1/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME=
|
github.com/hetznercloud/hcloud-go v1.33.1/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
@ -970,8 +972,9 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
|
||||||
github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||||
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||||
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
|
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
github.com/miekg/dns v1.1.45 h1:g5fRIhm9nx7g8osrAvgb16QJfmyMsyOCb+J7LSv+Qzk=
|
||||||
|
github.com/miekg/dns v1.1.45/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||||
github.com/mileusna/useragent v0.0.0-20190129205925-3e331f0949a5/go.mod h1:JWhYAp2EXqUtsxTKdeGlY8Wp44M7VxThC9FEoNGi2IE=
|
github.com/mileusna/useragent v0.0.0-20190129205925-3e331f0949a5/go.mod h1:JWhYAp2EXqUtsxTKdeGlY8Wp44M7VxThC9FEoNGi2IE=
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||||
|
@ -1168,8 +1171,8 @@ github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+
|
||||||
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/exporter-toolkit v0.6.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g=
|
github.com/prometheus/exporter-toolkit v0.6.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g=
|
||||||
github.com/prometheus/exporter-toolkit v0.7.0 h1:XtYeVeeC5daG4txbc9+mieKq+/AK4gtIBLl9Mulrjnk=
|
github.com/prometheus/exporter-toolkit v0.7.1 h1:c6RXaK8xBVercEeUQ4tRNL8UGWzDHfvj9dseo1FcK1Y=
|
||||||
github.com/prometheus/exporter-toolkit v0.7.0/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g=
|
github.com/prometheus/exporter-toolkit v0.7.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g=
|
||||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/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.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
@ -1288,8 +1291,8 @@ github.com/uber-go/tally v3.3.15+incompatible/go.mod h1:YDTIBxdXyOU/sCWilKB4bgyu
|
||||||
github.com/uber/athenadriver v1.1.4/go.mod h1:tQjho4NzXw55LGfSZEcETuYydpY1vtmixUabHkC1K/E=
|
github.com/uber/athenadriver v1.1.4/go.mod h1:tQjho4NzXw55LGfSZEcETuYydpY1vtmixUabHkC1K/E=
|
||||||
github.com/uber/jaeger-client-go v2.23.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
github.com/uber/jaeger-client-go v2.23.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||||
github.com/uber/jaeger-client-go v2.28.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
github.com/uber/jaeger-client-go v2.28.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||||
github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4=
|
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
|
||||||
github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||||
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||||
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
|
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
|
||||||
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||||
|
@ -1417,8 +1420,9 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
|
||||||
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.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8=
|
||||||
|
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/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-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
@ -1431,7 +1435,6 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||||
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 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
|
|
||||||
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/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||||
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=
|
||||||
|
@ -1522,6 +1525,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||||
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-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
|
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/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=
|
||||||
|
@ -1529,8 +1533,9 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
|
||||||
|
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
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=
|
||||||
|
@ -1672,8 +1677,10 @@ golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc=
|
|
||||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||||
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
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-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||||
|
@ -1777,6 +1784,7 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
|
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
|
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
|
||||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||||
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=
|
||||||
|
@ -1787,10 +1795,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
|
||||||
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||||
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||||
gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
|
gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
|
||||||
gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM=
|
|
||||||
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
|
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
|
||||||
gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc=
|
|
||||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||||
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
|
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
|
||||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
|
@ -1822,8 +1828,9 @@ google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6
|
||||||
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||||
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||||
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
|
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
|
||||||
google.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8=
|
|
||||||
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
|
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
|
||||||
|
google.golang.org/api v0.63.0 h1:n2bqqK895ygnBpdPDYetfy23K7fJ22wsrZKCyfuRkkA=
|
||||||
|
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
|
||||||
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.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.2.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.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
@ -1898,8 +1905,9 @@ google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEc
|
||||||
google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12 h1:DN5b3HU13J4sMd/QjDx34U6afpaexKTDdop+26pdjdk=
|
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0=
|
||||||
|
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
@ -1932,8 +1940,9 @@ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
|
||||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||||
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||||
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||||
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
|
|
||||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||||
|
google.golang.org/grpc v1.40.1 h1:pnP7OclFFFgFi4VHQDQDaoXUVauOFyktqTsqqgzFKbc=
|
||||||
|
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||||
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=
|
||||||
|
|
|
@ -305,7 +305,7 @@ func newScrapePool(cfg *config.ScrapeConfig, app storage.Appendable, jitterSeed
|
||||||
return mutateSampleLabels(l, opts.target, opts.honorLabels, opts.mrc)
|
return mutateSampleLabels(l, opts.target, opts.honorLabels, opts.mrc)
|
||||||
},
|
},
|
||||||
func(l labels.Labels) labels.Labels { return mutateReportSampleLabels(l, opts.target) },
|
func(l labels.Labels) labels.Labels { return mutateReportSampleLabels(l, opts.target) },
|
||||||
func(ctx context.Context) storage.Appender { return appender(app.Appender(ctx), opts.sampleLimit) },
|
func(ctx context.Context) storage.Appender { return app.Appender(ctx) },
|
||||||
cache,
|
cache,
|
||||||
jitterSeed,
|
jitterSeed,
|
||||||
opts.honorTimestamps,
|
opts.honorTimestamps,
|
||||||
|
@ -1426,6 +1426,9 @@ func (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string,
|
||||||
e exemplar.Exemplar // escapes to heap so hoisted out of loop
|
e exemplar.Exemplar // escapes to heap so hoisted out of loop
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Take an appender with limits.
|
||||||
|
app = appender(app, sl.sampleLimit)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
|
@ -463,7 +463,7 @@ func TestScrapePoolAppender(t *testing.T) {
|
||||||
appl, ok := loop.(*scrapeLoop)
|
appl, ok := loop.(*scrapeLoop)
|
||||||
require.True(t, ok, "Expected scrapeLoop but got %T", loop)
|
require.True(t, ok, "Expected scrapeLoop but got %T", loop)
|
||||||
|
|
||||||
wrapped := appl.appender(context.Background())
|
wrapped := appender(appl.appender(context.Background()), 0)
|
||||||
|
|
||||||
tl, ok := wrapped.(*timeLimitAppender)
|
tl, ok := wrapped.(*timeLimitAppender)
|
||||||
require.True(t, ok, "Expected timeLimitAppender but got %T", wrapped)
|
require.True(t, ok, "Expected timeLimitAppender but got %T", wrapped)
|
||||||
|
@ -471,20 +471,21 @@ func TestScrapePoolAppender(t *testing.T) {
|
||||||
_, ok = tl.Appender.(nopAppender)
|
_, ok = tl.Appender.(nopAppender)
|
||||||
require.True(t, ok, "Expected base appender but got %T", tl.Appender)
|
require.True(t, ok, "Expected base appender but got %T", tl.Appender)
|
||||||
|
|
||||||
|
sampleLimit := 100
|
||||||
loop = sp.newLoop(scrapeLoopOptions{
|
loop = sp.newLoop(scrapeLoopOptions{
|
||||||
target: &Target{},
|
target: &Target{},
|
||||||
sampleLimit: 100,
|
sampleLimit: sampleLimit,
|
||||||
})
|
})
|
||||||
appl, ok = loop.(*scrapeLoop)
|
appl, ok = loop.(*scrapeLoop)
|
||||||
require.True(t, ok, "Expected scrapeLoop but got %T", loop)
|
require.True(t, ok, "Expected scrapeLoop but got %T", loop)
|
||||||
|
|
||||||
wrapped = appl.appender(context.Background())
|
wrapped = appender(appl.appender(context.Background()), sampleLimit)
|
||||||
|
|
||||||
sl, ok := wrapped.(*limitAppender)
|
sl, ok := wrapped.(*limitAppender)
|
||||||
require.True(t, ok, "Expected limitAppender but got %T", wrapped)
|
require.True(t, ok, "Expected limitAppender but got %T", wrapped)
|
||||||
|
|
||||||
tl, ok = sl.Appender.(*timeLimitAppender)
|
tl, ok = sl.Appender.(*timeLimitAppender)
|
||||||
require.True(t, ok, "Expected limitAppender but got %T", sl.Appender)
|
require.True(t, ok, "Expected timeLimitAppender but got %T", sl.Appender)
|
||||||
|
|
||||||
_, ok = tl.Appender.(nopAppender)
|
_, ok = tl.Appender.(nopAppender)
|
||||||
require.True(t, ok, "Expected base appender but got %T", tl.Appender)
|
require.True(t, ok, "Expected base appender but got %T", tl.Appender)
|
||||||
|
@ -2772,6 +2773,72 @@ func TestScrapeReportSingleAppender(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestScrapeReportLimit(t *testing.T) {
|
||||||
|
s := teststorage.New(t)
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
cfg := &config.ScrapeConfig{
|
||||||
|
JobName: "test",
|
||||||
|
SampleLimit: 5,
|
||||||
|
Scheme: "http",
|
||||||
|
ScrapeInterval: model.Duration(100 * time.Millisecond),
|
||||||
|
ScrapeTimeout: model.Duration(100 * time.Millisecond),
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
scrapes int
|
||||||
|
scrapedTwice = make(chan bool)
|
||||||
|
)
|
||||||
|
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fmt.Fprint(w, "metric_a 44\nmetric_b 44\nmetric_c 44\nmetric_d 44\n")
|
||||||
|
scrapes++
|
||||||
|
if scrapes == 2 {
|
||||||
|
close(scrapedTwice)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
sp, err := newScrapePool(cfg, s, 0, nil, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer sp.stop()
|
||||||
|
|
||||||
|
testURL, err := url.Parse(ts.URL)
|
||||||
|
require.NoError(t, err)
|
||||||
|
sp.Sync([]*targetgroup.Group{
|
||||||
|
{
|
||||||
|
Targets: []model.LabelSet{{model.AddressLabel: model.LabelValue(testURL.Host)}},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
t.Fatalf("target was not scraped twice")
|
||||||
|
case <-scrapedTwice:
|
||||||
|
// If the target has been scraped twice, report samples from the first
|
||||||
|
// scrape have been inserted in the database.
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
q, err := s.Querier(ctx, time.Time{}.UnixNano(), time.Now().UnixNano())
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer q.Close()
|
||||||
|
series := q.Select(false, nil, labels.MustNewMatcher(labels.MatchRegexp, "__name__", "up"))
|
||||||
|
|
||||||
|
var found bool
|
||||||
|
for series.Next() {
|
||||||
|
i := series.At().Iterator()
|
||||||
|
for i.Next() {
|
||||||
|
_, v := i.At()
|
||||||
|
require.Equal(t, 1.0, v)
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require.True(t, found)
|
||||||
|
}
|
||||||
|
|
||||||
func TestScrapeLoopLabelLimit(t *testing.T) {
|
func TestScrapeLoopLabelLimit(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
title string
|
title string
|
||||||
|
|
|
@ -418,28 +418,22 @@ func PopulateLabels(lset labels.Labels, cfg *config.ScrapeConfig) (res, orig lab
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var interval string
|
interval := lset.Get(model.ScrapeIntervalLabel)
|
||||||
var intervalDuration model.Duration
|
intervalDuration, err := model.ParseDuration(interval)
|
||||||
if interval = lset.Get(model.ScrapeIntervalLabel); interval != cfg.ScrapeInterval.String() {
|
if err != nil {
|
||||||
intervalDuration, err = model.ParseDuration(interval)
|
return nil, nil, errors.Errorf("error parsing scrape interval: %v", err)
|
||||||
if err != nil {
|
}
|
||||||
return nil, nil, errors.Errorf("error parsing scrape interval: %v", err)
|
if time.Duration(intervalDuration) == 0 {
|
||||||
}
|
return nil, nil, errors.New("scrape interval cannot be 0")
|
||||||
if time.Duration(intervalDuration) == 0 {
|
|
||||||
return nil, nil, errors.New("scrape interval cannot be 0")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var timeout string
|
timeout := lset.Get(model.ScrapeTimeoutLabel)
|
||||||
var timeoutDuration model.Duration
|
timeoutDuration, err := model.ParseDuration(timeout)
|
||||||
if timeout = lset.Get(model.ScrapeTimeoutLabel); timeout != cfg.ScrapeTimeout.String() {
|
if err != nil {
|
||||||
timeoutDuration, err = model.ParseDuration(timeout)
|
return nil, nil, errors.Errorf("error parsing scrape timeout: %v", err)
|
||||||
if err != nil {
|
}
|
||||||
return nil, nil, errors.Errorf("error parsing scrape timeout: %v", err)
|
if time.Duration(timeoutDuration) == 0 {
|
||||||
}
|
return nil, nil, errors.New("scrape timeout cannot be 0")
|
||||||
if time.Duration(timeoutDuration) == 0 {
|
|
||||||
return nil, nil, errors.New("scrape timeout cannot be 0")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if timeoutDuration > intervalDuration {
|
if timeoutDuration > intervalDuration {
|
||||||
|
|
|
@ -371,7 +371,11 @@ func TestNewClientWithBadTLSConfig(t *testing.T) {
|
||||||
func TestTargetsFromGroup(t *testing.T) {
|
func TestTargetsFromGroup(t *testing.T) {
|
||||||
expectedError := "instance 0 in group : no address"
|
expectedError := "instance 0 in group : no address"
|
||||||
|
|
||||||
targets, failures := TargetsFromGroup(&targetgroup.Group{Targets: []model.LabelSet{{}, {model.AddressLabel: "localhost:9090"}}}, &config.ScrapeConfig{})
|
cfg := config.ScrapeConfig{
|
||||||
|
ScrapeTimeout: model.Duration(10 * time.Second),
|
||||||
|
ScrapeInterval: model.Duration(1 * time.Minute),
|
||||||
|
}
|
||||||
|
targets, failures := TargetsFromGroup(&targetgroup.Group{Targets: []model.LabelSet{{}, {model.AddressLabel: "localhost:9090"}}}, &cfg)
|
||||||
if len(targets) != 1 {
|
if len(targets) != 1 {
|
||||||
t.Fatalf("Expected 1 target, got %v", len(targets))
|
t.Fatalf("Expected 1 target, got %v", len(targets))
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,6 +360,9 @@ func (c *concreteSeriesIterator) Seek(t int64) bool {
|
||||||
if c.cur == -1 {
|
if c.cur == -1 {
|
||||||
c.cur = 0
|
c.cur = 0
|
||||||
}
|
}
|
||||||
|
if c.cur >= len(c.series.samples) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// No-op check.
|
// No-op check.
|
||||||
if s := c.series.samples[c.cur]; s.Timestamp >= t {
|
if s := c.series.samples[c.cur]; s.Timestamp >= t {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -233,6 +233,11 @@ func TestConcreteSeriesIterator(t *testing.T) {
|
||||||
ts, v = it.At()
|
ts, v = it.At()
|
||||||
require.Equal(t, int64(3), ts)
|
require.Equal(t, int64(3), ts)
|
||||||
require.Equal(t, 3., v)
|
require.Equal(t, 3., v)
|
||||||
|
|
||||||
|
// Seek beyond the end.
|
||||||
|
require.False(t, it.Seek(5))
|
||||||
|
// And we don't go back. (This exposes issue #10027.)
|
||||||
|
require.False(t, it.Seek(2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromQueryResultWithDuplicates(t *testing.T) {
|
func TestFromQueryResultWithDuplicates(t *testing.T) {
|
||||||
|
|
|
@ -507,7 +507,6 @@ func (t *QueueManager) sendMetadataWithBackoff(ctx context.Context, metadata []p
|
||||||
// Append queues a sample to be sent to the remote storage. Blocks until all samples are
|
// Append queues a sample to be sent to the remote storage. Blocks until all samples are
|
||||||
// enqueued on their shards or a shutdown signal is received.
|
// enqueued on their shards or a shutdown signal is received.
|
||||||
func (t *QueueManager) Append(samples []record.RefSample) bool {
|
func (t *QueueManager) Append(samples []record.RefSample) bool {
|
||||||
var appendSample prompb.Sample
|
|
||||||
outer:
|
outer:
|
||||||
for _, s := range samples {
|
for _, s := range samples {
|
||||||
t.seriesMtx.Lock()
|
t.seriesMtx.Lock()
|
||||||
|
@ -530,9 +529,12 @@ outer:
|
||||||
return false
|
return false
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
appendSample.Value = s.V
|
if t.shards.enqueue(s.Ref, sampleOrExemplar{
|
||||||
appendSample.Timestamp = s.T
|
seriesLabels: lbls,
|
||||||
if t.shards.enqueue(s.Ref, writeSample{lbls, appendSample}) {
|
timestamp: s.T,
|
||||||
|
value: s.V,
|
||||||
|
isSample: true,
|
||||||
|
}) {
|
||||||
continue outer
|
continue outer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,7 +554,6 @@ func (t *QueueManager) AppendExemplars(exemplars []record.RefExemplar) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
var appendExemplar prompb.Exemplar
|
|
||||||
outer:
|
outer:
|
||||||
for _, e := range exemplars {
|
for _, e := range exemplars {
|
||||||
t.seriesMtx.Lock()
|
t.seriesMtx.Lock()
|
||||||
|
@ -576,10 +577,12 @@ outer:
|
||||||
return false
|
return false
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
appendExemplar.Labels = labelsToLabelsProto(e.Labels, nil)
|
if t.shards.enqueue(e.Ref, sampleOrExemplar{
|
||||||
appendExemplar.Timestamp = e.T
|
seriesLabels: lbls,
|
||||||
appendExemplar.Value = e.V
|
timestamp: e.T,
|
||||||
if t.shards.enqueue(e.Ref, writeExemplar{lbls, appendExemplar}) {
|
value: e.V,
|
||||||
|
exemplarLabels: e.Labels,
|
||||||
|
}) {
|
||||||
continue outer
|
continue outer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,16 +904,6 @@ func (t *QueueManager) newShards() *shards {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
type writeSample struct {
|
|
||||||
seriesLabels labels.Labels
|
|
||||||
sample prompb.Sample
|
|
||||||
}
|
|
||||||
|
|
||||||
type writeExemplar struct {
|
|
||||||
seriesLabels labels.Labels
|
|
||||||
exemplar prompb.Exemplar
|
|
||||||
}
|
|
||||||
|
|
||||||
type shards struct {
|
type shards struct {
|
||||||
mtx sync.RWMutex // With the WAL, this is never actually contended.
|
mtx sync.RWMutex // With the WAL, this is never actually contended.
|
||||||
|
|
||||||
|
@ -999,7 +992,7 @@ func (s *shards) stop() {
|
||||||
|
|
||||||
// enqueue data (sample or exemplar). If we are currently in the process of shutting down or resharding,
|
// enqueue data (sample or exemplar). If we are currently in the process of shutting down or resharding,
|
||||||
// will return false; in this case, you should back off and retry.
|
// will return false; in this case, you should back off and retry.
|
||||||
func (s *shards) enqueue(ref chunks.HeadSeriesRef, data interface{}) bool {
|
func (s *shards) enqueue(ref chunks.HeadSeriesRef, data sampleOrExemplar) bool {
|
||||||
s.mtx.RLock()
|
s.mtx.RLock()
|
||||||
defer s.mtx.RUnlock()
|
defer s.mtx.RUnlock()
|
||||||
|
|
||||||
|
@ -1018,43 +1011,48 @@ func (s *shards) enqueue(ref chunks.HeadSeriesRef, data interface{}) bool {
|
||||||
if !appended {
|
if !appended {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
switch data.(type) {
|
if data.isSample {
|
||||||
case writeSample:
|
|
||||||
s.qm.metrics.pendingSamples.Inc()
|
s.qm.metrics.pendingSamples.Inc()
|
||||||
s.enqueuedSamples.Inc()
|
s.enqueuedSamples.Inc()
|
||||||
case writeExemplar:
|
} else {
|
||||||
s.qm.metrics.pendingExemplars.Inc()
|
s.qm.metrics.pendingExemplars.Inc()
|
||||||
s.enqueuedExemplars.Inc()
|
s.enqueuedExemplars.Inc()
|
||||||
default:
|
|
||||||
level.Warn(s.qm.logger).Log("msg", "Invalid object type in shards enqueue")
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type queue struct {
|
type queue struct {
|
||||||
batch []interface{}
|
batch []sampleOrExemplar
|
||||||
batchQueue chan []interface{}
|
batchQueue chan []sampleOrExemplar
|
||||||
|
|
||||||
// Since we know there are a limited number of batches out, using a stack
|
// Since we know there are a limited number of batches out, using a stack
|
||||||
// is easy and safe so a sync.Pool is not necessary.
|
// is easy and safe so a sync.Pool is not necessary.
|
||||||
batchPool [][]interface{}
|
batchPool [][]sampleOrExemplar
|
||||||
// This mutex covers adding and removing batches from the batchPool.
|
// This mutex covers adding and removing batches from the batchPool.
|
||||||
poolMux sync.Mutex
|
poolMux sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sampleOrExemplar struct {
|
||||||
|
seriesLabels labels.Labels
|
||||||
|
value float64
|
||||||
|
timestamp int64
|
||||||
|
exemplarLabels labels.Labels
|
||||||
|
isSample bool
|
||||||
|
}
|
||||||
|
|
||||||
func newQueue(batchSize, capacity int) *queue {
|
func newQueue(batchSize, capacity int) *queue {
|
||||||
batches := capacity / batchSize
|
batches := capacity / batchSize
|
||||||
return &queue{
|
return &queue{
|
||||||
batch: make([]interface{}, 0, batchSize),
|
batch: make([]sampleOrExemplar, 0, batchSize),
|
||||||
batchQueue: make(chan []interface{}, batches),
|
batchQueue: make(chan []sampleOrExemplar, batches),
|
||||||
// batchPool should have capacity for everything in the channel + 1 for
|
// batchPool should have capacity for everything in the channel + 1 for
|
||||||
// the batch being processed.
|
// the batch being processed.
|
||||||
batchPool: make([][]interface{}, 0, batches+1),
|
batchPool: make([][]sampleOrExemplar, 0, batches+1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queue) Append(datum interface{}, stop <-chan struct{}) bool {
|
func (q *queue) Append(datum sampleOrExemplar, stop <-chan struct{}) bool {
|
||||||
q.batch = append(q.batch, datum)
|
q.batch = append(q.batch, datum)
|
||||||
if len(q.batch) == cap(q.batch) {
|
if len(q.batch) == cap(q.batch) {
|
||||||
select {
|
select {
|
||||||
|
@ -1070,20 +1068,20 @@ func (q *queue) Append(datum interface{}, stop <-chan struct{}) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queue) Chan() <-chan []interface{} {
|
func (q *queue) Chan() <-chan []sampleOrExemplar {
|
||||||
return q.batchQueue
|
return q.batchQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Batch returns the current batch and allocates a new batch. Must not be
|
// Batch returns the current batch and allocates a new batch. Must not be
|
||||||
// called concurrently with Append.
|
// called concurrently with Append.
|
||||||
func (q *queue) Batch() []interface{} {
|
func (q *queue) Batch() []sampleOrExemplar {
|
||||||
batch := q.batch
|
batch := q.batch
|
||||||
q.batch = q.newBatch(cap(batch))
|
q.batch = q.newBatch(cap(batch))
|
||||||
return batch
|
return batch
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReturnForReuse adds the batch buffer back to the internal pool.
|
// ReturnForReuse adds the batch buffer back to the internal pool.
|
||||||
func (q *queue) ReturnForReuse(batch []interface{}) {
|
func (q *queue) ReturnForReuse(batch []sampleOrExemplar) {
|
||||||
q.poolMux.Lock()
|
q.poolMux.Lock()
|
||||||
defer q.poolMux.Unlock()
|
defer q.poolMux.Unlock()
|
||||||
if len(q.batchPool) < cap(q.batchPool) {
|
if len(q.batchPool) < cap(q.batchPool) {
|
||||||
|
@ -1106,7 +1104,7 @@ func (q *queue) FlushAndShutdown(done <-chan struct{}) {
|
||||||
close(q.batchQueue)
|
close(q.batchQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queue) newBatch(capacity int) []interface{} {
|
func (q *queue) newBatch(capacity int) []sampleOrExemplar {
|
||||||
q.poolMux.Lock()
|
q.poolMux.Lock()
|
||||||
defer q.poolMux.Unlock()
|
defer q.poolMux.Unlock()
|
||||||
batches := len(q.batchPool)
|
batches := len(q.batchPool)
|
||||||
|
@ -1115,7 +1113,7 @@ func (q *queue) newBatch(capacity int) []interface{} {
|
||||||
q.batchPool = q.batchPool[:batches-1]
|
q.batchPool = q.batchPool[:batches-1]
|
||||||
return batch
|
return batch
|
||||||
}
|
}
|
||||||
return make([]interface{}, 0, capacity)
|
return make([]sampleOrExemplar, 0, capacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *shards) runShard(ctx context.Context, shardID int, queue *queue) {
|
func (s *shards) runShard(ctx context.Context, shardID int, queue *queue) {
|
||||||
|
@ -1192,7 +1190,7 @@ func (s *shards) runShard(ctx context.Context, shardID int, queue *queue) {
|
||||||
// traffic instances.
|
// traffic instances.
|
||||||
s.mtx.Lock()
|
s.mtx.Lock()
|
||||||
// First, we need to see if we can happen to get a batch from the queue if it filled while acquiring the lock.
|
// First, we need to see if we can happen to get a batch from the queue if it filled while acquiring the lock.
|
||||||
var batch []interface{}
|
var batch []sampleOrExemplar
|
||||||
select {
|
select {
|
||||||
case batch = <-batchQueue:
|
case batch = <-batchQueue:
|
||||||
default:
|
default:
|
||||||
|
@ -1211,9 +1209,9 @@ func (s *shards) runShard(ctx context.Context, shardID int, queue *queue) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *shards) populateTimeSeries(batch []interface{}, pendingData []prompb.TimeSeries) (int, int) {
|
func (s *shards) populateTimeSeries(batch []sampleOrExemplar, pendingData []prompb.TimeSeries) (int, int) {
|
||||||
var nPendingSamples, nPendingExemplars int
|
var nPendingSamples, nPendingExemplars int
|
||||||
for nPending, sample := range batch {
|
for nPending, d := range batch {
|
||||||
pendingData[nPending].Samples = pendingData[nPending].Samples[:0]
|
pendingData[nPending].Samples = pendingData[nPending].Samples[:0]
|
||||||
if s.qm.sendExemplars {
|
if s.qm.sendExemplars {
|
||||||
pendingData[nPending].Exemplars = pendingData[nPending].Exemplars[:0]
|
pendingData[nPending].Exemplars = pendingData[nPending].Exemplars[:0]
|
||||||
|
@ -1221,14 +1219,20 @@ func (s *shards) populateTimeSeries(batch []interface{}, pendingData []prompb.Ti
|
||||||
// Number of pending samples is limited by the fact that sendSamples (via sendSamplesWithBackoff)
|
// Number of pending samples is limited by the fact that sendSamples (via sendSamplesWithBackoff)
|
||||||
// retries endlessly, so once we reach max samples, if we can never send to the endpoint we'll
|
// retries endlessly, so once we reach max samples, if we can never send to the endpoint we'll
|
||||||
// stop reading from the queue. This makes it safe to reference pendingSamples by index.
|
// stop reading from the queue. This makes it safe to reference pendingSamples by index.
|
||||||
switch d := sample.(type) {
|
if d.isSample {
|
||||||
case writeSample:
|
|
||||||
pendingData[nPending].Labels = labelsToLabelsProto(d.seriesLabels, pendingData[nPending].Labels)
|
pendingData[nPending].Labels = labelsToLabelsProto(d.seriesLabels, pendingData[nPending].Labels)
|
||||||
pendingData[nPending].Samples = append(pendingData[nPending].Samples, d.sample)
|
pendingData[nPending].Samples = append(pendingData[nPending].Samples, prompb.Sample{
|
||||||
|
Value: d.value,
|
||||||
|
Timestamp: d.timestamp,
|
||||||
|
})
|
||||||
nPendingSamples++
|
nPendingSamples++
|
||||||
case writeExemplar:
|
} else {
|
||||||
pendingData[nPending].Labels = labelsToLabelsProto(d.seriesLabels, pendingData[nPending].Labels)
|
pendingData[nPending].Labels = labelsToLabelsProto(d.seriesLabels, pendingData[nPending].Labels)
|
||||||
pendingData[nPending].Exemplars = append(pendingData[nPending].Exemplars, d.exemplar)
|
pendingData[nPending].Exemplars = append(pendingData[nPending].Exemplars, prompb.Exemplar{
|
||||||
|
Labels: labelsToLabelsProto(d.exemplarLabels, nil),
|
||||||
|
Value: d.value,
|
||||||
|
Timestamp: d.timestamp,
|
||||||
|
})
|
||||||
nPendingExemplars++
|
nPendingExemplars++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,22 +578,6 @@ func (c *TestWriteClient) waitForExpectedData(tb testing.TB) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TestWriteClient) expectDataCount(numSamples int) {
|
|
||||||
if !c.withWaitGroup {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mtx.Lock()
|
|
||||||
defer c.mtx.Unlock()
|
|
||||||
c.wg.Add(numSamples)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *TestWriteClient) waitForExpectedDataCount() {
|
|
||||||
if !c.withWaitGroup {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.wg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *TestWriteClient) Store(_ context.Context, req []byte) error {
|
func (c *TestWriteClient) Store(_ context.Context, req []byte) error {
|
||||||
c.mtx.Lock()
|
c.mtx.Lock()
|
||||||
defer c.mtx.Unlock()
|
defer c.mtx.Unlock()
|
||||||
|
@ -682,7 +666,15 @@ func (c *TestBlockingWriteClient) Endpoint() string {
|
||||||
return "http://test-remote-blocking.com/1234"
|
return "http://test-remote-blocking.com/1234"
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkSampleDelivery(b *testing.B) {
|
// For benchmarking the send and not the receive side.
|
||||||
|
type NopWriteClient struct{}
|
||||||
|
|
||||||
|
func NewNopWriteClient() *NopWriteClient { return &NopWriteClient{} }
|
||||||
|
func (c *NopWriteClient) Store(_ context.Context, req []byte) error { return nil }
|
||||||
|
func (c *NopWriteClient) Name() string { return "nopwriteclient" }
|
||||||
|
func (c *NopWriteClient) Endpoint() string { return "http://test-remote.com/1234" }
|
||||||
|
|
||||||
|
func BenchmarkSampleSend(b *testing.B) {
|
||||||
// Send one sample per series, which is the typical remote_write case
|
// Send one sample per series, which is the typical remote_write case
|
||||||
const numSamples = 1
|
const numSamples = 1
|
||||||
const numSeries = 10000
|
const numSeries = 10000
|
||||||
|
@ -707,12 +699,13 @@ func BenchmarkSampleDelivery(b *testing.B) {
|
||||||
}
|
}
|
||||||
samples, series := createTimeseries(numSamples, numSeries, extraLabels...)
|
samples, series := createTimeseries(numSamples, numSeries, extraLabels...)
|
||||||
|
|
||||||
c := NewTestWriteClient()
|
c := NewNopWriteClient()
|
||||||
|
|
||||||
cfg := config.DefaultQueueConfig
|
cfg := config.DefaultQueueConfig
|
||||||
mcfg := config.DefaultMetadataConfig
|
mcfg := config.DefaultMetadataConfig
|
||||||
cfg.BatchSendDeadline = model.Duration(100 * time.Millisecond)
|
cfg.BatchSendDeadline = model.Duration(100 * time.Millisecond)
|
||||||
cfg.MaxShards = 1
|
cfg.MinShards = 20
|
||||||
|
cfg.MaxShards = 20
|
||||||
|
|
||||||
dir := b.TempDir()
|
dir := b.TempDir()
|
||||||
|
|
||||||
|
@ -726,11 +719,9 @@ func BenchmarkSampleDelivery(b *testing.B) {
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
c.expectDataCount(len(samples))
|
m.Append(samples)
|
||||||
go m.Append(samples)
|
|
||||||
m.UpdateSeriesSegment(series, i+1) // simulate what wal.Watcher.garbageCollectSeries does
|
m.UpdateSeriesSegment(series, i+1) // simulate what wal.Watcher.garbageCollectSeries does
|
||||||
m.SeriesReset(i + 1)
|
m.SeriesReset(i + 1)
|
||||||
c.waitForExpectedDataCount()
|
|
||||||
}
|
}
|
||||||
// Do not include shutdown
|
// Do not include shutdown
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
|
|
|
@ -99,6 +99,9 @@ func (it *listSeriesIterator) Seek(t int64) bool {
|
||||||
if it.idx == -1 {
|
if it.idx == -1 {
|
||||||
it.idx = 0
|
it.idx = 0
|
||||||
}
|
}
|
||||||
|
if it.idx >= it.samples.Len() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// No-op check.
|
// No-op check.
|
||||||
if s := it.samples.Get(it.idx); s.T() >= t {
|
if s := it.samples.Get(it.idx); s.T() >= t {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -51,4 +51,9 @@ func TestListSeriesIterator(t *testing.T) {
|
||||||
ts, v = it.At()
|
ts, v = it.At()
|
||||||
require.Equal(t, int64(3), ts)
|
require.Equal(t, int64(3), ts)
|
||||||
require.Equal(t, 3., v)
|
require.Equal(t, 3., v)
|
||||||
|
|
||||||
|
// Seek beyond the end.
|
||||||
|
require.False(t, it.Seek(5))
|
||||||
|
// And we don't go back. (This exposes issue #10027.)
|
||||||
|
require.False(t, it.Seek(2))
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
html_template "html/template"
|
html_template "html/template"
|
||||||
"math"
|
"math"
|
||||||
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -184,6 +185,13 @@ func NewTemplateExpander(
|
||||||
sort.Stable(sorter)
|
sort.Stable(sorter)
|
||||||
return v
|
return v
|
||||||
},
|
},
|
||||||
|
"stripPort": func(hostPort string) string {
|
||||||
|
host, _, err := net.SplitHostPort(hostPort)
|
||||||
|
if err != nil {
|
||||||
|
return hostPort
|
||||||
|
}
|
||||||
|
return host
|
||||||
|
},
|
||||||
"humanize": func(i interface{}) (string, error) {
|
"humanize": func(i interface{}) (string, error) {
|
||||||
v, err := convertToFloat(i)
|
v, err := convertToFloat(i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -161,6 +161,41 @@ func TestTemplateExpansion(t *testing.T) {
|
||||||
},
|
},
|
||||||
output: "a:11: b:21: ",
|
output: "a:11: b:21: ",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// Simple hostname.
|
||||||
|
text: "{{ \"foo.example.com\" | stripPort }}",
|
||||||
|
output: "foo.example.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Hostname with port.
|
||||||
|
text: "{{ \"foo.example.com:12345\" | stripPort }}",
|
||||||
|
output: "foo.example.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Simple IPv4 address.
|
||||||
|
text: "{{ \"192.0.2.1\" | stripPort }}",
|
||||||
|
output: "192.0.2.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// IPv4 address with port.
|
||||||
|
text: "{{ \"192.0.2.1:12345\" | stripPort }}",
|
||||||
|
output: "192.0.2.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Simple IPv6 address.
|
||||||
|
text: "{{ \"2001:0DB8::1\" | stripPort }}",
|
||||||
|
output: "2001:0DB8::1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// IPv6 address with port.
|
||||||
|
text: "{{ \"[2001:0DB8::1]:12345\" | stripPort }}",
|
||||||
|
output: "2001:0DB8::1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Value can't be split into host and port.
|
||||||
|
text: "{{ \"[2001:0DB8::1]::12345\" | stripPort }}",
|
||||||
|
output: "[2001:0DB8::1]::12345",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Missing value is no value for nil options.
|
// Missing value is no value for nil options.
|
||||||
text: "{{ .Foo }}",
|
text: "{{ .Foo }}",
|
||||||
|
|
|
@ -103,11 +103,18 @@ func (h *headIndexReader) LabelNames(matchers ...*labels.Matcher) ([]string, err
|
||||||
|
|
||||||
// Postings returns the postings list iterator for the label pairs.
|
// Postings returns the postings list iterator for the label pairs.
|
||||||
func (h *headIndexReader) Postings(name string, values ...string) (index.Postings, error) {
|
func (h *headIndexReader) Postings(name string, values ...string) (index.Postings, error) {
|
||||||
res := make([]index.Postings, 0, len(values))
|
switch len(values) {
|
||||||
for _, value := range values {
|
case 0:
|
||||||
res = append(res, h.head.postings.Get(name, value))
|
return index.EmptyPostings(), nil
|
||||||
|
case 1:
|
||||||
|
return h.head.postings.Get(name, values[0]), nil
|
||||||
|
default:
|
||||||
|
res := make([]index.Postings, 0, len(values))
|
||||||
|
for _, value := range values {
|
||||||
|
res = append(res, h.head.postings.Get(name, value))
|
||||||
|
}
|
||||||
|
return index.Merge(res...), nil
|
||||||
}
|
}
|
||||||
return index.Merge(res...), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *headIndexReader) PostingsForMatchers(concurrent bool, ms ...*labels.Matcher) (index.Postings, error) {
|
func (h *headIndexReader) PostingsForMatchers(concurrent bool, ms ...*labels.Matcher) (index.Postings, error) {
|
||||||
|
|
|
@ -20,6 +20,8 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/model/labels"
|
"github.com/prometheus/prometheus/model/labels"
|
||||||
"github.com/prometheus/prometheus/storage"
|
"github.com/prometheus/prometheus/storage"
|
||||||
)
|
)
|
||||||
|
@ -853,3 +855,78 @@ type seriesRefSlice []storage.SeriesRef
|
||||||
func (x seriesRefSlice) Len() int { return len(x) }
|
func (x seriesRefSlice) Len() int { return len(x) }
|
||||||
func (x seriesRefSlice) Less(i, j int) bool { return x[i] < x[j] }
|
func (x seriesRefSlice) Less(i, j int) bool { return x[i] < x[j] }
|
||||||
func (x seriesRefSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
func (x seriesRefSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
|
// FindIntersectingPostings checks the intersection of p and candidates[i] for each i in candidates,
|
||||||
|
// if intersection is non empty, then i is added to the indexes returned.
|
||||||
|
// Returned indexes are not sorted.
|
||||||
|
func FindIntersectingPostings(p Postings, candidates []Postings) (indexes []int, err error) {
|
||||||
|
h := make(postingsWithIndexHeap, 0, len(candidates))
|
||||||
|
for idx, it := range candidates {
|
||||||
|
if it.Next() {
|
||||||
|
h = append(h, postingsWithIndex{index: idx, p: it})
|
||||||
|
} else if it.Err() != nil {
|
||||||
|
return nil, it.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(h) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
h.Init()
|
||||||
|
|
||||||
|
for len(h) > 0 {
|
||||||
|
if !p.Seek(h.At()) {
|
||||||
|
return indexes, p.Err()
|
||||||
|
}
|
||||||
|
if p.At() == h.At() {
|
||||||
|
found := heap.Pop(&h).(postingsWithIndex)
|
||||||
|
indexes = append(indexes, found.index)
|
||||||
|
} else if err := h.Next(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return indexes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type postingsWithIndex struct {
|
||||||
|
index int
|
||||||
|
p Postings
|
||||||
|
}
|
||||||
|
|
||||||
|
type postingsWithIndexHeap []postingsWithIndex
|
||||||
|
|
||||||
|
func (h *postingsWithIndexHeap) Init() { heap.Init(h) }
|
||||||
|
func (h postingsWithIndexHeap) At() storage.SeriesRef { return h[0].p.At() }
|
||||||
|
func (h *postingsWithIndexHeap) Next() error {
|
||||||
|
pi := (*h)[0]
|
||||||
|
next := pi.p.Next()
|
||||||
|
if next {
|
||||||
|
heap.Fix(h, 0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pi.p.Err(); err != nil {
|
||||||
|
return errors.Wrapf(err, "postings %d", pi.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.Pop(h)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h postingsWithIndexHeap) Len() int { return len(h) }
|
||||||
|
func (h postingsWithIndexHeap) Less(i, j int) bool { return h[i].p.At() < h[j].p.At() }
|
||||||
|
func (h *postingsWithIndexHeap) Swap(i, j int) { (*h)[i], (*h)[j] = (*h)[j], (*h)[i] }
|
||||||
|
|
||||||
|
func (h *postingsWithIndexHeap) Push(x interface{}) {
|
||||||
|
*h = append(*h, x.(postingsWithIndex))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop implements heap.Interface and pops the last element, which is NOT the min element,
|
||||||
|
// so this doesn't return the same heap.Pop()
|
||||||
|
func (h *postingsWithIndexHeap) Pop() interface{} {
|
||||||
|
old := *h
|
||||||
|
n := len(old)
|
||||||
|
x := old[n-1]
|
||||||
|
*h = old[0 : n-1]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
package index
|
package index
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"container/heap"
|
||||||
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
@ -21,6 +23,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/model/labels"
|
"github.com/prometheus/prometheus/model/labels"
|
||||||
|
@ -1052,3 +1055,142 @@ func TestPostingsCloner(t *testing.T) {
|
||||||
require.Equal(t, expectedErr, p.Err())
|
require.Equal(t, expectedErr, p.Err())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindIntersectingPostings(t *testing.T) {
|
||||||
|
t.Run("multiple intersections", func(t *testing.T) {
|
||||||
|
p := NewListPostings([]storage.SeriesRef{10, 15, 20, 25, 30, 35, 40, 45, 50})
|
||||||
|
candidates := []Postings{
|
||||||
|
0: NewListPostings([]storage.SeriesRef{7, 13, 14, 27}), // Does not intersect.
|
||||||
|
1: NewListPostings([]storage.SeriesRef{10, 20}), // Does intersect.
|
||||||
|
2: NewListPostings([]storage.SeriesRef{29, 30, 31}), // Does intersect.
|
||||||
|
3: NewListPostings([]storage.SeriesRef{29, 30, 31}), // Does intersect (same again).
|
||||||
|
4: NewListPostings([]storage.SeriesRef{60}), // Does not intersect.
|
||||||
|
5: NewListPostings([]storage.SeriesRef{45}), // Does intersect.
|
||||||
|
6: EmptyPostings(), // Does not intersect.
|
||||||
|
}
|
||||||
|
|
||||||
|
indexes, err := FindIntersectingPostings(p, candidates)
|
||||||
|
require.NoError(t, err)
|
||||||
|
sort.Ints(indexes)
|
||||||
|
require.Equal(t, []int{1, 2, 3, 5}, indexes)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("no intersections", func(t *testing.T) {
|
||||||
|
p := NewListPostings([]storage.SeriesRef{10, 15, 20, 25, 30, 35, 40, 45, 50})
|
||||||
|
candidates := []Postings{
|
||||||
|
0: NewListPostings([]storage.SeriesRef{7, 13, 14, 27}), // Does not intersect.
|
||||||
|
1: NewListPostings([]storage.SeriesRef{60}), // Does not intersect.
|
||||||
|
2: EmptyPostings(), // Does not intersect.
|
||||||
|
}
|
||||||
|
|
||||||
|
indexes, err := FindIntersectingPostings(p, candidates)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Empty(t, indexes)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("p is ErrPostings", func(t *testing.T) {
|
||||||
|
p := ErrPostings(context.Canceled)
|
||||||
|
candidates := []Postings{NewListPostings([]storage.SeriesRef{1})}
|
||||||
|
_, err := FindIntersectingPostings(p, candidates)
|
||||||
|
require.Error(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("one of the candidates is ErrPostings", func(t *testing.T) {
|
||||||
|
p := NewListPostings([]storage.SeriesRef{1})
|
||||||
|
candidates := []Postings{
|
||||||
|
NewListPostings([]storage.SeriesRef{1}),
|
||||||
|
ErrPostings(context.Canceled),
|
||||||
|
}
|
||||||
|
_, err := FindIntersectingPostings(p, candidates)
|
||||||
|
require.Error(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("one of the candidates fails on nth call", func(t *testing.T) {
|
||||||
|
p := NewListPostings([]storage.SeriesRef{10, 20, 30, 40, 50, 60, 70})
|
||||||
|
candidates := []Postings{
|
||||||
|
NewListPostings([]storage.SeriesRef{7, 13, 14, 27}),
|
||||||
|
&postingsFailingAfterNthCall{2, NewListPostings([]storage.SeriesRef{29, 30, 31, 40})},
|
||||||
|
}
|
||||||
|
_, err := FindIntersectingPostings(p, candidates)
|
||||||
|
require.Error(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("p fails on the nth call", func(t *testing.T) {
|
||||||
|
p := &postingsFailingAfterNthCall{2, NewListPostings([]storage.SeriesRef{10, 20, 30, 40, 50, 60, 70})}
|
||||||
|
candidates := []Postings{
|
||||||
|
NewListPostings([]storage.SeriesRef{7, 13, 14, 27}),
|
||||||
|
NewListPostings([]storage.SeriesRef{29, 30, 31, 40}),
|
||||||
|
}
|
||||||
|
_, err := FindIntersectingPostings(p, candidates)
|
||||||
|
require.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type postingsFailingAfterNthCall struct {
|
||||||
|
ttl int
|
||||||
|
Postings
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *postingsFailingAfterNthCall) Seek(v storage.SeriesRef) bool {
|
||||||
|
p.ttl--
|
||||||
|
if p.ttl <= 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return p.Postings.Seek(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *postingsFailingAfterNthCall) Next() bool {
|
||||||
|
p.ttl--
|
||||||
|
if p.ttl <= 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return p.Postings.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *postingsFailingAfterNthCall) Err() error {
|
||||||
|
if p.ttl <= 0 {
|
||||||
|
return errors.New("ttl exceeded")
|
||||||
|
}
|
||||||
|
return p.Postings.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPostingsWithIndexHeap(t *testing.T) {
|
||||||
|
t.Run("iterate", func(t *testing.T) {
|
||||||
|
h := postingsWithIndexHeap{
|
||||||
|
{index: 0, p: NewListPostings([]storage.SeriesRef{10, 20, 30})},
|
||||||
|
{index: 1, p: NewListPostings([]storage.SeriesRef{1, 5})},
|
||||||
|
{index: 2, p: NewListPostings([]storage.SeriesRef{25, 50})},
|
||||||
|
}
|
||||||
|
for _, node := range h {
|
||||||
|
node.p.Next()
|
||||||
|
}
|
||||||
|
h.Init()
|
||||||
|
|
||||||
|
for _, expected := range []storage.SeriesRef{1, 5, 10, 20, 25, 30, 50} {
|
||||||
|
require.Equal(t, expected, h.At())
|
||||||
|
require.NoError(t, h.Next())
|
||||||
|
}
|
||||||
|
require.Empty(t, h)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("pop", func(t *testing.T) {
|
||||||
|
h := postingsWithIndexHeap{
|
||||||
|
{index: 0, p: NewListPostings([]storage.SeriesRef{10, 20, 30})},
|
||||||
|
{index: 1, p: NewListPostings([]storage.SeriesRef{1, 5})},
|
||||||
|
{index: 2, p: NewListPostings([]storage.SeriesRef{25, 50})},
|
||||||
|
}
|
||||||
|
for _, node := range h {
|
||||||
|
node.p.Next()
|
||||||
|
}
|
||||||
|
h.Init()
|
||||||
|
|
||||||
|
for _, expected := range []storage.SeriesRef{1, 5, 10, 20} {
|
||||||
|
require.Equal(t, expected, h.At())
|
||||||
|
require.NoError(t, h.Next())
|
||||||
|
}
|
||||||
|
require.Equal(t, storage.SeriesRef(25), h.At())
|
||||||
|
node := heap.Pop(&h).(postingsWithIndex)
|
||||||
|
require.Equal(t, 2, node.index)
|
||||||
|
require.Equal(t, storage.SeriesRef(25), node.p.At())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -324,38 +324,30 @@ func inversePostingsForMatcher(ix IndexPostingsReader, m *labels.Matcher) (index
|
||||||
}
|
}
|
||||||
|
|
||||||
func labelValuesWithMatchers(r IndexReader, name string, matchers ...*labels.Matcher) ([]string, error) {
|
func labelValuesWithMatchers(r IndexReader, name string, matchers ...*labels.Matcher) ([]string, error) {
|
||||||
// We're only interested in metrics which have the label <name>.
|
p, err := PostingsForMatchers(r, matchers...)
|
||||||
requireLabel, err := labels.NewMatcher(labels.MatchNotEqual, name, "")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "Failed to instantiate label matcher")
|
return nil, errors.Wrap(err, "fetching postings for matchers")
|
||||||
}
|
}
|
||||||
|
|
||||||
var p index.Postings
|
allValues, err := r.LabelValues(name)
|
||||||
p, err = r.PostingsForMatchers(false, append(matchers, requireLabel)...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrapf(err, "fetching values of label %s", name)
|
||||||
}
|
}
|
||||||
|
valuesPostings := make([]index.Postings, len(allValues))
|
||||||
dedupe := map[string]interface{}{}
|
for i, value := range allValues {
|
||||||
for p.Next() {
|
valuesPostings[i], err = r.Postings(name, value)
|
||||||
v, err := r.LabelValueFor(p.At(), name)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == storage.ErrNotFound {
|
return nil, errors.Wrapf(err, "fetching postings for %s=%q", name, value)
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
dedupe[v] = nil
|
}
|
||||||
|
indexes, err := index.FindIntersectingPostings(p, valuesPostings)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "intersecting postings")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = p.Err(); err != nil {
|
values := make([]string, 0, len(indexes))
|
||||||
return nil, err
|
for _, idx := range indexes {
|
||||||
}
|
values = append(values, allValues[idx])
|
||||||
|
|
||||||
values := make([]string, 0, len(dedupe))
|
|
||||||
for value := range dedupe {
|
|
||||||
values = append(values, value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return values, nil
|
return values, nil
|
||||||
|
|
|
@ -33,7 +33,7 @@ const (
|
||||||
postingsBenchSuffix = "aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd"
|
postingsBenchSuffix = "aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkPostingsForMatchers(b *testing.B) {
|
func BenchmarkQuerier(b *testing.B) {
|
||||||
chunkDir, err := ioutil.TempDir("", "chunk_dir")
|
chunkDir, err := ioutil.TempDir("", "chunk_dir")
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -68,7 +68,12 @@ func BenchmarkPostingsForMatchers(b *testing.B) {
|
||||||
ir, err := h.Index()
|
ir, err := h.Index()
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
b.Run("Head", func(b *testing.B) {
|
b.Run("Head", func(b *testing.B) {
|
||||||
benchmarkPostingsForMatchers(b, ir)
|
b.Run("PostingsForMatchers", func(b *testing.B) {
|
||||||
|
benchmarkPostingsForMatchers(b, ir)
|
||||||
|
})
|
||||||
|
b.Run("labelValuesWithMatchers", func(b *testing.B) {
|
||||||
|
benchmarkLabelValuesWithMatchers(b, ir)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "test_benchpostingsformatchers")
|
tmpdir, err := ioutil.TempDir("", "test_benchpostingsformatchers")
|
||||||
|
@ -87,7 +92,12 @@ func BenchmarkPostingsForMatchers(b *testing.B) {
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
defer ir.Close()
|
defer ir.Close()
|
||||||
b.Run("Block", func(b *testing.B) {
|
b.Run("Block", func(b *testing.B) {
|
||||||
benchmarkPostingsForMatchers(b, ir)
|
b.Run("PostingsForMatchers", func(b *testing.B) {
|
||||||
|
benchmarkPostingsForMatchers(b, ir)
|
||||||
|
})
|
||||||
|
b.Run("labelValuesWithMatchers", func(b *testing.B) {
|
||||||
|
benchmarkLabelValuesWithMatchers(b, ir)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +115,7 @@ func benchmarkPostingsForMatchers(b *testing.B, ir IndexReader) {
|
||||||
i1Plus := labels.MustNewMatcher(labels.MatchRegexp, "i", "^1.+$")
|
i1Plus := labels.MustNewMatcher(labels.MatchRegexp, "i", "^1.+$")
|
||||||
iEmptyRe := labels.MustNewMatcher(labels.MatchRegexp, "i", "^$")
|
iEmptyRe := labels.MustNewMatcher(labels.MatchRegexp, "i", "^$")
|
||||||
iNotEmpty := labels.MustNewMatcher(labels.MatchNotEqual, "i", "")
|
iNotEmpty := labels.MustNewMatcher(labels.MatchNotEqual, "i", "")
|
||||||
iNot2 := labels.MustNewMatcher(labels.MatchNotEqual, "n", "2"+postingsBenchSuffix)
|
iNot2 := labels.MustNewMatcher(labels.MatchNotEqual, "i", "2"+postingsBenchSuffix)
|
||||||
iNot2Star := labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^2.*$")
|
iNot2Star := labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^2.*$")
|
||||||
iNotStar2Star := labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^.*2.*$")
|
iNotStar2Star := labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^.*2.*$")
|
||||||
jFooBar := labels.MustNewMatcher(labels.MatchRegexp, "j", "foo|bar")
|
jFooBar := labels.MustNewMatcher(labels.MatchRegexp, "j", "foo|bar")
|
||||||
|
@ -150,6 +160,38 @@ func benchmarkPostingsForMatchers(b *testing.B, ir IndexReader) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func benchmarkLabelValuesWithMatchers(b *testing.B, ir IndexReader) {
|
||||||
|
i1 := labels.MustNewMatcher(labels.MatchEqual, "i", "1")
|
||||||
|
iStar := labels.MustNewMatcher(labels.MatchRegexp, "i", "^.*$")
|
||||||
|
jNotFoo := labels.MustNewMatcher(labels.MatchNotEqual, "j", "foo")
|
||||||
|
n1 := labels.MustNewMatcher(labels.MatchEqual, "n", "1"+postingsBenchSuffix)
|
||||||
|
nPlus := labels.MustNewMatcher(labels.MatchRegexp, "i", "^.+$")
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
labelName string
|
||||||
|
matchers []*labels.Matcher
|
||||||
|
}{
|
||||||
|
// i has 100k values.
|
||||||
|
{`i with n="1"`, "i", []*labels.Matcher{n1}},
|
||||||
|
{`i with n="^.+$"`, "i", []*labels.Matcher{nPlus}},
|
||||||
|
{`i with n="1",j!="foo"`, "i", []*labels.Matcher{n1, jNotFoo}},
|
||||||
|
{`i with n="1",i=~"^.*$",j!="foo"`, "i", []*labels.Matcher{n1, iStar, jNotFoo}},
|
||||||
|
// n has 10 values.
|
||||||
|
{`n with j!="foo"`, "n", []*labels.Matcher{jNotFoo}},
|
||||||
|
{`n with i="1"`, "n", []*labels.Matcher{i1}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
b.Run(c.name, func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err := labelValuesWithMatchers(ir, c.labelName, c.matchers...)
|
||||||
|
require.NoError(b, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkQuerierSelect(b *testing.B) {
|
func BenchmarkQuerierSelect(b *testing.B) {
|
||||||
chunkDir, err := ioutil.TempDir("", "chunk_dir")
|
chunkDir, err := ioutil.TempDir("", "chunk_dir")
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
|
|
|
@ -159,6 +159,9 @@ func (it *listSeriesIterator) Seek(t int64) bool {
|
||||||
if it.idx == -1 {
|
if it.idx == -1 {
|
||||||
it.idx = 0
|
it.idx = 0
|
||||||
}
|
}
|
||||||
|
if it.idx >= len(it.list) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// No-op check.
|
// No-op check.
|
||||||
if s := it.list[it.idx]; s.T() >= t {
|
if s := it.list[it.idx]; s.T() >= t {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -190,7 +190,7 @@ func OpenSegmentWAL(dir string, logger log.Logger, flushInterval time.Duration,
|
||||||
flushInterval: flushInterval,
|
flushInterval: flushInterval,
|
||||||
donec: make(chan struct{}),
|
donec: make(chan struct{}),
|
||||||
stopc: make(chan struct{}),
|
stopc: make(chan struct{}),
|
||||||
actorc: make(chan func() error, 1),
|
actorc: make(chan func() error, 2),
|
||||||
segmentSize: walSegmentSizeBytes,
|
segmentSize: walSegmentSizeBytes,
|
||||||
crc32: newCRC32(),
|
crc32: newCRC32(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ func New(t testutil.T) *TestStorage {
|
||||||
opts := tsdb.DefaultOptions()
|
opts := tsdb.DefaultOptions()
|
||||||
opts.MinBlockDuration = int64(24 * time.Hour / time.Millisecond)
|
opts.MinBlockDuration = int64(24 * time.Hour / time.Millisecond)
|
||||||
opts.MaxBlockDuration = int64(24 * time.Hour / time.Millisecond)
|
opts.MaxBlockDuration = int64(24 * time.Hour / time.Millisecond)
|
||||||
|
opts.RetentionDuration = 0
|
||||||
db, err := tsdb.Open(dir, nil, nil, opts, tsdb.NewDBStats())
|
db, err := tsdb.Open(dir, nil, nil, opts, tsdb.NewDBStats())
|
||||||
require.NoError(t, err, "unexpected error while opening test storage")
|
require.NoError(t, err, "unexpected error while opening test storage")
|
||||||
reg := prometheus.NewRegistry()
|
reg := prometheus.NewRegistry()
|
||||||
|
|
|
@ -155,11 +155,18 @@ type TSDBAdminStats interface {
|
||||||
WALReplayStatus() (tsdb.WALReplayStatus, error)
|
WALReplayStatus() (tsdb.WALReplayStatus, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryEngine defines the interface for the *promql.Engine, so it can be replaced, wrapped or mocked.
|
||||||
|
type QueryEngine interface {
|
||||||
|
SetQueryLogger(l promql.QueryLogger)
|
||||||
|
NewInstantQuery(q storage.Queryable, qs string, ts time.Time) (promql.Query, error)
|
||||||
|
NewRangeQuery(q storage.Queryable, qs string, start, end time.Time, interval time.Duration) (promql.Query, error)
|
||||||
|
}
|
||||||
|
|
||||||
// API can register a set of endpoints in a router and handle
|
// API can register a set of endpoints in a router and handle
|
||||||
// them using the provided storage and query engine.
|
// them using the provided storage and query engine.
|
||||||
type API struct {
|
type API struct {
|
||||||
Queryable storage.SampleAndChunkQueryable
|
Queryable storage.SampleAndChunkQueryable
|
||||||
QueryEngine *promql.Engine
|
QueryEngine QueryEngine
|
||||||
ExemplarQueryable storage.ExemplarQueryable
|
ExemplarQueryable storage.ExemplarQueryable
|
||||||
|
|
||||||
targetRetriever func(context.Context) TargetRetriever
|
targetRetriever func(context.Context) TargetRetriever
|
||||||
|
@ -192,7 +199,7 @@ func init() {
|
||||||
|
|
||||||
// NewAPI returns an initialized API type.
|
// NewAPI returns an initialized API type.
|
||||||
func NewAPI(
|
func NewAPI(
|
||||||
qe *promql.Engine,
|
qe QueryEngine,
|
||||||
q storage.SampleAndChunkQueryable,
|
q storage.SampleAndChunkQueryable,
|
||||||
ap storage.Appendable,
|
ap storage.Appendable,
|
||||||
eq storage.ExemplarQueryable,
|
eq storage.ExemplarQueryable,
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
0.19.0 / 2021-12-20
|
||||||
|
===================
|
||||||
|
|
||||||
|
* **[Enhancement]**: Add a negative autocompletion boost to some trigonometric functions that can overlap with other more popular PromQL functions.
|
||||||
|
* **[BugFix]**: Improve checking of whether a `PrometheusConfig` object was passed to `newCompleteStrategy()`.
|
||||||
|
|
||||||
0.18.0 / 2021-10-20
|
0.18.0 / 2021-10-20
|
||||||
===================
|
===================
|
||||||
|
|
||||||
* **[Feature]**: Allow overriding the API prefix used to contact a remote Prometheus.
|
* **[Feature]**: Allow overriding the API prefix used to contact a remote Prometheus.
|
||||||
* **[Feature]**: Add linter and autocompletion support for trigonometric functions (like `sin`, `cos`)
|
* **[Feature]**: Add linter and autocompletion support for trigonometric functions (like `sin`, `cos`)
|
||||||
* **[BreakingChange]**: The lib is now exposed under the `dist` folder. When importing `codemirror-promql`, it means you
|
* **[BreakingChange]**: The lib is now exposed under the `dist` folder. When importing `codemirror-promql`, it means you
|
||||||
will need to add `dist` in the import. For example `import { newCompleteStrategy } from 'codemirror-promql/cjs/complete';`
|
will need to add `dist` in the import. For example `import { newCompleteStrategy } from 'codemirror-promql/cjs/complete';`
|
||||||
becomes `import { newCompleteStrategy } from 'codemirror-promql/dist/cjs/complete';`
|
becomes `import { newCompleteStrategy } from 'codemirror-promql/dist/cjs/complete';`
|
||||||
* **[BreakingChange]**: lezer-promql has been migrated into codemirror-promql in the `grammar` folder
|
* **[BreakingChange]**: lezer-promql has been migrated into codemirror-promql in the `grammar` folder
|
||||||
|
@ -22,8 +28,8 @@ becomes `import { newCompleteStrategy } from 'codemirror-promql/dist/cjs/complet
|
||||||
name. (#142)
|
name. (#142)
|
||||||
* **[Feature]**: Autocomplete `NaN` and `Inf` (#141)
|
* **[Feature]**: Autocomplete `NaN` and `Inf` (#141)
|
||||||
* **[Enhancement]**: Fetch series using the HTTP `POST` method (#139)
|
* **[Enhancement]**: Fetch series using the HTTP `POST` method (#139)
|
||||||
* **[Enhancement]**: Upgrade lezer-promql that fixed the parsing of metric names starting with `Inf`/`NaN` like infra (#142)
|
* **[Enhancement]**: Upgrade lezer-promql that fixed the parsing of metric names starting with `Inf`/`NaN` like infra (#142)
|
||||||
* **[BreakingChange]**: The constant `promQLLanguage` has been changed to be a function. It takes a `LanguageType` as a
|
* **[BreakingChange]**: The constant `promQLLanguage` has been changed to be a function. It takes a `LanguageType` as a
|
||||||
parameter (#142)
|
parameter (#142)
|
||||||
|
|
||||||
0.15.0 / 2021-04-13
|
0.15.0 / 2021-04-13
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "codemirror-promql",
|
"name": "codemirror-promql",
|
||||||
"version": "0.18.0",
|
"version": "0.19.0",
|
||||||
"description": "a CodeMirror mode for the PromQL language",
|
"description": "a CodeMirror mode for the PromQL language",
|
||||||
"main": "dist/cjs/index.js",
|
"main": "dist/cjs/index.js",
|
||||||
"module": "dist/esm/index.js",
|
"module": "dist/esm/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build:grammar && npm run build:lib",
|
"build": "npm run build:grammar && npm run build:lib",
|
||||||
"build:grammar": "lezer-generator src/grammar/promql.grammar -o src/grammar/parser",
|
"build:grammar": "npx lezer-generator src/grammar/promql.grammar -o src/grammar/parser",
|
||||||
"build:lib": "bash ./build.sh",
|
"build:lib": "bash ./build.sh",
|
||||||
"test": "npm run build:grammar && ts-mocha -p tsconfig.json ./**/*.test.ts",
|
"test": "npm run build:grammar && ts-mocha -p tsconfig.json ./**/*.test.ts",
|
||||||
"test:coverage": "npm run build:grammar && nyc ts-mocha -p ./tsconfig.json ./**/*.test.ts",
|
"test:coverage": "npm run build:grammar && nyc ts-mocha -p ./tsconfig.json ./**/*.test.ts",
|
||||||
|
@ -41,17 +41,18 @@
|
||||||
"@codemirror/lint": "^0.19.3",
|
"@codemirror/lint": "^0.19.3",
|
||||||
"@codemirror/state": "^0.19.6",
|
"@codemirror/state": "^0.19.6",
|
||||||
"@codemirror/view": "^0.19.27",
|
"@codemirror/view": "^0.19.27",
|
||||||
"@lezer/common": "^0.15.10",
|
"@lezer/common": "^0.15.11",
|
||||||
|
"@lezer/lr": "^0.15.5",
|
||||||
"@lezer/generator": "^0.15.2",
|
"@lezer/generator": "^0.15.2",
|
||||||
"@types/chai": "^4.2.22",
|
"@types/chai": "^4.2.22",
|
||||||
"@types/lru-cache": "^5.1.1",
|
"@types/lru-cache": "^5.1.1",
|
||||||
"@types/mocha": "^9.0.0",
|
"@types/mocha": "^9.0.0",
|
||||||
"@types/node": "^16.11.12",
|
"@types/node": "^16.11.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.5.0",
|
"@typescript-eslint/eslint-plugin": "^5.8.0",
|
||||||
"@typescript-eslint/parser": "^5.5.0",
|
"@typescript-eslint/parser": "^5.8.0",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"codecov": "^3.8.3",
|
"codecov": "^3.8.3",
|
||||||
"eslint": "^8.4.0",
|
"eslint": "^8.4.1",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-plugin-flowtype": "^8.0.3",
|
"eslint-plugin-flowtype": "^8.0.3",
|
||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
@ -73,7 +74,7 @@
|
||||||
"@codemirror/lint": "^0.19.3",
|
"@codemirror/lint": "^0.19.3",
|
||||||
"@codemirror/state": "^0.19.6",
|
"@codemirror/state": "^0.19.6",
|
||||||
"@codemirror/view": "^0.19.27",
|
"@codemirror/view": "^0.19.27",
|
||||||
"@lezer/common": "^0.15.10"
|
"@lezer/common": "^0.15.11"
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
|
|
|
@ -342,7 +342,7 @@ export function analyzeCompletion(state: EditorState, node: SyntaxNode): Context
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PromQL:
|
case PromQL:
|
||||||
if (!node.firstChild) {
|
if (node.firstChild !== null && node.firstChild.type.id === 0) {
|
||||||
// this situation can happen when there is nothing in the text area and the user is explicitly triggering the autocompletion (with ctrl + space)
|
// this situation can happen when there is nothing in the text area and the user is explicitly triggering the autocompletion (with ctrl + space)
|
||||||
result.push(
|
result.push(
|
||||||
{ kind: ContextKind.MetricName, metricName: '' },
|
{ kind: ContextKind.MetricName, metricName: '' },
|
||||||
|
|
221
web/ui/package-lock.json
generated
221
web/ui/package-lock.json
generated
|
@ -14,7 +14,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql": {
|
"module/codemirror-promql": {
|
||||||
"version": "0.18.0",
|
"version": "0.19.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
|
@ -27,17 +27,18 @@
|
||||||
"@codemirror/lint": "^0.19.3",
|
"@codemirror/lint": "^0.19.3",
|
||||||
"@codemirror/state": "^0.19.6",
|
"@codemirror/state": "^0.19.6",
|
||||||
"@codemirror/view": "^0.19.27",
|
"@codemirror/view": "^0.19.27",
|
||||||
"@lezer/common": "^0.15.10",
|
"@lezer/common": "^0.15.11",
|
||||||
"@lezer/generator": "^0.15.2",
|
"@lezer/generator": "^0.15.2",
|
||||||
|
"@lezer/lr": "^0.15.5",
|
||||||
"@types/chai": "^4.2.22",
|
"@types/chai": "^4.2.22",
|
||||||
"@types/lru-cache": "^5.1.1",
|
"@types/lru-cache": "^5.1.1",
|
||||||
"@types/mocha": "^9.0.0",
|
"@types/mocha": "^9.0.0",
|
||||||
"@types/node": "^16.11.12",
|
"@types/node": "^16.11.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.5.0",
|
"@typescript-eslint/eslint-plugin": "^5.8.0",
|
||||||
"@typescript-eslint/parser": "^5.5.0",
|
"@typescript-eslint/parser": "^5.8.0",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"codecov": "^3.8.3",
|
"codecov": "^3.8.3",
|
||||||
"eslint": "^8.4.0",
|
"eslint": "^8.4.1",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-plugin-flowtype": "^8.0.3",
|
"eslint-plugin-flowtype": "^8.0.3",
|
||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
@ -62,7 +63,7 @@
|
||||||
"@codemirror/lint": "^0.19.3",
|
"@codemirror/lint": "^0.19.3",
|
||||||
"@codemirror/state": "^0.19.6",
|
"@codemirror/state": "^0.19.6",
|
||||||
"@codemirror/view": "^0.19.27",
|
"@codemirror/view": "^0.19.27",
|
||||||
"@lezer/common": "^0.15.10"
|
"@lezer/common": "^0.15.11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql/node_modules/@eslint/eslintrc": {
|
"module/codemirror-promql/node_modules/@eslint/eslintrc": {
|
||||||
|
@ -100,13 +101,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql/node_modules/@typescript-eslint/eslint-plugin": {
|
"module/codemirror-promql/node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.8.0.tgz",
|
||||||
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==",
|
"integrity": "sha512-spu1UW7QuBn0nJ6+psnfCc3iVoQAifjKORgBngKOmC8U/1tbe2YJMzYQqDGYB4JCss7L8+RM2kKLb1B1Aw9BNA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/experimental-utils": "5.5.0",
|
"@typescript-eslint/experimental-utils": "5.8.0",
|
||||||
"@typescript-eslint/scope-manager": "5.5.0",
|
"@typescript-eslint/scope-manager": "5.8.0",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"functional-red-black-tree": "^1.0.1",
|
"functional-red-black-tree": "^1.0.1",
|
||||||
"ignore": "^5.1.8",
|
"ignore": "^5.1.8",
|
||||||
|
@ -140,15 +141,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql/node_modules/@typescript-eslint/experimental-utils": {
|
"module/codemirror-promql/node_modules/@typescript-eslint/experimental-utils": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.8.0.tgz",
|
||||||
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==",
|
"integrity": "sha512-KN5FvNH71bhZ8fKtL+lhW7bjm7cxs1nt+hrDZWIqb6ViCffQcWyLunGrgvISgkRojIDcXIsH+xlFfI4RCDA0xA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/json-schema": "^7.0.9",
|
"@types/json-schema": "^7.0.9",
|
||||||
"@typescript-eslint/scope-manager": "5.5.0",
|
"@typescript-eslint/scope-manager": "5.8.0",
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"@typescript-eslint/typescript-estree": "5.5.0",
|
"@typescript-eslint/typescript-estree": "5.8.0",
|
||||||
"eslint-scope": "^5.1.1",
|
"eslint-scope": "^5.1.1",
|
||||||
"eslint-utils": "^3.0.0"
|
"eslint-utils": "^3.0.0"
|
||||||
},
|
},
|
||||||
|
@ -160,18 +161,18 @@
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "*"
|
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql/node_modules/@typescript-eslint/parser": {
|
"module/codemirror-promql/node_modules/@typescript-eslint/parser": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.8.0.tgz",
|
||||||
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
|
"integrity": "sha512-Gleacp/ZhRtJRYs5/T8KQR3pAQjQI89Dn/k+OzyCKOsLiZH2/Vh60cFBTnFsHNI6WAD+lNUo/xGZ4NeA5u0Ipw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "5.5.0",
|
"@typescript-eslint/scope-manager": "5.8.0",
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"@typescript-eslint/typescript-estree": "5.5.0",
|
"@typescript-eslint/typescript-estree": "5.8.0",
|
||||||
"debug": "^4.3.2"
|
"debug": "^4.3.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -191,13 +192,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql/node_modules/@typescript-eslint/scope-manager": {
|
"module/codemirror-promql/node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.8.0.tgz",
|
||||||
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==",
|
"integrity": "sha512-x82CYJsLOjPCDuFFEbS6e7K1QEWj7u5Wk1alw8A+gnJiYwNnDJk0ib6PCegbaPMjrfBvFKa7SxE3EOnnIQz2Gg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.5.0"
|
"@typescript-eslint/visitor-keys": "5.8.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
@ -208,9 +209,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql/node_modules/@typescript-eslint/types": {
|
"module/codemirror-promql/node_modules/@typescript-eslint/types": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.8.0.tgz",
|
||||||
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==",
|
"integrity": "sha512-LdCYOqeqZWqCMOmwFnum6YfW9F3nKuxJiR84CdIRN5nfHJ7gyvGpXWqL/AaW0k3Po0+wm93ARAsOdzlZDPCcXg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
@ -221,13 +222,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql/node_modules/@typescript-eslint/typescript-estree": {
|
"module/codemirror-promql/node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.8.0.tgz",
|
||||||
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==",
|
"integrity": "sha512-srfeZ3URdEcUsSLbkOFqS7WoxOqn8JNil2NSLO9O+I2/Uyc85+UlfpEvQHIpj5dVts7KKOZnftoJD/Fdv0L7nQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.5.0",
|
"@typescript-eslint/visitor-keys": "5.8.0",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"globby": "^11.0.4",
|
"globby": "^11.0.4",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
|
@ -248,12 +249,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql/node_modules/@typescript-eslint/visitor-keys": {
|
"module/codemirror-promql/node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.8.0.tgz",
|
||||||
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==",
|
"integrity": "sha512-+HDIGOEMnqbxdAHegxvnOqESUH6RWFRR2b8qxP1W9CZnnYh4Usz6MBL+2KMAgPk/P0o9c1HqnYtwzVH6GTIqug==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"eslint-visitor-keys": "^3.0.0"
|
"eslint-visitor-keys": "^3.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -313,9 +314,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"module/codemirror-promql/node_modules/eslint": {
|
"module/codemirror-promql/node_modules/eslint": {
|
||||||
"version": "8.4.0",
|
"version": "8.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz",
|
||||||
"integrity": "sha512-kv0XQcAQJL/VD9THQKhTQZVqkJKA+tIj/v2ZKNaIHRAADcJWFb+B/BAewUYuF6UVg1s2xC5qXVoDk0G8sKGeTA==",
|
"integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/eslintrc": "^1.0.5",
|
"@eslint/eslintrc": "^1.0.5",
|
||||||
|
@ -1567,9 +1568,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lezer/common": {
|
"node_modules/@lezer/common": {
|
||||||
"version": "0.15.10",
|
"version": "0.15.11",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.10.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.11.tgz",
|
||||||
"integrity": "sha512-vlr+be73zTDoQBIknBVOh/633tmbQcjxUu9PIeVeYESeBK3V6TuBW96RRFg93Y2cyK9lglz241gOgSn452HFvA=="
|
"integrity": "sha512-vv0nSdIaVCRcJ8rPuDdsrNVfBOYe/4Szr/LhF929XyDmBndLDuWiCCHooGlGlJfzELyO608AyDhVsuX/ZG36NA=="
|
||||||
},
|
},
|
||||||
"node_modules/@lezer/generator": {
|
"node_modules/@lezer/generator": {
|
||||||
"version": "0.15.2",
|
"version": "0.15.2",
|
||||||
|
@ -1584,8 +1585,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lezer/lr": {
|
"node_modules/@lezer/lr": {
|
||||||
"version": "0.15.2",
|
"version": "0.15.5",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.5.tgz",
|
||||||
|
"integrity": "sha512-DEcLyhdmBxD1foQe7RegLrSlfS/XaTMGLkO5evkzHWAQKh/JnFWp7j7iNB7s2EpxzRrBCh0U+W7JDCeFhv2mng==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lezer/common": "^0.15.0"
|
"@lezer/common": "^0.15.0"
|
||||||
}
|
}
|
||||||
|
@ -1855,9 +1857,10 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/sanitize-html": {
|
"node_modules/@types/sanitize-html": {
|
||||||
"version": "2.5.0",
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-+JLlZdJkIHdgvlFnMorJeLv5WIORNcI+jHsAoPBWMnhGx5Rbz/D1QN5D4qvmoA7fooDlEVy6zlioWSgqbU0KeQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"htmlparser2": "^6.0.0"
|
"htmlparser2": "^6.0.0"
|
||||||
}
|
}
|
||||||
|
@ -4130,12 +4133,6 @@
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/i": {
|
|
||||||
"version": "0.3.7",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ignore": {
|
"node_modules/ignore": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
@ -7244,10 +7241,9 @@
|
||||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||||
"@nexucis/fuzzy": "^0.3.0",
|
"@nexucis/fuzzy": "^0.3.0",
|
||||||
"bootstrap": "^4.6.1",
|
"bootstrap": "^4.6.1",
|
||||||
"codemirror-promql": "0.18.0",
|
"codemirror-promql": "0.19.0",
|
||||||
"css.escape": "^1.5.1",
|
"css.escape": "^1.5.1",
|
||||||
"downshift": "^6.1.7",
|
"downshift": "^6.1.7",
|
||||||
"i": "^0.3.7",
|
|
||||||
"jquery": "^3.5.1",
|
"jquery": "^3.5.1",
|
||||||
"jquery.flot.tooltip": "^0.9.0",
|
"jquery.flot.tooltip": "^0.9.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
|
@ -7277,7 +7273,7 @@
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
"@types/react-resize-detector": "^6.1.0",
|
"@types/react-resize-detector": "^6.1.0",
|
||||||
"@types/react-router-dom": "^5.3.2",
|
"@types/react-router-dom": "^5.3.2",
|
||||||
"@types/sanitize-html": "^2.5.0",
|
"@types/sanitize-html": "^2.6.1",
|
||||||
"@types/sinon": "^10.0.6",
|
"@types/sinon": "^10.0.6",
|
||||||
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
||||||
"enzyme": "^3.11.0",
|
"enzyme": "^3.11.0",
|
||||||
|
@ -27644,9 +27640,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@lezer/common": {
|
"@lezer/common": {
|
||||||
"version": "0.15.10",
|
"version": "0.15.11",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.10.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.11.tgz",
|
||||||
"integrity": "sha512-vlr+be73zTDoQBIknBVOh/633tmbQcjxUu9PIeVeYESeBK3V6TuBW96RRFg93Y2cyK9lglz241gOgSn452HFvA=="
|
"integrity": "sha512-vv0nSdIaVCRcJ8rPuDdsrNVfBOYe/4Szr/LhF929XyDmBndLDuWiCCHooGlGlJfzELyO608AyDhVsuX/ZG36NA=="
|
||||||
},
|
},
|
||||||
"@lezer/generator": {
|
"@lezer/generator": {
|
||||||
"version": "0.15.2",
|
"version": "0.15.2",
|
||||||
|
@ -27657,7 +27653,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@lezer/lr": {
|
"@lezer/lr": {
|
||||||
"version": "0.15.2",
|
"version": "0.15.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.5.tgz",
|
||||||
|
"integrity": "sha512-DEcLyhdmBxD1foQe7RegLrSlfS/XaTMGLkO5evkzHWAQKh/JnFWp7j7iNB7s2EpxzRrBCh0U+W7JDCeFhv2mng==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@lezer/common": "^0.15.0"
|
"@lezer/common": "^0.15.0"
|
||||||
}
|
}
|
||||||
|
@ -27893,7 +27891,9 @@
|
||||||
"version": "0.1.6"
|
"version": "0.1.6"
|
||||||
},
|
},
|
||||||
"@types/sanitize-html": {
|
"@types/sanitize-html": {
|
||||||
"version": "2.5.0",
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-+JLlZdJkIHdgvlFnMorJeLv5WIORNcI+jHsAoPBWMnhGx5Rbz/D1QN5D4qvmoA7fooDlEVy6zlioWSgqbU0KeQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"htmlparser2": "^6.0.0"
|
"htmlparser2": "^6.0.0"
|
||||||
|
@ -28431,17 +28431,18 @@
|
||||||
"@codemirror/lint": "^0.19.3",
|
"@codemirror/lint": "^0.19.3",
|
||||||
"@codemirror/state": "^0.19.6",
|
"@codemirror/state": "^0.19.6",
|
||||||
"@codemirror/view": "^0.19.27",
|
"@codemirror/view": "^0.19.27",
|
||||||
"@lezer/common": "^0.15.10",
|
"@lezer/common": "^0.15.11",
|
||||||
"@lezer/generator": "^0.15.2",
|
"@lezer/generator": "^0.15.2",
|
||||||
|
"@lezer/lr": "^0.15.5",
|
||||||
"@types/chai": "^4.2.22",
|
"@types/chai": "^4.2.22",
|
||||||
"@types/lru-cache": "^5.1.1",
|
"@types/lru-cache": "^5.1.1",
|
||||||
"@types/mocha": "^9.0.0",
|
"@types/mocha": "^9.0.0",
|
||||||
"@types/node": "^16.11.12",
|
"@types/node": "^16.11.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.5.0",
|
"@typescript-eslint/eslint-plugin": "^5.8.0",
|
||||||
"@typescript-eslint/parser": "^5.5.0",
|
"@typescript-eslint/parser": "^5.8.0",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"codecov": "^3.8.3",
|
"codecov": "^3.8.3",
|
||||||
"eslint": "^8.4.0",
|
"eslint": "^8.4.1",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-plugin-flowtype": "^8.0.3",
|
"eslint-plugin-flowtype": "^8.0.3",
|
||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
@ -28487,13 +28488,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/eslint-plugin": {
|
"@typescript-eslint/eslint-plugin": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.8.0.tgz",
|
||||||
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==",
|
"integrity": "sha512-spu1UW7QuBn0nJ6+psnfCc3iVoQAifjKORgBngKOmC8U/1tbe2YJMzYQqDGYB4JCss7L8+RM2kKLb1B1Aw9BNA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/experimental-utils": "5.5.0",
|
"@typescript-eslint/experimental-utils": "5.8.0",
|
||||||
"@typescript-eslint/scope-manager": "5.5.0",
|
"@typescript-eslint/scope-manager": "5.8.0",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"functional-red-black-tree": "^1.0.1",
|
"functional-red-black-tree": "^1.0.1",
|
||||||
"ignore": "^5.1.8",
|
"ignore": "^5.1.8",
|
||||||
|
@ -28509,55 +28510,55 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/experimental-utils": {
|
"@typescript-eslint/experimental-utils": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.8.0.tgz",
|
||||||
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==",
|
"integrity": "sha512-KN5FvNH71bhZ8fKtL+lhW7bjm7cxs1nt+hrDZWIqb6ViCffQcWyLunGrgvISgkRojIDcXIsH+xlFfI4RCDA0xA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/json-schema": "^7.0.9",
|
"@types/json-schema": "^7.0.9",
|
||||||
"@typescript-eslint/scope-manager": "5.5.0",
|
"@typescript-eslint/scope-manager": "5.8.0",
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"@typescript-eslint/typescript-estree": "5.5.0",
|
"@typescript-eslint/typescript-estree": "5.8.0",
|
||||||
"eslint-scope": "^5.1.1",
|
"eslint-scope": "^5.1.1",
|
||||||
"eslint-utils": "^3.0.0"
|
"eslint-utils": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/parser": {
|
"@typescript-eslint/parser": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.8.0.tgz",
|
||||||
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
|
"integrity": "sha512-Gleacp/ZhRtJRYs5/T8KQR3pAQjQI89Dn/k+OzyCKOsLiZH2/Vh60cFBTnFsHNI6WAD+lNUo/xGZ4NeA5u0Ipw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/scope-manager": "5.5.0",
|
"@typescript-eslint/scope-manager": "5.8.0",
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"@typescript-eslint/typescript-estree": "5.5.0",
|
"@typescript-eslint/typescript-estree": "5.8.0",
|
||||||
"debug": "^4.3.2"
|
"debug": "^4.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/scope-manager": {
|
"@typescript-eslint/scope-manager": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.8.0.tgz",
|
||||||
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==",
|
"integrity": "sha512-x82CYJsLOjPCDuFFEbS6e7K1QEWj7u5Wk1alw8A+gnJiYwNnDJk0ib6PCegbaPMjrfBvFKa7SxE3EOnnIQz2Gg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.5.0"
|
"@typescript-eslint/visitor-keys": "5.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/types": {
|
"@typescript-eslint/types": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.8.0.tgz",
|
||||||
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==",
|
"integrity": "sha512-LdCYOqeqZWqCMOmwFnum6YfW9F3nKuxJiR84CdIRN5nfHJ7gyvGpXWqL/AaW0k3Po0+wm93ARAsOdzlZDPCcXg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@typescript-eslint/typescript-estree": {
|
"@typescript-eslint/typescript-estree": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.8.0.tgz",
|
||||||
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==",
|
"integrity": "sha512-srfeZ3URdEcUsSLbkOFqS7WoxOqn8JNil2NSLO9O+I2/Uyc85+UlfpEvQHIpj5dVts7KKOZnftoJD/Fdv0L7nQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.5.0",
|
"@typescript-eslint/visitor-keys": "5.8.0",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"globby": "^11.0.4",
|
"globby": "^11.0.4",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
|
@ -28566,12 +28567,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/visitor-keys": {
|
"@typescript-eslint/visitor-keys": {
|
||||||
"version": "5.5.0",
|
"version": "5.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.8.0.tgz",
|
||||||
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==",
|
"integrity": "sha512-+HDIGOEMnqbxdAHegxvnOqESUH6RWFRR2b8qxP1W9CZnnYh4Usz6MBL+2KMAgPk/P0o9c1HqnYtwzVH6GTIqug==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "5.5.0",
|
"@typescript-eslint/types": "5.8.0",
|
||||||
"eslint-visitor-keys": "^3.0.0"
|
"eslint-visitor-keys": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -28609,9 +28610,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint": {
|
"eslint": {
|
||||||
"version": "8.4.0",
|
"version": "8.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz",
|
||||||
"integrity": "sha512-kv0XQcAQJL/VD9THQKhTQZVqkJKA+tIj/v2ZKNaIHRAADcJWFb+B/BAewUYuF6UVg1s2xC5qXVoDk0G8sKGeTA==",
|
"integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@eslint/eslintrc": "^1.0.5",
|
"@eslint/eslintrc": "^1.0.5",
|
||||||
|
@ -29692,11 +29693,11 @@
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
"@types/react-resize-detector": "^6.1.0",
|
"@types/react-resize-detector": "^6.1.0",
|
||||||
"@types/react-router-dom": "^5.3.2",
|
"@types/react-router-dom": "^5.3.2",
|
||||||
"@types/sanitize-html": "^2.5.0",
|
"@types/sanitize-html": "^2.6.1",
|
||||||
"@types/sinon": "^10.0.6",
|
"@types/sinon": "^10.0.6",
|
||||||
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
||||||
"bootstrap": "^4.6.1",
|
"bootstrap": "^4.6.1",
|
||||||
"codemirror-promql": "0.18.0",
|
"codemirror-promql": "0.19.0",
|
||||||
"css.escape": "^1.5.1",
|
"css.escape": "^1.5.1",
|
||||||
"downshift": "^6.1.7",
|
"downshift": "^6.1.7",
|
||||||
"enzyme": "^3.11.0",
|
"enzyme": "^3.11.0",
|
||||||
|
@ -29705,7 +29706,6 @@
|
||||||
"eslint-config-react-app": "^6.0.0",
|
"eslint-config-react-app": "^6.0.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"fsevents": "^2.3.2",
|
"fsevents": "^2.3.2",
|
||||||
"i": "^0.3.7",
|
|
||||||
"jest-canvas-mock": "^2.3.1",
|
"jest-canvas-mock": "^2.3.1",
|
||||||
"jest-fetch-mock": "^3.0.3",
|
"jest-fetch-mock": "^3.0.3",
|
||||||
"jquery": "^3.5.1",
|
"jquery": "^3.5.1",
|
||||||
|
@ -43287,9 +43287,6 @@
|
||||||
"debug": "4"
|
"debug": "4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"i": {
|
|
||||||
"version": "0.3.7"
|
|
||||||
},
|
|
||||||
"ignore": {
|
"ignore": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
|
|
@ -21,10 +21,9 @@
|
||||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||||
"@nexucis/fuzzy": "^0.3.0",
|
"@nexucis/fuzzy": "^0.3.0",
|
||||||
"bootstrap": "^4.6.1",
|
"bootstrap": "^4.6.1",
|
||||||
"codemirror-promql": "0.18.0",
|
"codemirror-promql": "0.19.0",
|
||||||
"css.escape": "^1.5.1",
|
"css.escape": "^1.5.1",
|
||||||
"downshift": "^6.1.7",
|
"downshift": "^6.1.7",
|
||||||
"i": "^0.3.7",
|
|
||||||
"jquery": "^3.5.1",
|
"jquery": "^3.5.1",
|
||||||
"jquery.flot.tooltip": "^0.9.0",
|
"jquery.flot.tooltip": "^0.9.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
|
@ -75,7 +74,7 @@
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
"@types/react-resize-detector": "^6.1.0",
|
"@types/react-resize-detector": "^6.1.0",
|
||||||
"@types/react-router-dom": "^5.3.2",
|
"@types/react-router-dom": "^5.3.2",
|
||||||
"@types/sanitize-html": "^2.5.0",
|
"@types/sanitize-html": "^2.6.1",
|
||||||
"@types/sinon": "^10.0.6",
|
"@types/sinon": "^10.0.6",
|
||||||
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
||||||
"enzyme": "^3.11.0",
|
"enzyme": "^3.11.0",
|
||||||
|
|
|
@ -103,7 +103,7 @@ const App: FC<AppProps> = ({ consolesLink, agentMode }) => {
|
||||||
<ServiceDiscoveryPage />
|
<ServiceDiscoveryPage />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/status">
|
<Route path="/status">
|
||||||
<StatusPage />
|
<StatusPage agentMode={agentMode} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/tsdb-status">
|
<Route path="/tsdb-status">
|
||||||
<TSDBStatusPage />
|
<TSDBStatusPage />
|
||||||
|
|
|
@ -6,7 +6,7 @@ const Agent: FC = () => {
|
||||||
<h2>Prometheus Agent</h2>
|
<h2>Prometheus Agent</h2>
|
||||||
<p>
|
<p>
|
||||||
This Prometheus instance is running in <strong>agent mode</strong>. In this mode, Prometheus is only used to scrape
|
This Prometheus instance is running in <strong>agent mode</strong>. In this mode, Prometheus is only used to scrape
|
||||||
discovered targets and forward them to remote write endpoints.
|
discovered targets and forward the scraped metrics to remote write endpoints.
|
||||||
</p>
|
</p>
|
||||||
<p>Some features are not available in this mode, such as querying and alerting.</p>
|
<p>Some features are not available in this mode, such as querying and alerting.</p>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -83,28 +83,35 @@ const StatusWithStatusIndicator = withStatusIndicator(StatusContent);
|
||||||
|
|
||||||
StatusContent.displayName = 'Status';
|
StatusContent.displayName = 'Status';
|
||||||
|
|
||||||
const Status: FC = () => {
|
const StatusResult: FC<{ fetchPath: string; title: string }> = ({ fetchPath, title }) => {
|
||||||
|
const { response, isLoading, error } = useFetch(fetchPath);
|
||||||
|
return (
|
||||||
|
<StatusWithStatusIndicator
|
||||||
|
key={title}
|
||||||
|
data={response.data}
|
||||||
|
title={title}
|
||||||
|
isLoading={isLoading}
|
||||||
|
error={error}
|
||||||
|
componentTitle={title}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Status: FC<{ agentMode: boolean }> = ({ agentMode }) => {
|
||||||
const pathPrefix = usePathPrefix();
|
const pathPrefix = usePathPrefix();
|
||||||
const path = `${pathPrefix}/${API_PATH}`;
|
const path = `${pathPrefix}/${API_PATH}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{[
|
{[
|
||||||
{ fetchResult: useFetch<Record<string, string>>(`${path}/status/runtimeinfo`), title: 'Runtime Information' },
|
{ fetchPath: `${path}/status/runtimeinfo`, title: 'Runtime Information' },
|
||||||
{ fetchResult: useFetch<Record<string, string>>(`${path}/status/buildinfo`), title: 'Build Information' },
|
{ fetchPath: `${path}/status/buildinfo`, title: 'Build Information' },
|
||||||
{ fetchResult: useFetch<Record<string, string>>(`${path}/alertmanagers`), title: 'Alertmanagers' },
|
{ fetchPath: `${path}/alertmanagers`, title: 'Alertmanagers' },
|
||||||
].map(({ fetchResult, title }) => {
|
].map(({ fetchPath, title }) => {
|
||||||
const { response, isLoading, error } = fetchResult;
|
if (agentMode && title === 'Alertmanagers') {
|
||||||
return (
|
return null;
|
||||||
<StatusWithStatusIndicator
|
}
|
||||||
key={title}
|
return <StatusResult fetchPath={fetchPath} title={title} />;
|
||||||
data={response.data}
|
|
||||||
title={title}
|
|
||||||
isLoading={isLoading}
|
|
||||||
error={error}
|
|
||||||
componentTitle={title}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
100
web/web_test.go
100
web/web_test.go
|
@ -116,7 +116,9 @@ func TestReadyAndHealthy(t *testing.T) {
|
||||||
|
|
||||||
db, err := tsdb.Open(dbDir, nil, nil, nil, nil)
|
db, err := tsdb.Open(dbDir, nil, nil, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
require.NoError(t, db.Close())
|
||||||
|
})
|
||||||
port := fmt.Sprintf(":%d", testutil.RandomUnprivilegedPort(t))
|
port := fmt.Sprintf(":%d", testutil.RandomUnprivilegedPort(t))
|
||||||
|
|
||||||
opts := &Options{
|
opts := &Options{
|
||||||
|
@ -237,6 +239,9 @@ func TestRoutePrefix(t *testing.T) {
|
||||||
|
|
||||||
db, err := tsdb.Open(dbDir, nil, nil, nil, nil)
|
db, err := tsdb.Open(dbDir, nil, nil, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
require.NoError(t, db.Close())
|
||||||
|
})
|
||||||
|
|
||||||
port := fmt.Sprintf(":%d", testutil.RandomUnprivilegedPort(t))
|
port := fmt.Sprintf(":%d", testutil.RandomUnprivilegedPort(t))
|
||||||
|
|
||||||
|
@ -404,7 +409,9 @@ func TestShutdownWithStaleConnection(t *testing.T) {
|
||||||
|
|
||||||
db, err := tsdb.Open(dbDir, nil, nil, nil, nil)
|
db, err := tsdb.Open(dbDir, nil, nil, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
require.NoError(t, db.Close())
|
||||||
|
})
|
||||||
timeout := 10 * time.Second
|
timeout := 10 * time.Second
|
||||||
|
|
||||||
port := fmt.Sprintf(":%d", testutil.RandomUnprivilegedPort(t))
|
port := fmt.Sprintf(":%d", testutil.RandomUnprivilegedPort(t))
|
||||||
|
@ -567,39 +574,68 @@ func TestAgentAPIEndPoints(t *testing.T) {
|
||||||
|
|
||||||
webHandler := New(nil, opts)
|
webHandler := New(nil, opts)
|
||||||
webHandler.Ready()
|
webHandler.Ready()
|
||||||
|
webHandler.config = &config.Config{}
|
||||||
baseURL := "http://localhost" + port
|
webHandler.notifier = ¬ifier.Manager{}
|
||||||
|
l, err := webHandler.Listener()
|
||||||
// Test for non-available endpoints in the Agent mode.
|
if err != nil {
|
||||||
for _, u := range []string{
|
panic(fmt.Sprintf("Unable to start web listener: %s", err))
|
||||||
"/-/labels",
|
|
||||||
"/label",
|
|
||||||
"/series",
|
|
||||||
"/alertmanagers",
|
|
||||||
"/query",
|
|
||||||
"/query_range",
|
|
||||||
"/query_exemplars",
|
|
||||||
"/graph",
|
|
||||||
"/rules",
|
|
||||||
} {
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
req, err := http.NewRequest("GET", baseURL+u, nil)
|
|
||||||
require.NoError(t, err)
|
|
||||||
webHandler.router.ServeHTTP(w, req)
|
|
||||||
require.Equal(t, http.StatusNotFound, w.Code)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for available endpoints in the Agent mode.
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
for _, u := range []string{
|
defer cancel()
|
||||||
"/agent",
|
go func() {
|
||||||
"/targets",
|
err := webHandler.Run(ctx, l, "")
|
||||||
"/status",
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("Can't start web handler:%s", err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Give some time for the web goroutine to run since we need the server
|
||||||
|
// to be up before starting tests.
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
baseURL := "http://localhost" + port + "/api/v1"
|
||||||
|
|
||||||
|
// Test for non-available endpoints in the Agent mode.
|
||||||
|
for path, methods := range map[string][]string{
|
||||||
|
"/labels": {http.MethodGet, http.MethodPost},
|
||||||
|
"/label/:name/values": {http.MethodGet},
|
||||||
|
"/series": {http.MethodGet, http.MethodPost, http.MethodDelete},
|
||||||
|
"/alertmanagers": {http.MethodGet},
|
||||||
|
"/query": {http.MethodGet, http.MethodPost},
|
||||||
|
"/query_range": {http.MethodGet, http.MethodPost},
|
||||||
|
"/query_exemplars": {http.MethodGet, http.MethodPost},
|
||||||
|
"/status/tsdb": {http.MethodGet},
|
||||||
|
"/alerts": {http.MethodGet},
|
||||||
|
"/rules": {http.MethodGet},
|
||||||
|
"/admin/tsdb/delete_series": {http.MethodPost, http.MethodPut},
|
||||||
|
"/admin/tsdb/clean_tombstones": {http.MethodPost, http.MethodPut},
|
||||||
|
"/admin/tsdb/snapshot": {http.MethodPost, http.MethodPut},
|
||||||
} {
|
} {
|
||||||
w := httptest.NewRecorder()
|
for _, m := range methods {
|
||||||
req, err := http.NewRequest("GET", baseURL+u, nil)
|
req, err := http.NewRequest(m, baseURL+path, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
webHandler.router.ServeHTTP(w, req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
require.Equal(t, http.StatusOK, w.Code)
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, http.StatusUnprocessableEntity, resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for some of available endpoints in the Agent mode.
|
||||||
|
for path, methods := range map[string][]string{
|
||||||
|
"/targets": {http.MethodGet},
|
||||||
|
"/targets/metadata": {http.MethodGet},
|
||||||
|
"/metadata": {http.MethodGet},
|
||||||
|
"/status/config": {http.MethodGet},
|
||||||
|
"/status/runtimeinfo": {http.MethodGet},
|
||||||
|
"/status/flags": {http.MethodGet},
|
||||||
|
} {
|
||||||
|
for _, m := range methods {
|
||||||
|
req, err := http.NewRequest(m, baseURL+path, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue