Merge remote-tracking branch 'upstream/main'

Minor conflicts:
rules/manager.go
tsdb/compact.go
tsdb/db.go
go.mod
This commit is contained in:
Jeanette Tan 2023-07-19 21:28:28 +08:00
commit 8035c04624
69 changed files with 1657 additions and 833 deletions

View file

@ -1,7 +1,7 @@
<!-- <!--
Don't forget! Don't forget!
- Please sign CNCF's Developer Certificate of Origin and sign-off your commits by adding the -s / --sign-off flag to `git commit`. See https://github.com/apps/dco for more information. - Please sign CNCF's Developer Certificate of Origin and sign-off your commits by adding the -s / --signoff flag to `git commit`. See https://github.com/apps/dco for more information.
- If the PR adds or changes a behaviour or fixes a bug of an exported API it would need a unit/e2e test. - If the PR adds or changes a behaviour or fixes a bug of an exported API it would need a unit/e2e test.

View file

@ -55,7 +55,7 @@ ifneq ($(shell command -v gotestsum > /dev/null),)
endif endif
endif endif
PROMU_VERSION ?= 0.14.0 PROMU_VERSION ?= 0.15.0
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
SKIP_GOLANGCI_LINT := SKIP_GOLANGCI_LINT :=

View file

@ -71,6 +71,7 @@ import (
"github.com/prometheus/prometheus/tracing" "github.com/prometheus/prometheus/tracing"
"github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb"
"github.com/prometheus/prometheus/tsdb/agent" "github.com/prometheus/prometheus/tsdb/agent"
"github.com/prometheus/prometheus/tsdb/wlog"
"github.com/prometheus/prometheus/util/documentcli" "github.com/prometheus/prometheus/util/documentcli"
"github.com/prometheus/prometheus/util/logging" "github.com/prometheus/prometheus/util/logging"
prom_runtime "github.com/prometheus/prometheus/util/runtime" prom_runtime "github.com/prometheus/prometheus/util/runtime"
@ -334,6 +335,9 @@ func main() {
serverOnlyFlag(a, "storage.tsdb.wal-compression", "Compress the tsdb WAL."). serverOnlyFlag(a, "storage.tsdb.wal-compression", "Compress the tsdb WAL.").
Hidden().Default("true").BoolVar(&cfg.tsdb.WALCompression) Hidden().Default("true").BoolVar(&cfg.tsdb.WALCompression)
serverOnlyFlag(a, "storage.tsdb.wal-compression-type", "Compression algorithm for the tsdb WAL.").
Hidden().Default(string(wlog.CompressionSnappy)).EnumVar(&cfg.tsdb.WALCompressionType, string(wlog.CompressionSnappy), string(wlog.CompressionZstd))
serverOnlyFlag(a, "storage.tsdb.head-chunks-write-queue-size", "Size of the queue through which head chunks are written to the disk to be m-mapped, 0 disables the queue completely. Experimental."). serverOnlyFlag(a, "storage.tsdb.head-chunks-write-queue-size", "Size of the queue through which head chunks are written to the disk to be m-mapped, 0 disables the queue completely. Experimental.").
Default("0").IntVar(&cfg.tsdb.HeadChunksWriteQueueSize) Default("0").IntVar(&cfg.tsdb.HeadChunksWriteQueueSize)
@ -350,6 +354,9 @@ func main() {
agentOnlyFlag(a, "storage.agent.wal-compression", "Compress the agent WAL."). agentOnlyFlag(a, "storage.agent.wal-compression", "Compress the agent WAL.").
Default("true").BoolVar(&cfg.agent.WALCompression) Default("true").BoolVar(&cfg.agent.WALCompression)
agentOnlyFlag(a, "storage.agent.wal-compression-type", "Compression algorithm for the agent WAL.").
Hidden().Default(string(wlog.CompressionSnappy)).EnumVar(&cfg.agent.WALCompressionType, string(wlog.CompressionSnappy), string(wlog.CompressionZstd))
agentOnlyFlag(a, "storage.agent.wal-truncate-frequency", agentOnlyFlag(a, "storage.agent.wal-truncate-frequency",
"The frequency at which to truncate the WAL and remove old data."). "The frequency at which to truncate the WAL and remove old data.").
Hidden().PlaceHolder("<duration>").SetValue(&cfg.agent.TruncateFrequency) Hidden().PlaceHolder("<duration>").SetValue(&cfg.agent.TruncateFrequency)
@ -1546,6 +1553,7 @@ type tsdbOptions struct {
MaxBytes units.Base2Bytes MaxBytes units.Base2Bytes
NoLockfile bool NoLockfile bool
WALCompression bool WALCompression bool
WALCompressionType string
HeadChunksWriteQueueSize int HeadChunksWriteQueueSize int
SamplesPerChunk int SamplesPerChunk int
StripeSize int StripeSize int
@ -1566,7 +1574,7 @@ func (opts tsdbOptions) ToTSDBOptions() tsdb.Options {
MaxBytes: int64(opts.MaxBytes), MaxBytes: int64(opts.MaxBytes),
NoLockfile: opts.NoLockfile, NoLockfile: opts.NoLockfile,
AllowOverlappingCompaction: true, AllowOverlappingCompaction: true,
WALCompression: opts.WALCompression, WALCompression: wlog.ParseCompressionType(opts.WALCompression, opts.WALCompressionType),
HeadChunksWriteQueueSize: opts.HeadChunksWriteQueueSize, HeadChunksWriteQueueSize: opts.HeadChunksWriteQueueSize,
SamplesPerChunk: opts.SamplesPerChunk, SamplesPerChunk: opts.SamplesPerChunk,
StripeSize: opts.StripeSize, StripeSize: opts.StripeSize,
@ -1585,6 +1593,7 @@ func (opts tsdbOptions) ToTSDBOptions() tsdb.Options {
type agentOptions struct { type agentOptions struct {
WALSegmentSize units.Base2Bytes WALSegmentSize units.Base2Bytes
WALCompression bool WALCompression bool
WALCompressionType string
StripeSize int StripeSize int
TruncateFrequency model.Duration TruncateFrequency model.Duration
MinWALTime, MaxWALTime model.Duration MinWALTime, MaxWALTime model.Duration
@ -1594,7 +1603,7 @@ type agentOptions struct {
func (opts agentOptions) ToAgentOptions() agent.Options { func (opts agentOptions) ToAgentOptions() agent.Options {
return agent.Options{ return agent.Options{
WALSegmentSize: int(opts.WALSegmentSize), WALSegmentSize: int(opts.WALSegmentSize),
WALCompression: opts.WALCompression, WALCompression: wlog.ParseCompressionType(opts.WALCompression, opts.WALCompressionType),
StripeSize: opts.StripeSize, StripeSize: opts.StripeSize,
TruncateFrequency: time.Duration(opts.TruncateFrequency), TruncateFrequency: time.Duration(opts.TruncateFrequency),
MinWALTime: durationToInt64Millis(time.Duration(opts.MinWALTime)), MinWALTime: durationToInt64Millis(time.Duration(opts.MinWALTime)),

View file

@ -58,6 +58,7 @@ import (
"github.com/prometheus/prometheus/notifier" "github.com/prometheus/prometheus/notifier"
_ "github.com/prometheus/prometheus/plugins" // Register plugins. _ "github.com/prometheus/prometheus/plugins" // Register plugins.
"github.com/prometheus/prometheus/promql" "github.com/prometheus/prometheus/promql"
"github.com/prometheus/prometheus/promql/parser"
"github.com/prometheus/prometheus/scrape" "github.com/prometheus/prometheus/scrape"
"github.com/prometheus/prometheus/util/documentcli" "github.com/prometheus/prometheus/util/documentcli"
) )
@ -91,6 +92,8 @@ func main() {
checkCmd := app.Command("check", "Check the resources for validity.") checkCmd := app.Command("check", "Check the resources for validity.")
experimental := app.Flag("experimental", "Enable experimental commands.").Bool()
sdCheckCmd := checkCmd.Command("service-discovery", "Perform service discovery for the given job name and report the results, including relabeling.") sdCheckCmd := checkCmd.Command("service-discovery", "Perform service discovery for the given job name and report the results, including relabeling.")
sdConfigFile := sdCheckCmd.Arg("config-file", "The prometheus config file.").Required().ExistingFile() sdConfigFile := sdCheckCmd.Arg("config-file", "The prometheus config file.").Required().ExistingFile()
sdJobName := sdCheckCmd.Arg("job", "The job to run service discovery for.").Required().String() sdJobName := sdCheckCmd.Arg("job", "The job to run service discovery for.").Required().String()
@ -245,6 +248,22 @@ func main() {
"A list of one or more files containing recording rules to be backfilled. All recording rules listed in the files will be backfilled. Alerting rules are not evaluated.", "A list of one or more files containing recording rules to be backfilled. All recording rules listed in the files will be backfilled. Alerting rules are not evaluated.",
).Required().ExistingFiles() ).Required().ExistingFiles()
promQLCmd := app.Command("promql", "PromQL formatting and editing. Requires the --experimental flag.")
promQLFormatCmd := promQLCmd.Command("format", "Format PromQL query to pretty printed form.")
promQLFormatQuery := promQLFormatCmd.Arg("query", "PromQL query.").Required().String()
promQLLabelsCmd := promQLCmd.Command("label-matchers", "Edit label matchers contained within an existing PromQL query.")
promQLLabelsSetCmd := promQLLabelsCmd.Command("set", "Set a label matcher in the query.")
promQLLabelsSetType := promQLLabelsSetCmd.Flag("type", "Type of the label matcher to set.").Short('t').Default("=").Enum("=", "!=", "=~", "!~")
promQLLabelsSetQuery := promQLLabelsSetCmd.Arg("query", "PromQL query.").Required().String()
promQLLabelsSetName := promQLLabelsSetCmd.Arg("name", "Name of the label matcher to set.").Required().String()
promQLLabelsSetValue := promQLLabelsSetCmd.Arg("value", "Value of the label matcher to set.").Required().String()
promQLLabelsDeleteCmd := promQLLabelsCmd.Command("delete", "Delete a label from the query.")
promQLLabelsDeleteQuery := promQLLabelsDeleteCmd.Arg("query", "PromQL query.").Required().String()
promQLLabelsDeleteName := promQLLabelsDeleteCmd.Arg("name", "Name of the label to delete.").Required().String()
featureList := app.Flag("enable-feature", "Comma separated feature names to enable (only PromQL related and no-default-scrape-port). See https://prometheus.io/docs/prometheus/latest/feature_flags/ for the options and more details.").Default("").Strings() featureList := app.Flag("enable-feature", "Comma separated feature names to enable (only PromQL related and no-default-scrape-port). See https://prometheus.io/docs/prometheus/latest/feature_flags/ for the options and more details.").Default("").Strings()
documentationCmd := app.Command("write-documentation", "Generate command line documentation. Internal use.").Hidden() documentationCmd := app.Command("write-documentation", "Generate command line documentation. Internal use.").Hidden()
@ -364,8 +383,28 @@ func main() {
case importRulesCmd.FullCommand(): case importRulesCmd.FullCommand():
os.Exit(checkErr(importRules(serverURL, httpRoundTripper, *importRulesStart, *importRulesEnd, *importRulesOutputDir, *importRulesEvalInterval, *maxBlockDuration, *importRulesFiles...))) os.Exit(checkErr(importRules(serverURL, httpRoundTripper, *importRulesStart, *importRulesEnd, *importRulesOutputDir, *importRulesEvalInterval, *maxBlockDuration, *importRulesFiles...)))
case documentationCmd.FullCommand(): case documentationCmd.FullCommand():
os.Exit(checkErr(documentcli.GenerateMarkdown(app.Model(), os.Stdout))) os.Exit(checkErr(documentcli.GenerateMarkdown(app.Model(), os.Stdout)))
case promQLFormatCmd.FullCommand():
checkExperimental(*experimental)
os.Exit(checkErr(formatPromQL(*promQLFormatQuery)))
case promQLLabelsSetCmd.FullCommand():
checkExperimental(*experimental)
os.Exit(checkErr(labelsSetPromQL(*promQLLabelsSetQuery, *promQLLabelsSetType, *promQLLabelsSetName, *promQLLabelsSetValue)))
case promQLLabelsDeleteCmd.FullCommand():
checkExperimental(*experimental)
os.Exit(checkErr(labelsDeletePromQL(*promQLLabelsDeleteQuery, *promQLLabelsDeleteName)))
}
}
func checkExperimental(f bool) {
if !f {
fmt.Fprintln(os.Stderr, "This command is experimental and requires the --experimental flag to be set.")
os.Exit(1)
} }
} }
@ -1375,3 +1414,79 @@ func checkTargetGroupsForScrapeConfig(targetGroups []*targetgroup.Group, scfg *c
return nil return nil
} }
func formatPromQL(query string) error {
expr, err := parser.ParseExpr(query)
if err != nil {
return err
}
fmt.Println(expr.Pretty(0))
return nil
}
func labelsSetPromQL(query, labelMatchType, name, value string) error {
expr, err := parser.ParseExpr(query)
if err != nil {
return err
}
var matchType labels.MatchType
switch labelMatchType {
case parser.ItemType(parser.EQL).String():
matchType = labels.MatchEqual
case parser.ItemType(parser.NEQ).String():
matchType = labels.MatchNotEqual
case parser.ItemType(parser.EQL_REGEX).String():
matchType = labels.MatchRegexp
case parser.ItemType(parser.NEQ_REGEX).String():
matchType = labels.MatchNotRegexp
default:
return fmt.Errorf("invalid label match type: %s", labelMatchType)
}
parser.Inspect(expr, func(node parser.Node, path []parser.Node) error {
if n, ok := node.(*parser.VectorSelector); ok {
var found bool
for i, l := range n.LabelMatchers {
if l.Name == name {
n.LabelMatchers[i].Type = matchType
n.LabelMatchers[i].Value = value
found = true
}
}
if !found {
n.LabelMatchers = append(n.LabelMatchers, &labels.Matcher{
Type: matchType,
Name: name,
Value: value,
})
}
}
return nil
})
fmt.Println(expr.Pretty(0))
return nil
}
func labelsDeletePromQL(query, name string) error {
expr, err := parser.ParseExpr(query)
if err != nil {
return err
}
parser.Inspect(expr, func(node parser.Node, path []parser.Node) error {
if n, ok := node.(*parser.VectorSelector); ok {
for i, l := range n.LabelMatchers {
if l.Name == name {
n.LabelMatchers = append(n.LabelMatchers[:i], n.LabelMatchers[i+1:]...)
}
}
}
return nil
})
fmt.Println(expr.Pretty(0))
return nil
}

View file

@ -23,26 +23,25 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"runtime/pprof" "runtime/pprof"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"text/tabwriter" "text/tabwriter"
"time" "time"
"github.com/prometheus/prometheus/promql/parser"
"github.com/prometheus/prometheus/storage"
"github.com/prometheus/prometheus/tsdb/chunkenc"
"github.com/prometheus/prometheus/tsdb/index"
"github.com/alecthomas/units" "github.com/alecthomas/units"
"github.com/go-kit/log" "github.com/go-kit/log"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/promql/parser"
"github.com/prometheus/prometheus/storage"
"github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb"
"github.com/prometheus/prometheus/tsdb/chunkenc"
"github.com/prometheus/prometheus/tsdb/chunks" "github.com/prometheus/prometheus/tsdb/chunks"
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors" tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
"github.com/prometheus/prometheus/tsdb/fileutil" "github.com/prometheus/prometheus/tsdb/fileutil"
"github.com/prometheus/prometheus/tsdb/index"
) )
const timeDelta = 30000 const timeDelta = 30000
@ -447,7 +446,7 @@ func analyzeBlock(path, blockID string, limit int, runExtended bool) error {
postingInfos := []postingInfo{} postingInfos := []postingInfo{}
printInfo := func(postingInfos []postingInfo) { printInfo := func(postingInfos []postingInfo) {
sort.Slice(postingInfos, func(i, j int) bool { return postingInfos[i].metric > postingInfos[j].metric }) slices.SortFunc(postingInfos, func(a, b postingInfo) bool { return a.metric > b.metric })
for i, pc := range postingInfos { for i, pc := range postingInfos {
if i >= limit { if i >= limit {

View file

@ -22,7 +22,7 @@ import (
"time" "time"
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/hetznercloud/hcloud-go/hcloud" "github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/prometheus/common/config" "github.com/prometheus/common/config"
"github.com/prometheus/common/model" "github.com/prometheus/common/model"
"github.com/prometheus/common/version" "github.com/prometheus/common/version"

View file

@ -20,7 +20,7 @@ import (
"time" "time"
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/hetznercloud/hcloud-go/hcloud" "github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/prometheus/common/config" "github.com/prometheus/common/config"
"github.com/prometheus/common/model" "github.com/prometheus/common/model"

View file

@ -29,7 +29,6 @@ import (
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"github.com/prometheus/prometheus/discovery/targetgroup" "github.com/prometheus/prometheus/discovery/targetgroup"
"github.com/prometheus/prometheus/util/strutil"
) )
var ( var (
@ -248,9 +247,6 @@ func endpointsSourceFromNamespaceAndName(namespace, name string) string {
} }
const ( const (
endpointsLabelPrefix = metaLabelPrefix + "endpoints_label_"
endpointsLabelPresentPrefix = metaLabelPrefix + "endpoints_labelpresent_"
endpointsNameLabel = metaLabelPrefix + "endpoints_name"
endpointNodeName = metaLabelPrefix + "endpoint_node_name" endpointNodeName = metaLabelPrefix + "endpoint_node_name"
endpointHostname = metaLabelPrefix + "endpoint_hostname" endpointHostname = metaLabelPrefix + "endpoint_hostname"
endpointReadyLabel = metaLabelPrefix + "endpoint_ready" endpointReadyLabel = metaLabelPrefix + "endpoint_ready"
@ -265,16 +261,11 @@ func (e *Endpoints) buildEndpoints(eps *apiv1.Endpoints) *targetgroup.Group {
Source: endpointsSource(eps), Source: endpointsSource(eps),
} }
tg.Labels = model.LabelSet{ tg.Labels = model.LabelSet{
namespaceLabel: lv(eps.Namespace), namespaceLabel: lv(eps.Namespace),
endpointsNameLabel: lv(eps.Name),
} }
e.addServiceLabels(eps.Namespace, eps.Name, tg) e.addServiceLabels(eps.Namespace, eps.Name, tg)
// Add endpoints labels metadata. // Add endpoints labels metadata.
for k, v := range eps.Labels { addObjectMetaLabels(tg.Labels, eps.ObjectMeta, RoleEndpoint)
ln := strutil.SanitizeLabelName(k)
tg.Labels[model.LabelName(endpointsLabelPrefix+ln)] = lv(v)
tg.Labels[model.LabelName(endpointsLabelPresentPrefix+ln)] = presentValue
}
type podEntry struct { type podEntry struct {
pod *apiv1.Pod pod *apiv1.Pod
@ -465,14 +456,7 @@ func addNodeLabels(tg model.LabelSet, nodeInf cache.SharedInformer, logger log.L
node := obj.(*apiv1.Node) node := obj.(*apiv1.Node)
// Allocate one target label for the node name, // Allocate one target label for the node name,
// and two target labels for each node label. nodeLabelset := make(model.LabelSet)
nodeLabelset := make(model.LabelSet, 1+2*len(node.GetLabels())) addObjectMetaLabels(nodeLabelset, node.ObjectMeta, RoleNode)
nodeLabelset[nodeNameLabel] = lv(*nodeName)
for k, v := range node.GetLabels() {
ln := strutil.SanitizeLabelName(k)
nodeLabelset[model.LabelName(nodeLabelPrefix+ln)] = lv(v)
nodeLabelset[model.LabelName(nodeLabelPresentPrefix+ln)] = presentValue
}
return tg.Merge(nodeLabelset) return tg.Merge(nodeLabelset)
} }

View file

@ -32,6 +32,9 @@ func makeEndpoints() *v1.Endpoints {
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "testendpoints", Name: "testendpoints",
Namespace: "default", Namespace: "default",
Annotations: map[string]string{
"test.annotation": "test",
},
}, },
Subsets: []v1.EndpointSubset{ Subsets: []v1.EndpointSubset{
{ {
@ -134,8 +137,10 @@ func TestEndpointsDiscoveryBeforeRun(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_namespace": "default",
"__meta_kubernetes_endpoints_name": "testendpoints", "__meta_kubernetes_endpoints_name": "testendpoints",
"__meta_kubernetes_endpoints_annotation_test_annotation": "test",
"__meta_kubernetes_endpoints_annotationpresent_test_annotation": "true",
}, },
Source: "endpoints/default/testendpoints", Source: "endpoints/default/testendpoints",
}, },
@ -434,11 +439,13 @@ func TestEndpointsDiscoveryWithService(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_namespace": "default",
"__meta_kubernetes_endpoints_name": "testendpoints", "__meta_kubernetes_endpoints_name": "testendpoints",
"__meta_kubernetes_service_label_app_name": "test", "__meta_kubernetes_service_label_app_name": "test",
"__meta_kubernetes_service_labelpresent_app_name": "true", "__meta_kubernetes_service_labelpresent_app_name": "true",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_service_name": "testendpoints",
"__meta_kubernetes_endpoints_annotation_test_annotation": "test",
"__meta_kubernetes_endpoints_annotationpresent_test_annotation": "true",
}, },
Source: "endpoints/default/testendpoints", Source: "endpoints/default/testendpoints",
}, },
@ -510,13 +517,15 @@ func TestEndpointsDiscoveryWithServiceUpdate(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_namespace": "default",
"__meta_kubernetes_endpoints_name": "testendpoints", "__meta_kubernetes_endpoints_name": "testendpoints",
"__meta_kubernetes_service_label_app_name": "svc", "__meta_kubernetes_service_label_app_name": "svc",
"__meta_kubernetes_service_labelpresent_app_name": "true", "__meta_kubernetes_service_labelpresent_app_name": "true",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_service_name": "testendpoints",
"__meta_kubernetes_service_label_component": "testing", "__meta_kubernetes_service_label_component": "testing",
"__meta_kubernetes_service_labelpresent_component": "true", "__meta_kubernetes_service_labelpresent_component": "true",
"__meta_kubernetes_endpoints_annotation_test_annotation": "test",
"__meta_kubernetes_endpoints_annotationpresent_test_annotation": "true",
}, },
Source: "endpoints/default/testendpoints", Source: "endpoints/default/testendpoints",
}, },
@ -583,11 +592,13 @@ func TestEndpointsDiscoveryWithNodeMetadata(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_namespace": "default",
"__meta_kubernetes_endpoints_name": "testendpoints", "__meta_kubernetes_endpoints_name": "testendpoints",
"__meta_kubernetes_service_label_app_name": "test", "__meta_kubernetes_service_label_app_name": "test",
"__meta_kubernetes_service_labelpresent_app_name": "true", "__meta_kubernetes_service_labelpresent_app_name": "true",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_service_name": "testendpoints",
"__meta_kubernetes_endpoints_annotation_test_annotation": "test",
"__meta_kubernetes_endpoints_annotationpresent_test_annotation": "true",
}, },
Source: "endpoints/default/testendpoints", Source: "endpoints/default/testendpoints",
}, },
@ -658,11 +669,13 @@ func TestEndpointsDiscoveryWithUpdatedNodeMetadata(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_namespace": "default",
"__meta_kubernetes_endpoints_name": "testendpoints", "__meta_kubernetes_endpoints_name": "testendpoints",
"__meta_kubernetes_service_label_app_name": "test", "__meta_kubernetes_service_label_app_name": "test",
"__meta_kubernetes_service_labelpresent_app_name": "true", "__meta_kubernetes_service_labelpresent_app_name": "true",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_service_name": "testendpoints",
"__meta_kubernetes_endpoints_annotation_test_annotation": "test",
"__meta_kubernetes_endpoints_annotationpresent_test_annotation": "true",
}, },
Source: "endpoints/default/testendpoints", Source: "endpoints/default/testendpoints",
}, },
@ -777,11 +790,13 @@ func TestEndpointsDiscoveryNamespaces(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_namespace": "ns1", "__meta_kubernetes_namespace": "ns1",
"__meta_kubernetes_endpoints_name": "testendpoints", "__meta_kubernetes_endpoints_name": "testendpoints",
"__meta_kubernetes_service_label_app": "app1", "__meta_kubernetes_endpoints_annotation_test_annotation": "test",
"__meta_kubernetes_service_labelpresent_app": "true", "__meta_kubernetes_endpoints_annotationpresent_test_annotation": "true",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_service_label_app": "app1",
"__meta_kubernetes_service_labelpresent_app": "true",
"__meta_kubernetes_service_name": "testendpoints",
}, },
Source: "endpoints/ns1/testendpoints", Source: "endpoints/ns1/testendpoints",
}, },
@ -901,8 +916,10 @@ func TestEndpointsDiscoveryOwnNamespace(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_namespace": "own-ns", "__meta_kubernetes_namespace": "own-ns",
"__meta_kubernetes_endpoints_name": "testendpoints", "__meta_kubernetes_endpoints_name": "testendpoints",
"__meta_kubernetes_endpoints_annotation_test_annotation": "test",
"__meta_kubernetes_endpoints_annotationpresent_test_annotation": "true",
}, },
Source: "endpoints/own-ns/testendpoints", Source: "endpoints/own-ns/testendpoints",
}, },

View file

@ -252,7 +252,6 @@ func endpointSliceSourceFromNamespaceAndName(namespace, name string) string {
} }
const ( const (
endpointSliceNameLabel = metaLabelPrefix + "endpointslice_name"
endpointSliceAddressTypeLabel = metaLabelPrefix + "endpointslice_address_type" endpointSliceAddressTypeLabel = metaLabelPrefix + "endpointslice_address_type"
endpointSlicePortNameLabel = metaLabelPrefix + "endpointslice_port_name" endpointSlicePortNameLabel = metaLabelPrefix + "endpointslice_port_name"
endpointSlicePortProtocolLabel = metaLabelPrefix + "endpointslice_port_protocol" endpointSlicePortProtocolLabel = metaLabelPrefix + "endpointslice_port_protocol"
@ -274,9 +273,11 @@ func (e *EndpointSlice) buildEndpointSlice(eps endpointSliceAdaptor) *targetgrou
} }
tg.Labels = model.LabelSet{ tg.Labels = model.LabelSet{
namespaceLabel: lv(eps.namespace()), namespaceLabel: lv(eps.namespace()),
endpointSliceNameLabel: lv(eps.name()),
endpointSliceAddressTypeLabel: lv(eps.addressType()), endpointSliceAddressTypeLabel: lv(eps.addressType()),
} }
addObjectMetaLabels(tg.Labels, eps.getObjectMeta(), RoleEndpointSlice)
e.addServiceLabels(eps, tg) e.addServiceLabels(eps, tg)
type podEntry struct { type podEntry struct {

View file

@ -17,11 +17,13 @@ import (
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/discovery/v1" v1 "k8s.io/api/discovery/v1"
"k8s.io/api/discovery/v1beta1" "k8s.io/api/discovery/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
// endpointSliceAdaptor is an adaptor for the different EndpointSlice versions // endpointSliceAdaptor is an adaptor for the different EndpointSlice versions
type endpointSliceAdaptor interface { type endpointSliceAdaptor interface {
get() interface{} get() interface{}
getObjectMeta() metav1.ObjectMeta
name() string name() string
namespace() string namespace() string
addressType() string addressType() string
@ -66,6 +68,10 @@ func (e *endpointSliceAdaptorV1) get() interface{} {
return e.endpointSlice return e.endpointSlice
} }
func (e *endpointSliceAdaptorV1) getObjectMeta() metav1.ObjectMeta {
return e.endpointSlice.ObjectMeta
}
func (e *endpointSliceAdaptorV1) name() string { func (e *endpointSliceAdaptorV1) name() string {
return e.endpointSlice.ObjectMeta.Name return e.endpointSlice.ObjectMeta.Name
} }
@ -115,6 +121,10 @@ func (e *endpointSliceAdaptorV1Beta1) get() interface{} {
return e.endpointSlice return e.endpointSlice
} }
func (e *endpointSliceAdaptorV1Beta1) getObjectMeta() metav1.ObjectMeta {
return e.endpointSlice.ObjectMeta
}
func (e *endpointSliceAdaptorV1Beta1) name() string { func (e *endpointSliceAdaptorV1Beta1) name() string {
return e.endpointSlice.Name return e.endpointSlice.Name
} }

View file

@ -52,6 +52,9 @@ func makeEndpointSliceV1() *v1.EndpointSlice {
Labels: map[string]string{ Labels: map[string]string{
v1.LabelServiceName: "testendpoints", v1.LabelServiceName: "testendpoints",
}, },
Annotations: map[string]string{
"test.annotation": "test",
},
}, },
AddressType: v1.AddressTypeIPv4, AddressType: v1.AddressTypeIPv4,
Ports: []v1.EndpointPort{ Ports: []v1.EndpointPort{
@ -114,6 +117,9 @@ func makeEndpointSliceV1beta1() *v1beta1.EndpointSlice {
Labels: map[string]string{ Labels: map[string]string{
v1beta1.LabelServiceName: "testendpoints", v1beta1.LabelServiceName: "testendpoints",
}, },
Annotations: map[string]string{
"test.annotation": "test",
},
}, },
AddressType: v1beta1.AddressTypeIPv4, AddressType: v1beta1.AddressTypeIPv4,
Ports: []v1beta1.EndpointPort{ Ports: []v1beta1.EndpointPort{
@ -219,9 +225,13 @@ func TestEndpointSliceDiscoveryBeforeRun(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_namespace": "default",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
}, },
Source: "endpointslice/default/testendpoints", Source: "endpointslice/default/testendpoints",
}, },
@ -280,9 +290,13 @@ func TestEndpointSliceDiscoveryBeforeRunV1beta1(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_namespace": "default",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
}, },
Source: "endpointslice/default/testendpoints", Source: "endpointslice/default/testendpoints",
}, },
@ -478,9 +492,13 @@ func TestEndpointSliceDiscoveryDelete(t *testing.T) {
}, },
}, },
Labels: map[model.LabelName]model.LabelValue{ Labels: map[model.LabelName]model.LabelValue{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
"__meta_kubernetes_namespace": "default",
}, },
}, },
}, },
@ -574,9 +592,13 @@ func TestEndpointSliceDiscoveryUpdate(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
"__meta_kubernetes_namespace": "default",
}, },
}, },
}, },
@ -659,9 +681,13 @@ func TestEndpointSliceDiscoveryEmptyEndpoints(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
"__meta_kubernetes_namespace": "default",
}, },
Source: "endpointslice/default/testendpoints", Source: "endpointslice/default/testendpoints",
}, },
@ -739,12 +765,16 @@ func TestEndpointSliceDiscoveryWithService(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_service_label_app_name": "test", "__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_service_labelpresent_app_name": "true", "__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
"__meta_kubernetes_namespace": "default",
"__meta_kubernetes_service_label_app_name": "test",
"__meta_kubernetes_service_labelpresent_app_name": "true",
"__meta_kubernetes_service_name": "testendpoints",
}, },
Source: "endpointslice/default/testendpoints", Source: "endpointslice/default/testendpoints",
}, },
@ -835,14 +865,18 @@ func TestEndpointSliceDiscoveryWithServiceUpdate(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_service_label_app_name": "svc", "__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_service_label_component": "testing", "__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_service_labelpresent_app_name": "true", "__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
"__meta_kubernetes_service_labelpresent_component": "true", "__meta_kubernetes_namespace": "default",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_service_label_app_name": "svc",
"__meta_kubernetes_service_label_component": "testing",
"__meta_kubernetes_service_labelpresent_app_name": "true",
"__meta_kubernetes_service_labelpresent_component": "true",
"__meta_kubernetes_service_name": "testendpoints",
}, },
Source: "endpointslice/default/testendpoints", Source: "endpointslice/default/testendpoints",
}, },
@ -927,12 +961,16 @@ func TestEndpointsSlicesDiscoveryWithNodeMetadata(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_service_label_app_name": "test", "__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_service_labelpresent_app_name": "true", "__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
"__meta_kubernetes_namespace": "default",
"__meta_kubernetes_service_label_app_name": "test",
"__meta_kubernetes_service_labelpresent_app_name": "true",
"__meta_kubernetes_service_name": "testendpoints",
}, },
Source: "endpointslice/default/testendpoints", Source: "endpointslice/default/testendpoints",
}, },
@ -1023,12 +1061,16 @@ func TestEndpointsSlicesDiscoveryWithUpdatedNodeMetadata(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_namespace": "default", "__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_service_label_app_name": "test", "__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_service_labelpresent_app_name": "true", "__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
"__meta_kubernetes_namespace": "default",
"__meta_kubernetes_service_label_app_name": "test",
"__meta_kubernetes_service_labelpresent_app_name": "true",
"__meta_kubernetes_service_name": "testendpoints",
}, },
Source: "endpointslice/default/testendpoints", Source: "endpointslice/default/testendpoints",
}, },
@ -1159,12 +1201,16 @@ func TestEndpointSliceDiscoveryNamespaces(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_namespace": "ns1", "__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_service_label_app": "app1", "__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_service_labelpresent_app": "true", "__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_service_name": "testendpoints", "__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
"__meta_kubernetes_namespace": "ns1",
"__meta_kubernetes_service_label_app": "app1",
"__meta_kubernetes_service_labelpresent_app": "true",
"__meta_kubernetes_service_name": "testendpoints",
}, },
Source: "endpointslice/ns1/testendpoints", Source: "endpointslice/ns1/testendpoints",
}, },
@ -1303,9 +1349,13 @@ func TestEndpointSliceDiscoveryOwnNamespace(t *testing.T) {
}, },
}, },
Labels: model.LabelSet{ Labels: model.LabelSet{
"__meta_kubernetes_endpointslice_address_type": "IPv4", "__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_endpointslice_name": "testendpoints", "__meta_kubernetes_endpointslice_name": "testendpoints",
"__meta_kubernetes_namespace": "own-ns", "__meta_kubernetes_namespace": "own-ns",
"__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "testendpoints",
"__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_endpointslice_annotation_test_annotation": "test",
"__meta_kubernetes_endpointslice_annotationpresent_test_annotation": "true",
}, },
Source: "endpointslice/own-ns/testendpoints", Source: "endpointslice/own-ns/testendpoints",
}, },

View file

@ -28,7 +28,6 @@ import (
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"github.com/prometheus/prometheus/discovery/targetgroup" "github.com/prometheus/prometheus/discovery/targetgroup"
"github.com/prometheus/prometheus/util/strutil"
) )
var ( var (
@ -143,37 +142,22 @@ func ingressSourceFromNamespaceAndName(namespace, name string) string {
} }
const ( const (
ingressNameLabel = metaLabelPrefix + "ingress_name" ingressSchemeLabel = metaLabelPrefix + "ingress_scheme"
ingressLabelPrefix = metaLabelPrefix + "ingress_label_" ingressHostLabel = metaLabelPrefix + "ingress_host"
ingressLabelPresentPrefix = metaLabelPrefix + "ingress_labelpresent_" ingressPathLabel = metaLabelPrefix + "ingress_path"
ingressAnnotationPrefix = metaLabelPrefix + "ingress_annotation_" ingressClassNameLabel = metaLabelPrefix + "ingress_class_name"
ingressAnnotationPresentPrefix = metaLabelPrefix + "ingress_annotationpresent_"
ingressSchemeLabel = metaLabelPrefix + "ingress_scheme"
ingressHostLabel = metaLabelPrefix + "ingress_host"
ingressPathLabel = metaLabelPrefix + "ingress_path"
ingressClassNameLabel = metaLabelPrefix + "ingress_class_name"
) )
func ingressLabels(ingress ingressAdaptor) model.LabelSet { func ingressLabels(ingress ingressAdaptor) model.LabelSet {
// Each label and annotation will create two key-value pairs in the map. // Each label and annotation will create two key-value pairs in the map.
ls := make(model.LabelSet, 2*(len(ingress.labels())+len(ingress.annotations()))+2) ls := make(model.LabelSet)
ls[ingressNameLabel] = lv(ingress.name())
ls[namespaceLabel] = lv(ingress.namespace()) ls[namespaceLabel] = lv(ingress.namespace())
if cls := ingress.ingressClassName(); cls != nil { if cls := ingress.ingressClassName(); cls != nil {
ls[ingressClassNameLabel] = lv(*cls) ls[ingressClassNameLabel] = lv(*cls)
} }
for k, v := range ingress.labels() { addObjectMetaLabels(ls, ingress.getObjectMeta(), RoleIngress)
ln := strutil.SanitizeLabelName(k)
ls[model.LabelName(ingressLabelPrefix+ln)] = lv(v)
ls[model.LabelName(ingressLabelPresentPrefix+ln)] = presentValue
}
for k, v := range ingress.annotations() {
ln := strutil.SanitizeLabelName(k)
ls[model.LabelName(ingressAnnotationPrefix+ln)] = lv(v)
ls[model.LabelName(ingressAnnotationPresentPrefix+ln)] = presentValue
}
return ls return ls
} }

View file

@ -16,10 +16,12 @@ package kubernetes
import ( import (
v1 "k8s.io/api/networking/v1" v1 "k8s.io/api/networking/v1"
"k8s.io/api/networking/v1beta1" "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
// ingressAdaptor is an adaptor for the different Ingress versions // ingressAdaptor is an adaptor for the different Ingress versions
type ingressAdaptor interface { type ingressAdaptor interface {
getObjectMeta() metav1.ObjectMeta
name() string name() string
namespace() string namespace() string
labels() map[string]string labels() map[string]string
@ -43,11 +45,12 @@ func newIngressAdaptorFromV1(ingress *v1.Ingress) ingressAdaptor {
return &ingressAdaptorV1{ingress: ingress} return &ingressAdaptorV1{ingress: ingress}
} }
func (i *ingressAdaptorV1) name() string { return i.ingress.Name } func (i *ingressAdaptorV1) getObjectMeta() metav1.ObjectMeta { return i.ingress.ObjectMeta }
func (i *ingressAdaptorV1) namespace() string { return i.ingress.Namespace } func (i *ingressAdaptorV1) name() string { return i.ingress.Name }
func (i *ingressAdaptorV1) labels() map[string]string { return i.ingress.Labels } func (i *ingressAdaptorV1) namespace() string { return i.ingress.Namespace }
func (i *ingressAdaptorV1) annotations() map[string]string { return i.ingress.Annotations } func (i *ingressAdaptorV1) labels() map[string]string { return i.ingress.Labels }
func (i *ingressAdaptorV1) ingressClassName() *string { return i.ingress.Spec.IngressClassName } func (i *ingressAdaptorV1) annotations() map[string]string { return i.ingress.Annotations }
func (i *ingressAdaptorV1) ingressClassName() *string { return i.ingress.Spec.IngressClassName }
func (i *ingressAdaptorV1) tlsHosts() []string { func (i *ingressAdaptorV1) tlsHosts() []string {
var hosts []string var hosts []string
@ -95,12 +98,12 @@ type ingressAdaptorV1Beta1 struct {
func newIngressAdaptorFromV1beta1(ingress *v1beta1.Ingress) ingressAdaptor { func newIngressAdaptorFromV1beta1(ingress *v1beta1.Ingress) ingressAdaptor {
return &ingressAdaptorV1Beta1{ingress: ingress} return &ingressAdaptorV1Beta1{ingress: ingress}
} }
func (i *ingressAdaptorV1Beta1) getObjectMeta() metav1.ObjectMeta { return i.ingress.ObjectMeta }
func (i *ingressAdaptorV1Beta1) name() string { return i.ingress.Name } func (i *ingressAdaptorV1Beta1) name() string { return i.ingress.Name }
func (i *ingressAdaptorV1Beta1) namespace() string { return i.ingress.Namespace } func (i *ingressAdaptorV1Beta1) namespace() string { return i.ingress.Namespace }
func (i *ingressAdaptorV1Beta1) labels() map[string]string { return i.ingress.Labels } func (i *ingressAdaptorV1Beta1) labels() map[string]string { return i.ingress.Labels }
func (i *ingressAdaptorV1Beta1) annotations() map[string]string { return i.ingress.Annotations } func (i *ingressAdaptorV1Beta1) annotations() map[string]string { return i.ingress.Annotations }
func (i *ingressAdaptorV1Beta1) ingressClassName() *string { return i.ingress.Spec.IngressClassName } func (i *ingressAdaptorV1Beta1) ingressClassName() *string { return i.ingress.Spec.IngressClassName }
func (i *ingressAdaptorV1Beta1) tlsHosts() []string { func (i *ingressAdaptorV1Beta1) tlsHosts() []string {
var hosts []string var hosts []string

View file

@ -23,6 +23,8 @@ import (
"sync" "sync"
"time" "time"
"github.com/prometheus/prometheus/util/strutil"
disv1beta1 "k8s.io/api/discovery/v1beta1" disv1beta1 "k8s.io/api/discovery/v1beta1"
"github.com/go-kit/log" "github.com/go-kit/log"
@ -843,3 +845,19 @@ func checkDiscoveryV1Supported(client kubernetes.Interface) (bool, error) {
// https://kubernetes.io/docs/reference/using-api/deprecation-guide/#v1-25 // https://kubernetes.io/docs/reference/using-api/deprecation-guide/#v1-25
return semVer.Major() >= 1 && semVer.Minor() >= 21, nil return semVer.Major() >= 1 && semVer.Minor() >= 21, nil
} }
func addObjectMetaLabels(labelSet model.LabelSet, objectMeta metav1.ObjectMeta, role Role) {
labelSet[model.LabelName(metaLabelPrefix+string(role)+"_name")] = lv(objectMeta.Name)
for k, v := range objectMeta.Labels {
ln := strutil.SanitizeLabelName(k)
labelSet[model.LabelName(metaLabelPrefix+string(role)+"_label_"+ln)] = lv(v)
labelSet[model.LabelName(metaLabelPrefix+string(role)+"_labelpresent_"+ln)] = presentValue
}
for k, v := range objectMeta.Annotations {
ln := strutil.SanitizeLabelName(k)
labelSet[model.LabelName(metaLabelPrefix+string(role)+"_annotation_"+ln)] = lv(v)
labelSet[model.LabelName(metaLabelPrefix+string(role)+"_annotationpresent_"+ln)] = presentValue
}
}

View file

@ -152,33 +152,18 @@ func nodeSourceFromName(name string) string {
} }
const ( const (
nodeNameLabel = metaLabelPrefix + "node_name" nodeProviderIDLabel = metaLabelPrefix + "node_provider_id"
nodeProviderIDLabel = metaLabelPrefix + "node_provider_id" nodeAddressPrefix = metaLabelPrefix + "node_address_"
nodeLabelPrefix = metaLabelPrefix + "node_label_"
nodeLabelPresentPrefix = metaLabelPrefix + "node_labelpresent_"
nodeAnnotationPrefix = metaLabelPrefix + "node_annotation_"
nodeAnnotationPresentPrefix = metaLabelPrefix + "node_annotationpresent_"
nodeAddressPrefix = metaLabelPrefix + "node_address_"
) )
func nodeLabels(n *apiv1.Node) model.LabelSet { func nodeLabels(n *apiv1.Node) model.LabelSet {
// Each label and annotation will create two key-value pairs in the map. // Each label and annotation will create two key-value pairs in the map.
ls := make(model.LabelSet, 2*(len(n.Labels)+len(n.Annotations))+1) ls := make(model.LabelSet)
ls[nodeNameLabel] = lv(n.Name)
ls[nodeProviderIDLabel] = lv(n.Spec.ProviderID) ls[nodeProviderIDLabel] = lv(n.Spec.ProviderID)
for k, v := range n.Labels { addObjectMetaLabels(ls, n.ObjectMeta, RoleNode)
ln := strutil.SanitizeLabelName(k)
ls[model.LabelName(nodeLabelPrefix+ln)] = lv(v)
ls[model.LabelName(nodeLabelPresentPrefix+ln)] = presentValue
}
for k, v := range n.Annotations {
ln := strutil.SanitizeLabelName(k)
ls[model.LabelName(nodeAnnotationPrefix+ln)] = lv(v)
ls[model.LabelName(nodeAnnotationPresentPrefix+ln)] = presentValue
}
return ls return ls
} }

View file

@ -30,7 +30,6 @@ import (
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"github.com/prometheus/prometheus/discovery/targetgroup" "github.com/prometheus/prometheus/discovery/targetgroup"
"github.com/prometheus/prometheus/util/strutil"
) )
const nodeIndex = "node" const nodeIndex = "node"
@ -180,7 +179,6 @@ func convertToPod(o interface{}) (*apiv1.Pod, error) {
} }
const ( const (
podNameLabel = metaLabelPrefix + "pod_name"
podIPLabel = metaLabelPrefix + "pod_ip" podIPLabel = metaLabelPrefix + "pod_ip"
podContainerNameLabel = metaLabelPrefix + "pod_container_name" podContainerNameLabel = metaLabelPrefix + "pod_container_name"
podContainerIDLabel = metaLabelPrefix + "pod_container_id" podContainerIDLabel = metaLabelPrefix + "pod_container_id"
@ -191,10 +189,6 @@ const (
podContainerIsInit = metaLabelPrefix + "pod_container_init" podContainerIsInit = metaLabelPrefix + "pod_container_init"
podReadyLabel = metaLabelPrefix + "pod_ready" podReadyLabel = metaLabelPrefix + "pod_ready"
podPhaseLabel = metaLabelPrefix + "pod_phase" podPhaseLabel = metaLabelPrefix + "pod_phase"
podLabelPrefix = metaLabelPrefix + "pod_label_"
podLabelPresentPrefix = metaLabelPrefix + "pod_labelpresent_"
podAnnotationPrefix = metaLabelPrefix + "pod_annotation_"
podAnnotationPresentPrefix = metaLabelPrefix + "pod_annotationpresent_"
podNodeNameLabel = metaLabelPrefix + "pod_node_name" podNodeNameLabel = metaLabelPrefix + "pod_node_name"
podHostIPLabel = metaLabelPrefix + "pod_host_ip" podHostIPLabel = metaLabelPrefix + "pod_host_ip"
podUID = metaLabelPrefix + "pod_uid" podUID = metaLabelPrefix + "pod_uid"
@ -215,7 +209,6 @@ func GetControllerOf(controllee metav1.Object) *metav1.OwnerReference {
func podLabels(pod *apiv1.Pod) model.LabelSet { func podLabels(pod *apiv1.Pod) model.LabelSet {
ls := model.LabelSet{ ls := model.LabelSet{
podNameLabel: lv(pod.ObjectMeta.Name),
podIPLabel: lv(pod.Status.PodIP), podIPLabel: lv(pod.Status.PodIP),
podReadyLabel: podReady(pod), podReadyLabel: podReady(pod),
podPhaseLabel: lv(string(pod.Status.Phase)), podPhaseLabel: lv(string(pod.Status.Phase)),
@ -224,6 +217,8 @@ func podLabels(pod *apiv1.Pod) model.LabelSet {
podUID: lv(string(pod.ObjectMeta.UID)), podUID: lv(string(pod.ObjectMeta.UID)),
} }
addObjectMetaLabels(ls, pod.ObjectMeta, RolePod)
createdBy := GetControllerOf(pod) createdBy := GetControllerOf(pod)
if createdBy != nil { if createdBy != nil {
if createdBy.Kind != "" { if createdBy.Kind != "" {
@ -234,18 +229,6 @@ func podLabels(pod *apiv1.Pod) model.LabelSet {
} }
} }
for k, v := range pod.Labels {
ln := strutil.SanitizeLabelName(k)
ls[model.LabelName(podLabelPrefix+ln)] = lv(v)
ls[model.LabelName(podLabelPresentPrefix+ln)] = presentValue
}
for k, v := range pod.Annotations {
ln := strutil.SanitizeLabelName(k)
ls[model.LabelName(podAnnotationPrefix+ln)] = lv(v)
ls[model.LabelName(podAnnotationPresentPrefix+ln)] = presentValue
}
return ls return ls
} }

View file

@ -28,7 +28,6 @@ import (
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"github.com/prometheus/prometheus/discovery/targetgroup" "github.com/prometheus/prometheus/discovery/targetgroup"
"github.com/prometheus/prometheus/util/strutil"
) )
var ( var (
@ -147,38 +146,20 @@ func serviceSourceFromNamespaceAndName(namespace, name string) string {
} }
const ( const (
serviceNameLabel = metaLabelPrefix + "service_name" servicePortNameLabel = metaLabelPrefix + "service_port_name"
serviceLabelPrefix = metaLabelPrefix + "service_label_" servicePortNumberLabel = metaLabelPrefix + "service_port_number"
serviceLabelPresentPrefix = metaLabelPrefix + "service_labelpresent_" servicePortProtocolLabel = metaLabelPrefix + "service_port_protocol"
serviceAnnotationPrefix = metaLabelPrefix + "service_annotation_" serviceClusterIPLabel = metaLabelPrefix + "service_cluster_ip"
serviceAnnotationPresentPrefix = metaLabelPrefix + "service_annotationpresent_" serviceLoadBalancerIP = metaLabelPrefix + "service_loadbalancer_ip"
servicePortNameLabel = metaLabelPrefix + "service_port_name" serviceExternalNameLabel = metaLabelPrefix + "service_external_name"
servicePortNumberLabel = metaLabelPrefix + "service_port_number" serviceType = metaLabelPrefix + "service_type"
servicePortProtocolLabel = metaLabelPrefix + "service_port_protocol"
serviceClusterIPLabel = metaLabelPrefix + "service_cluster_ip"
serviceLoadBalancerIP = metaLabelPrefix + "service_loadbalancer_ip"
serviceExternalNameLabel = metaLabelPrefix + "service_external_name"
serviceType = metaLabelPrefix + "service_type"
) )
func serviceLabels(svc *apiv1.Service) model.LabelSet { func serviceLabels(svc *apiv1.Service) model.LabelSet {
// Each label and annotation will create two key-value pairs in the map. ls := make(model.LabelSet)
ls := make(model.LabelSet, 2*(len(svc.Labels)+len(svc.Annotations))+2)
ls[serviceNameLabel] = lv(svc.Name)
ls[namespaceLabel] = lv(svc.Namespace) ls[namespaceLabel] = lv(svc.Namespace)
addObjectMetaLabels(ls, svc.ObjectMeta, RoleService)
for k, v := range svc.Labels {
ln := strutil.SanitizeLabelName(k)
ls[model.LabelName(serviceLabelPrefix+ln)] = lv(v)
ls[model.LabelName(serviceLabelPresentPrefix+ln)] = presentValue
}
for k, v := range svc.Annotations {
ln := strutil.SanitizeLabelName(k)
ls[model.LabelName(serviceAnnotationPrefix+ln)] = lv(v)
ls[model.LabelName(serviceAnnotationPresentPrefix+ln)] = presentValue
}
return ls return ls
} }

View file

@ -304,10 +304,10 @@ func (d *Discovery) refreshData(ctx context.Context) ([]*targetgroup.Group, erro
linodeLabelGroup: model.LabelValue(instance.Group), linodeLabelGroup: model.LabelValue(instance.Group),
linodeLabelHypervisor: model.LabelValue(instance.Hypervisor), linodeLabelHypervisor: model.LabelValue(instance.Hypervisor),
linodeLabelBackups: model.LabelValue(backupsStatus), linodeLabelBackups: model.LabelValue(backupsStatus),
linodeLabelSpecsDiskBytes: model.LabelValue(fmt.Sprintf("%d", instance.Specs.Disk<<20)), linodeLabelSpecsDiskBytes: model.LabelValue(fmt.Sprintf("%d", int64(instance.Specs.Disk)<<20)),
linodeLabelSpecsMemoryBytes: model.LabelValue(fmt.Sprintf("%d", instance.Specs.Memory<<20)), linodeLabelSpecsMemoryBytes: model.LabelValue(fmt.Sprintf("%d", int64(instance.Specs.Memory)<<20)),
linodeLabelSpecsVCPUs: model.LabelValue(fmt.Sprintf("%d", instance.Specs.VCPUs)), linodeLabelSpecsVCPUs: model.LabelValue(fmt.Sprintf("%d", instance.Specs.VCPUs)),
linodeLabelSpecsTransferBytes: model.LabelValue(fmt.Sprintf("%d", instance.Specs.Transfer<<20)), linodeLabelSpecsTransferBytes: model.LabelValue(fmt.Sprintf("%d", int64(instance.Specs.Transfer)<<20)),
} }
addr := net.JoinHostPort(publicIPv4, strconv.FormatUint(uint64(d.port), 10)) addr := net.JoinHostPort(publicIPv4, strconv.FormatUint(uint64(d.port), 10))

View file

@ -14,6 +14,7 @@ Tooling for the Prometheus monitoring system.
| --- | --- | | --- | --- |
| <code class="text-nowrap">-h</code>, <code class="text-nowrap">--help</code> | Show context-sensitive help (also try --help-long and --help-man). | | <code class="text-nowrap">-h</code>, <code class="text-nowrap">--help</code> | Show context-sensitive help (also try --help-long and --help-man). |
| <code class="text-nowrap">--version</code> | Show application version. | | <code class="text-nowrap">--version</code> | Show application version. |
| <code class="text-nowrap">--experimental</code> | Enable experimental commands. |
| <code class="text-nowrap">--enable-feature</code> | Comma separated feature names to enable (only PromQL related and no-default-scrape-port). See https://prometheus.io/docs/prometheus/latest/feature_flags/ for the options and more details. | | <code class="text-nowrap">--enable-feature</code> | Comma separated feature names to enable (only PromQL related and no-default-scrape-port). See https://prometheus.io/docs/prometheus/latest/feature_flags/ for the options and more details. |
@ -30,6 +31,7 @@ Tooling for the Prometheus monitoring system.
| push | Push to a Prometheus server. | | push | Push to a Prometheus server. |
| test | Unit testing. | | test | Unit testing. |
| tsdb | Run tsdb commands. | | tsdb | Run tsdb commands. |
| promql | PromQL formatting and editing. Requires the --experimental flag. |
@ -609,3 +611,72 @@ Create blocks of data for new recording rules.
| rule-files | A list of one or more files containing recording rules to be backfilled. All recording rules listed in the files will be backfilled. Alerting rules are not evaluated. | Yes | | rule-files | A list of one or more files containing recording rules to be backfilled. All recording rules listed in the files will be backfilled. Alerting rules are not evaluated. | Yes |
### `promtool promql`
PromQL formatting and editing. Requires the `--experimental` flag.
##### `promtool promql format`
Format PromQL query to pretty printed form.
###### Arguments
| Argument | Description | Required |
| --- | --- | --- |
| query | PromQL query. | Yes |
##### `promtool promql label-matchers`
Edit label matchers contained within an existing PromQL query.
##### `promtool promql label-matchers set`
Set a label matcher in the query.
###### Flags
| Flag | Description | Default |
| --- | --- | --- |
| <code class="text-nowrap">-t</code>, <code class="text-nowrap">--type</code> | Type of the label matcher to set. | `=` |
###### Arguments
| Argument | Description | Required |
| --- | --- | --- |
| query | PromQL query. | Yes |
| name | Name of the label matcher to set. | Yes |
| value | Value of the label matcher to set. | Yes |
##### `promtool promql label-matchers delete`
Delete a label from the query.
###### Arguments
| Argument | Description | Required |
| --- | --- | --- |
| query | PromQL query. | Yes |
| name | Name of the label to delete. | Yes |

View file

@ -2010,6 +2010,8 @@ Available meta labels:
* `__meta_kubernetes_endpoints_name`: The names of the endpoints object. * `__meta_kubernetes_endpoints_name`: The names of the endpoints object.
* `__meta_kubernetes_endpoints_label_<labelname>`: Each label from the endpoints object. * `__meta_kubernetes_endpoints_label_<labelname>`: Each label from the endpoints object.
* `__meta_kubernetes_endpoints_labelpresent_<labelname>`: `true` for each label from the endpoints object. * `__meta_kubernetes_endpoints_labelpresent_<labelname>`: `true` for each label from the endpoints object.
* `__meta_kubernetes_endpoints_annotation_<annotationname>`: Each annotation from the endpoints object.
* `__meta_kubernetes_endpoints_annotationpresent_<annotationname>`: `true` for each annotation from the endpoints object.
* For all targets discovered directly from the endpoints list (those not additionally inferred * For all targets discovered directly from the endpoints list (those not additionally inferred
from underlying pods), the following labels are attached: from underlying pods), the following labels are attached:
* `__meta_kubernetes_endpoint_hostname`: Hostname of the endpoint. * `__meta_kubernetes_endpoint_hostname`: Hostname of the endpoint.
@ -2032,6 +2034,10 @@ Available meta labels:
* `__meta_kubernetes_namespace`: The namespace of the endpoints object. * `__meta_kubernetes_namespace`: The namespace of the endpoints object.
* `__meta_kubernetes_endpointslice_name`: The name of endpointslice object. * `__meta_kubernetes_endpointslice_name`: The name of endpointslice object.
* `__meta_kubernetes_endpointslice_label_<labelname>`: Each label from the endpointslice object.
* `__meta_kubernetes_endpointslice_labelpresent_<labelname>`: `true` for each label from the endpointslice object.
* `__meta_kubernetes_endpointslice_annotation_<annotationname>`: Each annotation from the endpointslice object.
* `__meta_kubernetes_endpointslice_annotationpresent_<annotationname>`: `true` for each annotation from the 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.

View file

@ -317,6 +317,12 @@ bound of that bucket is greater than
bucket. Otherwise, the upper bound of the lowest bucket is returned for bucket. Otherwise, the upper bound of the lowest bucket is returned for
quantiles located in the lowest bucket. quantiles located in the lowest bucket.
You can use `histogram_quantile(0, v instant-vector)` to get the estimated minimum value stored in
a histogram.
You can use `histogram_quantile(1, v instant-vector)` to get the estimated maximum value stored in
a histogram.
## `holt_winters()` ## `holt_winters()`

View file

@ -314,7 +314,7 @@ local template = grafana.template;
template.new( template.new(
'cluster', 'cluster',
'$datasource', '$datasource',
'label_values(kube_pod_container_info{image=~".*prometheus.*"}, cluster)' % $._config, 'label_values(prometheus_build_info, cluster)' % $._config,
refresh='time', refresh='time',
current={ current={
selected: true, selected: true,

120
go.mod
View file

@ -4,22 +4,22 @@ go 1.19
require ( require (
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible github.com/Azure/azure-sdk-for-go v65.0.0+incompatible
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0
github.com/Azure/go-autorest/autorest v0.11.29 github.com/Azure/go-autorest/autorest v0.11.29
github.com/Azure/go-autorest/autorest/adal v0.9.23 github.com/Azure/go-autorest/autorest/adal v0.9.23
github.com/DmitriyVTitov/size v1.5.0 github.com/DmitriyVTitov/size v1.5.0
github.com/alecthomas/kingpin/v2 v2.3.2 github.com/alecthomas/kingpin/v2 v2.3.2
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137
github.com/aws/aws-sdk-go v1.44.284 github.com/aws/aws-sdk-go v1.44.302
github.com/cespare/xxhash/v2 v2.2.0 github.com/cespare/xxhash/v2 v2.2.0
github.com/dennwc/varint v1.0.0 github.com/dennwc/varint v1.0.0
github.com/dgraph-io/ristretto v0.1.1 github.com/dgraph-io/ristretto v0.1.1
github.com/digitalocean/godo v1.99.0 github.com/digitalocean/godo v1.99.0
github.com/docker/docker v24.0.2+incompatible github.com/docker/docker v24.0.4+incompatible
github.com/edsrzf/mmap-go v1.1.0 github.com/edsrzf/mmap-go v1.1.0
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f github.com/envoyproxy/go-control-plane v0.11.1
github.com/envoyproxy/protoc-gen-validate v1.0.1 github.com/envoyproxy/protoc-gen-validate v1.0.2
github.com/fsnotify/fsnotify v1.6.0 github.com/fsnotify/fsnotify v1.6.0
github.com/go-kit/log v0.2.1 github.com/go-kit/log v0.2.1
github.com/go-logfmt/logfmt v0.6.0 github.com/go-logfmt/logfmt v0.6.0
@ -27,18 +27,19 @@ require (
github.com/go-zookeeper/zk v1.0.3 github.com/go-zookeeper/zk v1.0.3
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-20230602150820-91b7bce49751 github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8
github.com/gophercloud/gophercloud v1.4.0 github.com/gophercloud/gophercloud v1.5.0
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd
github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/hashicorp/consul/api v1.21.0 github.com/hashicorp/consul/api v1.22.0
github.com/hashicorp/nomad/api v0.0.0-20230605233119-67e39d5d248f github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e
github.com/hetznercloud/hcloud-go v1.47.0 github.com/hetznercloud/hcloud-go/v2 v2.0.0
github.com/ionos-cloud/sdk-go/v6 v6.1.7 github.com/ionos-cloud/sdk-go/v6 v6.1.8
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/klauspost/compress v1.16.7
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b
github.com/linode/linodego v1.17.2 github.com/linode/linodego v1.19.0
github.com/miekg/dns v1.1.54 github.com/miekg/dns v1.1.55
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f
github.com/oklog/run v1.1.0 github.com/oklog/run v1.1.0
github.com/oklog/ulid v1.3.1 github.com/oklog/ulid v1.3.1
@ -51,8 +52,8 @@ require (
github.com/prometheus/common/assets v0.2.0 github.com/prometheus/common/assets v0.2.0
github.com/prometheus/common/sigv4 v0.1.0 github.com/prometheus/common/sigv4 v0.1.0
github.com/prometheus/exporter-toolkit v0.10.0 github.com/prometheus/exporter-toolkit v0.10.0
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.19
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/vultr/govultr/v2 v2.17.2 github.com/vultr/govultr/v2 v2.17.2
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0
@ -65,21 +66,21 @@ require (
go.uber.org/atomic v1.11.0 go.uber.org/atomic v1.11.0
go.uber.org/automaxprocs v1.5.2 go.uber.org/automaxprocs v1.5.2
go.uber.org/goleak v1.2.1 go.uber.org/goleak v1.2.1
golang.org/x/net v0.11.0 golang.org/x/net v0.12.0
golang.org/x/oauth2 v0.9.0 golang.org/x/oauth2 v0.10.0
golang.org/x/sync v0.2.0 golang.org/x/sync v0.3.0
golang.org/x/sys v0.9.0 golang.org/x/sys v0.10.0
golang.org/x/time v0.3.0 golang.org/x/time v0.3.0
golang.org/x/tools v0.9.3 golang.org/x/tools v0.11.0
google.golang.org/api v0.114.0 google.golang.org/api v0.132.0
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753
google.golang.org/grpc v1.56.1 google.golang.org/grpc v1.56.2
google.golang.org/protobuf v1.30.0 google.golang.org/protobuf v1.31.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.26.2 k8s.io/api v0.27.3
k8s.io/apimachinery v0.26.2 k8s.io/apimachinery v0.27.3
k8s.io/client-go v0.26.2 k8s.io/client-go v0.27.3
k8s.io/klog v1.0.0 k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.100.1 k8s.io/klog/v2 v2.100.1
) )
@ -90,47 +91,50 @@ require (
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/stretchr/objx v0.5.0 // indirect github.com/stretchr/objx v0.5.0 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 // indirect
) )
require ( require (
cloud.google.com/go/compute v1.19.1 // indirect cloud.google.com/go/compute v1.22.0 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
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/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/armon/go-metrics v0.4.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/emicklei/go-restful/v3 v3.10.2 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/fatih/color v1.14.1 // indirect github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/ghodss/yaml v1.0.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/kit v0.12.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/analysis v0.21.4 // indirect
github.com/go-openapi/errors v0.20.3 // indirect github.com/go-openapi/errors v0.20.4 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/loads v0.21.2 // indirect github.com/go-openapi/loads v0.21.2 // indirect
github.com/go-openapi/spec v0.20.8 // indirect github.com/go-openapi/spec v0.20.9 // indirect
github.com/go-openapi/swag v0.22.3 // indirect github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-openapi/validate v0.22.1 // indirect github.com/go-openapi/validate v0.22.1 // indirect
github.com/go-resty/resty/v2 v2.7.0 // indirect github.com/go-resty/resty/v2 v2.7.0 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
@ -142,26 +146,26 @@ require (
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/googleapis/gax-go/v2 v2.7.1 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/hashicorp/cronexpr v1.1.1 // indirect github.com/hashicorp/cronexpr v1.1.2 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.4.0 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.4 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect
github.com/hashicorp/serf v0.10.1 // indirect github.com/hashicorp/serf v0.10.1 // indirect
github.com/imdario/mergo v0.3.13 // indirect github.com/imdario/mergo v0.3.16 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect
github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
@ -172,33 +176,33 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/procfs v0.10.1 // indirect github.com/prometheus/procfs v0.11.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
go.mongodb.org/mongo-driver v1.11.3 // indirect go.mongodb.org/mongo-driver v1.12.0 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect
go.opentelemetry.io/otel/metric v1.16.0 // indirect go.opentelemetry.io/otel/metric v1.16.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/crypto v0.10.0 // indirect golang.org/x/crypto v0.11.0 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1
golang.org/x/mod v0.10.0 // indirect golang.org/x/mod v0.12.0 // indirect
golang.org/x/term v0.9.0 // indirect golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gotest.tools/v3 v3.0.3 // indirect gotest.tools/v3 v3.0.3 // indirect
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515 // indirect
k8s.io/utils v0.0.0-20230308161112-d77c459e9343 // indirect k8s.io/utils v0.0.0-20230711102312-30195339c3c7 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect sigs.k8s.io/yaml v1.3.0 // indirect
) )
replace ( replace (
k8s.io/klog => github.com/simonpasquier/klog-gokit v0.3.0 k8s.io/klog => github.com/simonpasquier/klog-gokit v0.3.0
k8s.io/klog/v2 => github.com/simonpasquier/klog-gokit/v3 v3.0.0 k8s.io/klog/v2 => github.com/simonpasquier/klog-gokit/v3 v3.3.0
) )
// Exclude linodego v1.0.0 as it is no longer published on github. // Exclude linodego v1.0.0 as it is no longer published on github.

265
go.sum
View file

@ -12,20 +12,18 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= cloud.google.com/go/compute v1.22.0 h1:cB8R6FtUtT1TYGl5R3xuxnW6OUIc/DrT2aiR16TTG7Y=
cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= cloud.google.com/go/compute v1.22.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@ -38,8 +36,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw= github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw=
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 h1:8kDqDngH+DmVBiCtIjCFTGa7MBnsIOkF9IccInFEbjk= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 h1:8q4SaHjFsClSvuVne0ID/5Ka8u3fcIHyqkLjcFpNRHQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
@ -74,8 +72,8 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3
github.com/DmitriyVTitov/size v1.5.0 h1:/PzqxYrOyOUX1BXj6J9OuVRVGe+66VL4D9FlUaW515g= github.com/DmitriyVTitov/size v1.5.0 h1:/PzqxYrOyOUX1BXj6J9OuVRVGe+66VL4D9FlUaW515g=
github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
@ -108,8 +106,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.44.284 h1:Oc5Kubi43/VCkerlt3ZU3KpBju6BpNkoG3s7E8vj/O8= github.com/aws/aws-sdk-go v1.44.302 h1:ST3ko6GrJKn3Xi+nAvxjG3uk/V1pW8KC52WLeIxqqNk=
github.com/aws/aws-sdk-go v1.44.284/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go v1.44.302/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
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/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@ -154,8 +152,9 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
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/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
@ -166,10 +165,10 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn
github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E=
github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v24.0.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg= github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI=
github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v24.0.4+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-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@ -184,8 +183,8 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP
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 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE=
github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@ -193,18 +192,18 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
@ -242,12 +241,13 @@ github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9Qy
github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M=
github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
@ -257,8 +257,8 @@ github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8en
github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg=
github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg=
@ -267,14 +267,16 @@ github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KA
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU=
github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
@ -312,7 +314,6 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -366,7 +367,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
@ -383,22 +383,24 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
github.com/gophercloud/gophercloud v1.4.0 h1:RqEu43vaX0lb0LanZr5BylK5ICVxjpFFoc0sxivyuHU= github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo=
github.com/gophercloud/gophercloud v1.4.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
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/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
@ -413,16 +415,15 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
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/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 h1:1JYBfzqrWPcCclBwxFCPAou9n+q86mfnu7NAeHfte7A= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0/go.mod h1:YDZoGHuwE+ov0c8smSH49WLF3F2LaWnYYuDVd+EWrc0=
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.21.0 h1:WMR2JiyuaQWRAMFaOGiYfY4Q4HRpyYRe/oYQofjyduM= github.com/hashicorp/consul/api v1.22.0 h1:ydEvDooB/A0c/xpsBd8GSt7P2/zYPBui4KrNip0xGjE=
github.com/hashicorp/consul/api v1.21.0/go.mod h1:f8zVJwBcLdr1IQnfdfszjUM0xzp31Zl3bpws3pL9uFM= github.com/hashicorp/consul/api v1.22.0/go.mod h1:zHpYgZ7TeYqS6zaszjwSt128OwESRpnhU9aGa6ue3Eg=
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.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= github.com/hashicorp/consul/sdk v0.14.0 h1:Hly+BMNMssVzoWddbBnBFi3W+Fzytvm0haSkihhj3GU=
github.com/hashicorp/cronexpr v1.1.1 h1:NJZDd87hGXjoZBdvyCF9mX4DCq5Wy7+A/w+A7q0wn6c= github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A=
github.com/hashicorp/cronexpr v1.1.1/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= github.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -431,20 +432,20 @@ github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
@ -453,7 +454,7 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
@ -467,22 +468,22 @@ github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/
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.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM=
github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0=
github.com/hashicorp/nomad/api v0.0.0-20230605233119-67e39d5d248f h1:yxjcAZRuYymIDC0W4IQHgTe9EQdu2BsjPlVmKwyVZT4= github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e h1:sr4lujmn9heD030xx/Pd4B/JSmvRhFzuotNXaaV0WLs=
github.com/hashicorp/nomad/api v0.0.0-20230605233119-67e39d5d248f/go.mod h1:Xjd3OXUTfsWbCCBsQd3EdfPTz5evDi+fxqdvpN+WqQg= github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e/go.mod h1:O23qLAZuCx4htdY9zBaO4cJPXgleSFEdq6D/sezGgYE=
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.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
github.com/hetznercloud/hcloud-go v1.47.0 h1:WMZDwLPtMZwOLWIgERHrrrTzRFdHx0hTygYVQ4VWHW4= github.com/hetznercloud/hcloud-go/v2 v2.0.0 h1:Sg1DJ+MAKvbYAqaBaq9tPbwXBS2ckPIaMtVdUjKu+4g=
github.com/hetznercloud/hcloud-go v1.47.0/go.mod h1:zSpmBnxIdb5oMdbpVg1Q977Cq2qiwERkjj3jqRbHH5U= github.com/hetznercloud/hcloud-go/v2 v2.0.0/go.mod h1:4iUG2NG8b61IAwNx6UsMWQ6IfIf/i1RsG0BbsKAyR5Q=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/ionos-cloud/sdk-go/v6 v6.1.7 h1:uVG1Q/ZDJ7YmCI9Oevpue9xJEH5UrUMyXv8gm7NTxIw= github.com/ionos-cloud/sdk-go/v6 v6.1.8 h1:493wE/BkZxJf7x79UCE0cYGPZoqQcPiEBALvt7uVGY0=
github.com/ionos-cloud/sdk-go/v6 v6.1.7/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= github.com/ionos-cloud/sdk-go/v6 v6.1.8/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k=
github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
@ -515,6 +516,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -533,8 +536,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/linode/linodego v1.17.2 h1:b32dj4662PGG5P9qVa6nBezccWdqgukndlMIuPGq1CQ= github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YUw=
github.com/linode/linodego v1.17.2/go.mod h1:C2iyT3Vg2O2sPxkWka4XAQ5WSUtm5LmTZ3Adw43Ra7Q= github.com/linode/linodego v1.19.0/go.mod h1:XZFR+yJ9mm2kwf6itZ6SCpu+6w3KnIevV0Uu5HNWJgQ=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@ -557,8 +560,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
@ -567,8 +570,8 @@ github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
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.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@ -619,9 +622,9 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
@ -653,8 +656,9 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
@ -698,30 +702,30 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 h1:1WuWJu7/e8SqK+uQl7lfk/N/oMZTL2NE/TJsNKRNMc4= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.19 h1:+1H+N9QFl2Sfvia0FBYfMrHYHYhmpZxhSE0wpPL2lYs=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.19/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shoenig/test v0.6.6 h1:Oe8TPH9wAbv++YPNDKJWUnI8Q4PPWCx3UbOfH+FxiMU= github.com/shoenig/test v0.6.6 h1:Oe8TPH9wAbv++YPNDKJWUnI8Q4PPWCx3UbOfH+FxiMU=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/simonpasquier/klog-gokit v0.3.0 h1:TkFK21cbwDRS+CiystjqbAiq5ubJcVTk9hLUck5Ntcs= github.com/simonpasquier/klog-gokit v0.3.0 h1:TkFK21cbwDRS+CiystjqbAiq5ubJcVTk9hLUck5Ntcs=
github.com/simonpasquier/klog-gokit v0.3.0/go.mod h1:+SUlDQNrhVtGt2FieaqNftzzk8P72zpWlACateWxA9k= github.com/simonpasquier/klog-gokit v0.3.0/go.mod h1:+SUlDQNrhVtGt2FieaqNftzzk8P72zpWlACateWxA9k=
github.com/simonpasquier/klog-gokit/v3 v3.0.0 h1:J0QrVhAULISHWN05PeXX/xMqJBjnpl2fAuO8uHdQGsA= github.com/simonpasquier/klog-gokit/v3 v3.3.0 h1:HMzH999kO5gEgJTaWWO+xjncW5oycspcsBnjn9b853Q=
github.com/simonpasquier/klog-gokit/v3 v3.0.0/go.mod h1:+WRhGy707Lp2Q4r727m9Oc7FxazOHgW76FIyCr23nus= github.com/simonpasquier/klog-gokit/v3 v3.3.0/go.mod h1:uSbnWC3T7kt1dQyY9sjv0Ao1SehMAJdVnUNSKhjaDsg=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
@ -759,7 +763,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
@ -770,8 +773,10 @@ github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
@ -789,8 +794,8 @@ go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mI
go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= go.mongodb.org/mongo-driver v1.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE=
go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@ -819,8 +824,8 @@ go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF
go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
@ -846,12 +851,13 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-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-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -862,8 +868,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -885,8 +891,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -934,17 +940,16 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -958,8 +963,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1028,14 +1033,15 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1044,10 +1050,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1107,8 +1114,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1128,8 +1135,8 @@ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE= google.golang.org/api v0.132.0 h1:8t2/+qZ26kAOGSmOiHwVycqVaDg7q3JDILrNi/Z6rvc=
google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= google.golang.org/api v0.132.0/go.mod h1:AeTBC6GpJnJSRJjktDcPX0QwtS8pGYZOV6MSuSCusw0=
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=
@ -1168,10 +1175,13 @@ google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1m
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 h1:+VoAg+OKmWaommL56xmZSE2sUK8A7m6SUO7X89F2tbw=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753/go.mod h1:iqkVr8IRpZ53gx1dEnWlCUIEwDWqWARWrbzpasaTNYM=
google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 h1:lCbbUxUDD+DiXx9Q6F/ttL0aAu7N2pz8XnmMm8ZW4NE=
google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 h1:XUODHrpzJEUeWmVo/jfNTLj0YyVveOo28oE6vkFbkO4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
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=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
@ -1192,9 +1202,9 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
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.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI=
google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -1208,8 +1218,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -1242,7 +1252,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
@ -1256,23 +1265,23 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= k8s.io/api v0.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y=
k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= k8s.io/api v0.27.3/go.mod h1:C4BNvZnQOF7JA/0Xed2S+aUyJSfTGkGFxLXz9MnpIpg=
k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= k8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM=
k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= k8s.io/client-go v0.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8=
k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= k8s.io/client-go v0.27.3/go.mod h1:2MBEKuTo6V1lbKy3z1euEGnhPfGZLKTS9tiJ2xodM48=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515 h1:OmK1d0WrkD3IPfkskvroRykOulHVHf0s0ZIFRjyt+UI=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515/go.mod h1:kzo02I3kQ4BTtEfVLaPbjvCkX97YqGve33wzlb3fofQ=
k8s.io/utils v0.0.0-20230308161112-d77c459e9343 h1:m7tbIjXGcGIAtpmQr7/NAi7RsWoW3E7Zcm4jI1HicTc= k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc=
k8s.io/utils v0.0.0-20230308161112-d77c459e9343/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

View file

@ -421,7 +421,7 @@ func addBucket(
// receiving histogram, but a pointer to it is returned for convenience. // receiving histogram, but a pointer to it is returned for convenience.
// //
// The ideal value for maxEmptyBuckets depends on circumstances. The motivation // The ideal value for maxEmptyBuckets depends on circumstances. The motivation
// to set maxEmptyBuckets > 0 is the assumption that is is less overhead to // to set maxEmptyBuckets > 0 is the assumption that is less overhead to
// represent very few empty buckets explicitly within one span than cutting the // represent very few empty buckets explicitly within one span than cutting the
// one span into two to treat the empty buckets as a gap between the two spans, // one span into two to treat the empty buckets as a gap between the two spans,
// both in terms of storage requirement as well as in terms of encoding and // both in terms of storage requirement as well as in terms of encoding and
@ -615,10 +615,24 @@ func (h *FloatHistogram) NegativeReverseBucketIterator() BucketIterator[float64]
// set to the zero threshold. // set to the zero threshold.
func (h *FloatHistogram) AllBucketIterator() BucketIterator[float64] { func (h *FloatHistogram) AllBucketIterator() BucketIterator[float64] {
return &allFloatBucketIterator{ return &allFloatBucketIterator{
h: h, h: h,
negIter: h.NegativeReverseBucketIterator(), leftIter: h.NegativeReverseBucketIterator(),
posIter: h.PositiveBucketIterator(), rightIter: h.PositiveBucketIterator(),
state: -1, state: -1,
}
}
// AllReverseBucketIterator returns a BucketIterator to iterate over all negative,
// zero, and positive buckets in descending order (starting at the lowest bucket
// and going up). If the highest negative bucket or the lowest positive bucket
// overlap with the zero bucket, their upper or lower boundary, respectively, is
// set to the zero threshold.
func (h *FloatHistogram) AllReverseBucketIterator() BucketIterator[float64] {
return &allFloatBucketIterator{
h: h,
leftIter: h.PositiveReverseBucketIterator(),
rightIter: h.NegativeBucketIterator(),
state: -1,
} }
} }
@ -903,8 +917,8 @@ func (i *reverseFloatBucketIterator) Next() bool {
} }
type allFloatBucketIterator struct { type allFloatBucketIterator struct {
h *FloatHistogram h *FloatHistogram
negIter, posIter BucketIterator[float64] leftIter, rightIter BucketIterator[float64]
// -1 means we are iterating negative buckets. // -1 means we are iterating negative buckets.
// 0 means it is time for the zero bucket. // 0 means it is time for the zero bucket.
// 1 means we are iterating positive buckets. // 1 means we are iterating positive buckets.
@ -916,10 +930,13 @@ type allFloatBucketIterator struct {
func (i *allFloatBucketIterator) Next() bool { func (i *allFloatBucketIterator) Next() bool {
switch i.state { switch i.state {
case -1: case -1:
if i.negIter.Next() { if i.leftIter.Next() {
i.currBucket = i.negIter.At() i.currBucket = i.leftIter.At()
if i.currBucket.Upper > -i.h.ZeroThreshold { switch {
case i.currBucket.Upper < 0 && i.currBucket.Upper > -i.h.ZeroThreshold:
i.currBucket.Upper = -i.h.ZeroThreshold i.currBucket.Upper = -i.h.ZeroThreshold
case i.currBucket.Lower > 0 && i.currBucket.Lower < i.h.ZeroThreshold:
i.currBucket.Lower = i.h.ZeroThreshold
} }
return true return true
} }
@ -940,10 +957,13 @@ func (i *allFloatBucketIterator) Next() bool {
} }
return i.Next() return i.Next()
case 1: case 1:
if i.posIter.Next() { if i.rightIter.Next() {
i.currBucket = i.posIter.At() i.currBucket = i.rightIter.At()
if i.currBucket.Lower < i.h.ZeroThreshold { switch {
case i.currBucket.Lower > 0 && i.currBucket.Lower < i.h.ZeroThreshold:
i.currBucket.Lower = i.h.ZeroThreshold i.currBucket.Lower = i.h.ZeroThreshold
case i.currBucket.Upper < 0 && i.currBucket.Upper > -i.h.ZeroThreshold:
i.currBucket.Upper = -i.h.ZeroThreshold
} }
return true return true
} }

View file

@ -1979,3 +1979,229 @@ func TestAllFloatBucketIterator(t *testing.T) {
}) })
} }
} }
func TestAllReverseFloatBucketIterator(t *testing.T) {
cases := []struct {
h FloatHistogram
// To determine the expected buckets.
includeNeg, includeZero, includePos bool
}{
{
h: FloatHistogram{
Count: 405,
ZeroCount: 102,
ZeroThreshold: 0.001,
Sum: 1008.4,
Schema: 1,
PositiveSpans: []Span{
{Offset: 0, Length: 4},
{Offset: 1, Length: 0},
{Offset: 3, Length: 3},
{Offset: 3, Length: 0},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
PositiveBuckets: []float64{100, 344, 123, 55, 3, 63, 2, 54, 235, 33},
NegativeSpans: []Span{
{Offset: 0, Length: 3},
{Offset: 1, Length: 0},
{Offset: 3, Length: 0},
{Offset: 3, Length: 4},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
NegativeBuckets: []float64{10, 34, 1230, 54, 67, 63, 2, 554, 235, 33},
},
includeNeg: true,
includeZero: true,
includePos: true,
},
{
h: FloatHistogram{
Count: 405,
ZeroCount: 102,
ZeroThreshold: 0.001,
Sum: 1008.4,
Schema: 1,
NegativeSpans: []Span{
{Offset: 0, Length: 3},
{Offset: 1, Length: 0},
{Offset: 3, Length: 0},
{Offset: 3, Length: 4},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
NegativeBuckets: []float64{10, 34, 1230, 54, 67, 63, 2, 554, 235, 33},
},
includeNeg: true,
includeZero: true,
includePos: false,
},
{
h: FloatHistogram{
Count: 405,
ZeroCount: 102,
ZeroThreshold: 0.001,
Sum: 1008.4,
Schema: 1,
PositiveSpans: []Span{
{Offset: 0, Length: 4},
{Offset: 1, Length: 0},
{Offset: 3, Length: 3},
{Offset: 3, Length: 0},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
PositiveBuckets: []float64{100, 344, 123, 55, 3, 63, 2, 54, 235, 33},
},
includeNeg: false,
includeZero: true,
includePos: true,
},
{
h: FloatHistogram{
Count: 405,
ZeroCount: 102,
ZeroThreshold: 0.001,
Sum: 1008.4,
Schema: 1,
},
includeNeg: false,
includeZero: true,
includePos: false,
},
{
h: FloatHistogram{
Count: 405,
ZeroCount: 0,
ZeroThreshold: 0.001,
Sum: 1008.4,
Schema: 1,
PositiveSpans: []Span{
{Offset: 0, Length: 4},
{Offset: 1, Length: 0},
{Offset: 3, Length: 3},
{Offset: 3, Length: 0},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
PositiveBuckets: []float64{100, 344, 123, 55, 3, 63, 2, 54, 235, 33},
NegativeSpans: []Span{
{Offset: 0, Length: 3},
{Offset: 1, Length: 0},
{Offset: 3, Length: 0},
{Offset: 3, Length: 4},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
NegativeBuckets: []float64{10, 34, 1230, 54, 67, 63, 2, 554, 235, 33},
},
includeNeg: true,
includeZero: false,
includePos: true,
},
{
h: FloatHistogram{
Count: 447,
ZeroCount: 42,
ZeroThreshold: 0.5, // Coinciding with bucket boundary.
Sum: 1008.4,
Schema: 0,
PositiveSpans: []Span{
{Offset: 0, Length: 4},
{Offset: 1, Length: 0},
{Offset: 3, Length: 3},
{Offset: 3, Length: 0},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
PositiveBuckets: []float64{100, 344, 123, 55, 3, 63, 2, 54, 235, 33},
NegativeSpans: []Span{
{Offset: 0, Length: 3},
{Offset: 1, Length: 0},
{Offset: 3, Length: 0},
{Offset: 3, Length: 4},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
NegativeBuckets: []float64{10, 34, 1230, 54, 67, 63, 2, 554, 235, 33},
},
includeNeg: true,
includeZero: true,
includePos: true,
},
{
h: FloatHistogram{
Count: 447,
ZeroCount: 42,
ZeroThreshold: 0.6, // Within the bucket closest to zero.
Sum: 1008.4,
Schema: 0,
PositiveSpans: []Span{
{Offset: 0, Length: 4},
{Offset: 1, Length: 0},
{Offset: 3, Length: 3},
{Offset: 3, Length: 0},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
PositiveBuckets: []float64{100, 344, 123, 55, 3, 63, 2, 54, 235, 33},
NegativeSpans: []Span{
{Offset: 0, Length: 3},
{Offset: 1, Length: 0},
{Offset: 3, Length: 0},
{Offset: 3, Length: 4},
{Offset: 2, Length: 0},
{Offset: 5, Length: 3},
},
NegativeBuckets: []float64{10, 34, 1230, 54, 67, 63, 2, 554, 235, 33},
},
includeNeg: true,
includeZero: true,
includePos: true,
},
}
for i, c := range cases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
var expBuckets, actBuckets []Bucket[float64]
if c.includePos {
it := c.h.PositiveReverseBucketIterator()
for it.Next() {
b := it.At()
if c.includeZero && b.Lower < c.h.ZeroThreshold {
b.Lower = c.h.ZeroThreshold
}
expBuckets = append(expBuckets, b)
}
}
if c.includeZero {
expBuckets = append(expBuckets, Bucket[float64]{
Lower: -c.h.ZeroThreshold,
Upper: c.h.ZeroThreshold,
LowerInclusive: true,
UpperInclusive: true,
Count: c.h.ZeroCount,
})
}
if c.includeNeg {
it := c.h.NegativeBucketIterator()
for it.Next() {
b := it.At()
if c.includeZero && b.Upper > -c.h.ZeroThreshold {
b.Upper = -c.h.ZeroThreshold
}
expBuckets = append(expBuckets, b)
}
}
it := c.h.AllReverseBucketIterator()
for it.Next() {
actBuckets = append(actBuckets, it.At())
}
require.Equal(t, expBuckets, actBuckets)
})
}
}

View file

@ -202,10 +202,12 @@ func (re Regexp) String() string {
return str[4 : len(str)-2] return str[4 : len(str)-2]
} }
// Process returns a relabeled copy of the given label set. The relabel configurations // Process returns a relabeled version of the given label set. The relabel configurations
// are applied in order of input. // are applied in order of input.
// There are circumstances where Process will modify the input label.
// If you want to avoid issues with the input label set being modified, at the cost of
// higher memory usage, you can use lbls.Copy().
// If a label set is dropped, EmptyLabels and false is returned. // If a label set is dropped, EmptyLabels and false is returned.
// May return the input labelSet modified.
func Process(lbls labels.Labels, cfgs ...*Config) (ret labels.Labels, keep bool) { func Process(lbls labels.Labels, cfgs ...*Config) (ret labels.Labels, keep bool) {
lb := labels.NewBuilder(lbls) lb := labels.NewBuilder(lbls)
if !ProcessBuilder(lb, cfgs...) { if !ProcessBuilder(lb, cfgs...) {

View file

@ -54,7 +54,7 @@ type ProtobufParser struct {
// quantiles/buckets. // quantiles/buckets.
fieldPos int fieldPos int
fieldsDone bool // true if no more fields of a Summary or (legacy) Histogram to be processed. fieldsDone bool // true if no more fields of a Summary or (legacy) Histogram to be processed.
redoClassic bool // true after parsing a native histogram if we need to parse it again as a classit histogram. redoClassic bool // true after parsing a native histogram if we need to parse it again as a classic histogram.
// state is marked by the entry we are processing. EntryInvalid implies // state is marked by the entry we are processing. EntryInvalid implies
// that we have to decode the next MetricFamily. // that we have to decode the next MetricFamily.
@ -411,6 +411,14 @@ func (p *ProtobufParser) Next() (Entry, error) {
p.metricPos++ p.metricPos++
p.fieldPos = -2 p.fieldPos = -2
p.fieldsDone = false p.fieldsDone = false
// If this is a metric family containing native
// histograms, we have to switch back to native
// histograms after parsing a classic histogram.
if p.state == EntrySeries &&
(t == dto.MetricType_HISTOGRAM || t == dto.MetricType_GAUGE_HISTOGRAM) &&
isNativeHistogram(p.mf.GetMetric()[0].GetHistogram()) {
p.state = EntryHistogram
}
} }
if p.metricPos >= len(p.mf.GetMetric()) { if p.metricPos >= len(p.mf.GetMetric()) {
p.state = EntryInvalid p.state = EntryInvalid

View file

@ -408,6 +408,61 @@ metric: <
> >
> >
`,
`name: "test_histogram_family"
help: "Test histogram metric family with two very simple histograms."
type: HISTOGRAM
metric: <
label: <
name: "foo"
value: "bar"
>
histogram: <
sample_count: 5
sample_sum: 12.1
bucket: <
cumulative_count: 2
upper_bound: 1.1
>
bucket: <
cumulative_count: 3
upper_bound: 2.2
>
schema: 3
positive_span: <
offset: 8
length: 2
>
positive_delta: 2
positive_delta: 1
>
>
metric: <
label: <
name: "foo"
value: "baz"
>
histogram: <
sample_count: 6
sample_sum: 13.1
bucket: <
cumulative_count: 1
upper_bound: 1.1
>
bucket: <
cumulative_count: 5
upper_bound: 2.2
>
schema: 3
positive_span: <
offset: 8
length: 2
>
positive_delta: 1
positive_delta: 4
>
>
`, `,
`name: "rpc_durations_seconds" `name: "rpc_durations_seconds"
help: "RPC latency distributions." help: "RPC latency distributions."
@ -751,6 +806,50 @@ func TestProtobufParse(t *testing.T) {
"le", "+Inf", "le", "+Inf",
), ),
}, },
{
m: "test_histogram_family",
help: "Test histogram metric family with two very simple histograms.",
},
{
m: "test_histogram_family",
typ: MetricTypeHistogram,
},
{
m: "test_histogram_family\xfffoo\xffbar",
shs: &histogram.Histogram{
CounterResetHint: histogram.UnknownCounterReset,
Count: 5,
Sum: 12.1,
Schema: 3,
PositiveSpans: []histogram.Span{
{Offset: 8, Length: 2},
},
NegativeSpans: []histogram.Span{},
PositiveBuckets: []int64{2, 1},
},
lset: labels.FromStrings(
"__name__", "test_histogram_family",
"foo", "bar",
),
},
{
m: "test_histogram_family\xfffoo\xffbaz",
shs: &histogram.Histogram{
CounterResetHint: histogram.UnknownCounterReset,
Count: 6,
Sum: 13.1,
Schema: 3,
PositiveSpans: []histogram.Span{
{Offset: 8, Length: 2},
},
NegativeSpans: []histogram.Span{},
PositiveBuckets: []int64{1, 4},
},
lset: labels.FromStrings(
"__name__", "test_histogram_family",
"foo", "baz",
),
},
{ {
m: "rpc_durations_seconds", m: "rpc_durations_seconds",
help: "RPC latency distributions.", help: "RPC latency distributions.",
@ -1321,14 +1420,144 @@ func TestProtobufParse(t *testing.T) {
), ),
}, },
{ // 53 { // 53
m: "test_histogram_family",
help: "Test histogram metric family with two very simple histograms.",
},
{ // 54
m: "test_histogram_family",
typ: MetricTypeHistogram,
},
{ // 55
m: "test_histogram_family\xfffoo\xffbar",
shs: &histogram.Histogram{
CounterResetHint: histogram.UnknownCounterReset,
Count: 5,
Sum: 12.1,
Schema: 3,
PositiveSpans: []histogram.Span{
{Offset: 8, Length: 2},
},
NegativeSpans: []histogram.Span{},
PositiveBuckets: []int64{2, 1},
},
lset: labels.FromStrings(
"__name__", "test_histogram_family",
"foo", "bar",
),
},
{ // 56
m: "test_histogram_family_count\xfffoo\xffbar",
v: 5,
lset: labels.FromStrings(
"__name__", "test_histogram_family_count",
"foo", "bar",
),
},
{ // 57
m: "test_histogram_family_sum\xfffoo\xffbar",
v: 12.1,
lset: labels.FromStrings(
"__name__", "test_histogram_family_sum",
"foo", "bar",
),
},
{ // 58
m: "test_histogram_family_bucket\xfffoo\xffbar\xffle\xff1.1",
v: 2,
lset: labels.FromStrings(
"__name__", "test_histogram_family_bucket",
"foo", "bar",
"le", "1.1",
),
},
{ // 59
m: "test_histogram_family_bucket\xfffoo\xffbar\xffle\xff2.2",
v: 3,
lset: labels.FromStrings(
"__name__", "test_histogram_family_bucket",
"foo", "bar",
"le", "2.2",
),
},
{ // 60
m: "test_histogram_family_bucket\xfffoo\xffbar\xffle\xff+Inf",
v: 5,
lset: labels.FromStrings(
"__name__", "test_histogram_family_bucket",
"foo", "bar",
"le", "+Inf",
),
},
{ // 61
m: "test_histogram_family\xfffoo\xffbaz",
shs: &histogram.Histogram{
CounterResetHint: histogram.UnknownCounterReset,
Count: 6,
Sum: 13.1,
Schema: 3,
PositiveSpans: []histogram.Span{
{Offset: 8, Length: 2},
},
NegativeSpans: []histogram.Span{},
PositiveBuckets: []int64{1, 4},
},
lset: labels.FromStrings(
"__name__", "test_histogram_family",
"foo", "baz",
),
},
{ // 62
m: "test_histogram_family_count\xfffoo\xffbaz",
v: 6,
lset: labels.FromStrings(
"__name__", "test_histogram_family_count",
"foo", "baz",
),
},
{ // 63
m: "test_histogram_family_sum\xfffoo\xffbaz",
v: 13.1,
lset: labels.FromStrings(
"__name__", "test_histogram_family_sum",
"foo", "baz",
),
},
{ // 64
m: "test_histogram_family_bucket\xfffoo\xffbaz\xffle\xff1.1",
v: 1,
lset: labels.FromStrings(
"__name__", "test_histogram_family_bucket",
"foo", "baz",
"le", "1.1",
),
},
{ // 65
m: "test_histogram_family_bucket\xfffoo\xffbaz\xffle\xff2.2",
v: 5,
lset: labels.FromStrings(
"__name__", "test_histogram_family_bucket",
"foo", "baz",
"le", "2.2",
),
},
{ // 66
m: "test_histogram_family_bucket\xfffoo\xffbaz\xffle\xff+Inf",
v: 6,
lset: labels.FromStrings(
"__name__", "test_histogram_family_bucket",
"foo", "baz",
"le", "+Inf",
),
},
{ // 67
m: "rpc_durations_seconds", m: "rpc_durations_seconds",
help: "RPC latency distributions.", help: "RPC latency distributions.",
}, },
{ // 54 { // 68
m: "rpc_durations_seconds", m: "rpc_durations_seconds",
typ: MetricTypeSummary, typ: MetricTypeSummary,
}, },
{ // 55 { // 69
m: "rpc_durations_seconds_count\xffservice\xffexponential", m: "rpc_durations_seconds_count\xffservice\xffexponential",
v: 262, v: 262,
lset: labels.FromStrings( lset: labels.FromStrings(
@ -1336,7 +1565,7 @@ func TestProtobufParse(t *testing.T) {
"service", "exponential", "service", "exponential",
), ),
}, },
{ // 56 { // 70
m: "rpc_durations_seconds_sum\xffservice\xffexponential", m: "rpc_durations_seconds_sum\xffservice\xffexponential",
v: 0.00025551262820703587, v: 0.00025551262820703587,
lset: labels.FromStrings( lset: labels.FromStrings(
@ -1344,7 +1573,7 @@ func TestProtobufParse(t *testing.T) {
"service", "exponential", "service", "exponential",
), ),
}, },
{ // 57 { // 71
m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.5", m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.5",
v: 6.442786329648548e-07, v: 6.442786329648548e-07,
lset: labels.FromStrings( lset: labels.FromStrings(
@ -1353,7 +1582,7 @@ func TestProtobufParse(t *testing.T) {
"service", "exponential", "service", "exponential",
), ),
}, },
{ // 58 { // 72
m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.9", m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.9",
v: 1.9435742936658396e-06, v: 1.9435742936658396e-06,
lset: labels.FromStrings( lset: labels.FromStrings(
@ -1362,7 +1591,7 @@ func TestProtobufParse(t *testing.T) {
"service", "exponential", "service", "exponential",
), ),
}, },
{ // 59 { // 73
m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.99", m: "rpc_durations_seconds\xffservice\xffexponential\xffquantile\xff0.99",
v: 4.0471608667037015e-06, v: 4.0471608667037015e-06,
lset: labels.FromStrings( lset: labels.FromStrings(
@ -1371,22 +1600,22 @@ func TestProtobufParse(t *testing.T) {
"service", "exponential", "service", "exponential",
), ),
}, },
{ // 60 { // 74
m: "without_quantiles", m: "without_quantiles",
help: "A summary without quantiles.", help: "A summary without quantiles.",
}, },
{ // 61 { // 75
m: "without_quantiles", m: "without_quantiles",
typ: MetricTypeSummary, typ: MetricTypeSummary,
}, },
{ // 62 { // 76
m: "without_quantiles_count", m: "without_quantiles_count",
v: 42, v: 42,
lset: labels.FromStrings( lset: labels.FromStrings(
"__name__", "without_quantiles_count", "__name__", "without_quantiles_count",
), ),
}, },
{ // 63 { // 77
m: "without_quantiles_sum", m: "without_quantiles_sum",
v: 1.234, v: 1.234,
lset: labels.FromStrings( lset: labels.FromStrings(
@ -1420,61 +1649,61 @@ func TestProtobufParse(t *testing.T) {
var e exemplar.Exemplar var e exemplar.Exemplar
p.Metric(&res) p.Metric(&res)
found := p.Exemplar(&e) found := p.Exemplar(&e)
require.Equal(t, exp[i].m, string(m)) require.Equal(t, exp[i].m, string(m), "i: %d", i)
if ts != nil { if ts != nil {
require.Equal(t, exp[i].t, *ts) require.Equal(t, exp[i].t, *ts, "i: %d", i)
} else { } else {
require.Equal(t, exp[i].t, int64(0)) require.Equal(t, exp[i].t, int64(0), "i: %d", i)
} }
require.Equal(t, exp[i].v, v) require.Equal(t, exp[i].v, v, "i: %d", i)
require.Equal(t, exp[i].lset, res) require.Equal(t, exp[i].lset, res, "i: %d", i)
if len(exp[i].e) == 0 { if len(exp[i].e) == 0 {
require.Equal(t, false, found) require.Equal(t, false, found, "i: %d", i)
} else { } else {
require.Equal(t, true, found) require.Equal(t, true, found, "i: %d", i)
require.Equal(t, exp[i].e[0], e) require.Equal(t, exp[i].e[0], e, "i: %d", i)
} }
case EntryHistogram: case EntryHistogram:
m, ts, shs, fhs := p.Histogram() m, ts, shs, fhs := p.Histogram()
p.Metric(&res) p.Metric(&res)
require.Equal(t, exp[i].m, string(m)) require.Equal(t, exp[i].m, string(m), "i: %d", i)
if ts != nil { if ts != nil {
require.Equal(t, exp[i].t, *ts) require.Equal(t, exp[i].t, *ts, "i: %d", i)
} else { } else {
require.Equal(t, exp[i].t, int64(0)) require.Equal(t, exp[i].t, int64(0), "i: %d", i)
} }
require.Equal(t, exp[i].lset, res) require.Equal(t, exp[i].lset, res, "i: %d", i)
require.Equal(t, exp[i].m, string(m)) require.Equal(t, exp[i].m, string(m), "i: %d", i)
if shs != nil { if shs != nil {
require.Equal(t, exp[i].shs, shs) require.Equal(t, exp[i].shs, shs, "i: %d", i)
} else { } else {
require.Equal(t, exp[i].fhs, fhs) require.Equal(t, exp[i].fhs, fhs, "i: %d", i)
} }
j := 0 j := 0
for e := (exemplar.Exemplar{}); p.Exemplar(&e); j++ { for e := (exemplar.Exemplar{}); p.Exemplar(&e); j++ {
require.Equal(t, exp[i].e[j], e) require.Equal(t, exp[i].e[j], e, "i: %d", i)
e = exemplar.Exemplar{} e = exemplar.Exemplar{}
} }
require.Equal(t, len(exp[i].e), j, "not enough exemplars found") require.Equal(t, len(exp[i].e), j, "not enough exemplars found, i: %d", i)
case EntryType: case EntryType:
m, typ := p.Type() m, typ := p.Type()
require.Equal(t, exp[i].m, string(m)) require.Equal(t, exp[i].m, string(m), "i: %d", i)
require.Equal(t, exp[i].typ, typ) require.Equal(t, exp[i].typ, typ, "i: %d", i)
case EntryHelp: case EntryHelp:
m, h := p.Help() m, h := p.Help()
require.Equal(t, exp[i].m, string(m)) require.Equal(t, exp[i].m, string(m), "i: %d", i)
require.Equal(t, exp[i].help, string(h)) require.Equal(t, exp[i].help, string(h), "i: %d", i)
case EntryUnit: case EntryUnit:
m, u := p.Unit() m, u := p.Unit()
require.Equal(t, exp[i].m, string(m)) require.Equal(t, exp[i].m, string(m), "i: %d", i)
require.Equal(t, exp[i].unit, string(u)) require.Equal(t, exp[i].unit, string(u), "i: %d", i)
case EntryComment: case EntryComment:
require.Equal(t, exp[i].comment, string(p.Comment())) require.Equal(t, exp[i].comment, string(p.Comment()), "i: %d", i)
} }
i++ i++

View file

@ -49,6 +49,7 @@ func TestQueryConcurrency(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
queryTracker := NewActiveQueryTracker(dir, maxConcurrency, nil) queryTracker := NewActiveQueryTracker(dir, maxConcurrency, nil)
t.Cleanup(queryTracker.Close)
opts := EngineOpts{ opts := EngineOpts{
Logger: nil, Logger: nil,

View file

@ -17,6 +17,8 @@ import (
"math" "math"
"sort" "sort"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/model/histogram" "github.com/prometheus/prometheus/model/histogram"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
) )
@ -38,10 +40,6 @@ type bucket struct {
// buckets implements sort.Interface. // buckets implements sort.Interface.
type buckets []bucket type buckets []bucket
func (b buckets) Len() int { return len(b) }
func (b buckets) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (b buckets) Less(i, j int) bool { return b[i].upperBound < b[j].upperBound }
type metricWithBuckets struct { type metricWithBuckets struct {
metric labels.Labels metric labels.Labels
buckets buckets buckets buckets
@ -83,7 +81,9 @@ func bucketQuantile(q float64, buckets buckets) float64 {
if q > 1 { if q > 1 {
return math.Inf(+1) return math.Inf(+1)
} }
sort.Sort(buckets) slices.SortFunc(buckets, func(a, b bucket) bool {
return a.upperBound < b.upperBound
})
if !math.IsInf(buckets[len(buckets)-1].upperBound, +1) { if !math.IsInf(buckets[len(buckets)-1].upperBound, +1) {
return math.NaN() return math.NaN()
} }
@ -158,9 +158,21 @@ func histogramQuantile(q float64, h *histogram.FloatHistogram) float64 {
var ( var (
bucket histogram.Bucket[float64] bucket histogram.Bucket[float64]
count float64 count float64
it = h.AllBucketIterator() it histogram.BucketIterator[float64]
rank = q * h.Count rank float64
) )
// if there are NaN observations in the histogram (h.Sum is NaN), use the forward iterator
// if the q < 0.5, use the forward iterator
// if the q >= 0.5, use the reverse iterator
if math.IsNaN(h.Sum) || q < 0.5 {
it = h.AllBucketIterator()
rank = q * h.Count
} else {
it = h.AllReverseBucketIterator()
rank = (1 - q) * h.Count
}
for it.Next() { for it.Next() {
bucket = it.At() bucket = it.At()
count += bucket.Count count += bucket.Count
@ -193,7 +205,16 @@ func histogramQuantile(q float64, h *histogram.FloatHistogram) float64 {
return bucket.Upper return bucket.Upper
} }
rank -= count - bucket.Count // NaN observations increase h.Count but not the total number of
// observations in the buckets. Therefore, we have to use the forward
// iterator to find percentiles. We recognize histograms containing NaN
// observations by checking if their h.Sum is NaN.
if math.IsNaN(h.Sum) || q < 0.5 {
rank -= count - bucket.Count
} else {
rank = count - rank
}
// TODO(codesome): Use a better estimation than linear. // TODO(codesome): Use a better estimation than linear.
return bucket.Lower + (bucket.Upper-bucket.Lower)*(rank/bucket.Count) return bucket.Lower + (bucket.Upper-bucket.Lower)*(rank/bucket.Count)
} }

View file

@ -16,6 +16,7 @@ package promql
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"io"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -31,6 +32,7 @@ type ActiveQueryTracker struct {
mmapedFile []byte mmapedFile []byte
getNextIndex chan int getNextIndex chan int
logger log.Logger logger log.Logger
closer io.Closer
maxConcurrent int maxConcurrent int
} }
@ -81,7 +83,7 @@ func logUnfinishedQueries(filename string, filesize int, logger log.Logger) {
} }
} }
func getMMapedFile(filename string, filesize int, logger log.Logger) ([]byte, error) { func getMMapedFile(filename string, filesize int, logger log.Logger) ([]byte, io.Closer, error) {
file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o666) file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o666)
if err != nil { if err != nil {
absPath, pathErr := filepath.Abs(filename) absPath, pathErr := filepath.Abs(filename)
@ -89,22 +91,22 @@ func getMMapedFile(filename string, filesize int, logger log.Logger) ([]byte, er
absPath = filename absPath = filename
} }
level.Error(logger).Log("msg", "Error opening query log file", "file", absPath, "err", err) level.Error(logger).Log("msg", "Error opening query log file", "file", absPath, "err", err)
return nil, err return nil, nil, err
} }
err = file.Truncate(int64(filesize)) err = file.Truncate(int64(filesize))
if err != nil { if err != nil {
level.Error(logger).Log("msg", "Error setting filesize.", "filesize", filesize, "err", err) level.Error(logger).Log("msg", "Error setting filesize.", "filesize", filesize, "err", err)
return nil, err return nil, nil, err
} }
fileAsBytes, err := mmap.Map(file, mmap.RDWR, 0) fileAsBytes, err := mmap.Map(file, mmap.RDWR, 0)
if err != nil { if err != nil {
level.Error(logger).Log("msg", "Failed to mmap", "file", filename, "Attempted size", filesize, "err", err) level.Error(logger).Log("msg", "Failed to mmap", "file", filename, "Attempted size", filesize, "err", err)
return nil, err return nil, nil, err
} }
return fileAsBytes, err return fileAsBytes, file, err
} }
func NewActiveQueryTracker(localStoragePath string, maxConcurrent int, logger log.Logger) *ActiveQueryTracker { func NewActiveQueryTracker(localStoragePath string, maxConcurrent int, logger log.Logger) *ActiveQueryTracker {
@ -116,7 +118,7 @@ func NewActiveQueryTracker(localStoragePath string, maxConcurrent int, logger lo
filename, filesize := filepath.Join(localStoragePath, "queries.active"), 1+maxConcurrent*entrySize filename, filesize := filepath.Join(localStoragePath, "queries.active"), 1+maxConcurrent*entrySize
logUnfinishedQueries(filename, filesize, logger) logUnfinishedQueries(filename, filesize, logger)
fileAsBytes, err := getMMapedFile(filename, filesize, logger) fileAsBytes, closer, err := getMMapedFile(filename, filesize, logger)
if err != nil { if err != nil {
panic("Unable to create mmap-ed active query log") panic("Unable to create mmap-ed active query log")
} }
@ -124,6 +126,7 @@ func NewActiveQueryTracker(localStoragePath string, maxConcurrent int, logger lo
copy(fileAsBytes, "[") copy(fileAsBytes, "[")
activeQueryTracker := ActiveQueryTracker{ activeQueryTracker := ActiveQueryTracker{
mmapedFile: fileAsBytes, mmapedFile: fileAsBytes,
closer: closer,
getNextIndex: make(chan int, maxConcurrent), getNextIndex: make(chan int, maxConcurrent),
logger: logger, logger: logger,
maxConcurrent: maxConcurrent, maxConcurrent: maxConcurrent,
@ -198,3 +201,10 @@ func (tracker ActiveQueryTracker) Insert(ctx context.Context, query string) (int
return 0, ctx.Err() return 0, ctx.Err()
} }
} }
func (tracker *ActiveQueryTracker) Close() {
if tracker == nil || tracker.closer == nil {
return
}
tracker.closer.Close()
}

View file

@ -110,7 +110,10 @@ func TestMMapFile(t *testing.T) {
filename := file.Name() filename := file.Name()
defer os.Remove(filename) defer os.Remove(filename)
fileAsBytes, err := getMMapedFile(filename, 2, nil) fileAsBytes, closer, err := getMMapedFile(filename, 2, nil)
if err != nil {
t.Cleanup(func() { closer.Close() })
}
require.NoError(t, err) require.NoError(t, err)
copy(fileAsBytes, "ab") copy(fileAsBytes, "ab")

View file

@ -214,7 +214,7 @@ func (s Sample) MarshalJSON() ([]byte, error) {
return json.Marshal(h) return json.Marshal(h)
} }
// Vector is basically only an an alias for []Sample, but the contract is that // Vector is basically only an alias for []Sample, but the contract is that
// in a Vector, all Samples have the same timestamp. // in a Vector, all Samples have the same timestamp.
type Vector []Sample type Vector []Sample

View file

@ -30,6 +30,7 @@ import (
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/codes"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/model/rulefmt" "github.com/prometheus/prometheus/model/rulefmt"
@ -505,10 +506,9 @@ func (g *Group) AlertingRules() []*AlertingRule {
alerts = append(alerts, alertingRule) alerts = append(alerts, alertingRule)
} }
} }
sort.Slice(alerts, func(i, j int) bool { slices.SortFunc(alerts, func(a, b *AlertingRule) bool {
return alerts[i].State() > alerts[j].State() || return a.State() > b.State() ||
(alerts[i].State() == alerts[j].State() && (a.State() == b.State() && a.Name() < b.Name())
alerts[i].Name() < alerts[j].Name())
}) })
return alerts return alerts
} }
@ -578,11 +578,26 @@ func (g *Group) EvalTimestamp(startTime int64) time.Time {
if !g.alignEvaluationTimeOnInterval { if !g.alignEvaluationTimeOnInterval {
offset = int64(g.hash() % uint64(g.interval)) offset = int64(g.hash() % uint64(g.interval))
} }
var (
// This group's evaluation times differ from the perfect time intervals by `offset` nanoseconds.
// But we can only use `% interval` to align with the interval. And `% interval` will always
// align with the perfect time intervals, instead of this group's. Because of this we add
// `offset` _after_ aligning with the perfect time interval.
//
// There can be cases where adding `offset` to the perfect evaluation time can yield a
// timestamp in the future, which is not what EvalTimestamp should do.
// So we subtract one `offset` to make sure that `now - (now % interval) + offset` gives an
// evaluation time in the past.
adjNow = startTime - offset
adjNow := startTime - offset // Adjust to perfect evaluation intervals.
base := adjNow - (adjNow % int64(g.interval)) base = adjNow - (adjNow % int64(g.interval))
return time.Unix(0, base+offset).UTC() // Add one offset to randomize the evaluation times of this group.
next = base + offset
)
return time.Unix(0, next).UTC()
} }
func nameAndLabels(rule Rule) string { func nameAndLabels(rule Rule) string {
@ -1262,11 +1277,11 @@ func (m *Manager) RuleGroups() []*Group {
rgs = append(rgs, g) rgs = append(rgs, g)
} }
sort.Slice(rgs, func(i, j int) bool { slices.SortFunc(rgs, func(a, b *Group) bool {
if rgs[i].file != rgs[j].file { if a.file != b.file {
return rgs[i].file < rgs[j].file return a.file < b.file
} }
return rgs[i].name < rgs[j].name return a.name < b.name
}) })
return rgs return rgs

View file

@ -23,7 +23,6 @@ import (
"math" "math"
"net/http" "net/http"
"reflect" "reflect"
"sort"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@ -35,6 +34,7 @@ import (
config_util "github.com/prometheus/common/config" config_util "github.com/prometheus/common/config"
"github.com/prometheus/common/model" "github.com/prometheus/common/model"
"github.com/prometheus/common/version" "github.com/prometheus/common/version"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/discovery/targetgroup" "github.com/prometheus/prometheus/discovery/targetgroup"
@ -720,8 +720,8 @@ func mutateSampleLabels(lset labels.Labels, target *Target, honor bool, rc []*re
} }
func resolveConflictingExposedLabels(lb *labels.Builder, conflictingExposedLabels []labels.Label) { func resolveConflictingExposedLabels(lb *labels.Builder, conflictingExposedLabels []labels.Label) {
sort.SliceStable(conflictingExposedLabels, func(i, j int) bool { slices.SortStableFunc(conflictingExposedLabels, func(a, b labels.Label) bool {
return len(conflictingExposedLabels[i].Name) < len(conflictingExposedLabels[j].Name) return len(a.Name) < len(b.Name)
}) })
for _, l := range conflictingExposedLabels { for _, l := range conflictingExposedLabels {

View file

@ -26,6 +26,7 @@ import (
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
"github.com/golang/snappy" "github.com/golang/snappy"
"github.com/prometheus/common/model" "github.com/prometheus/common/model"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/model/exemplar" "github.com/prometheus/prometheus/model/exemplar"
"github.com/prometheus/prometheus/model/histogram" "github.com/prometheus/prometheus/model/histogram"
@ -178,7 +179,9 @@ func FromQueryResult(sortSeries bool, res *prompb.QueryResult) storage.SeriesSet
} }
if sortSeries { if sortSeries {
sort.Sort(byLabel(series)) slices.SortFunc(series, func(a, b storage.Series) bool {
return labels.Compare(a.Labels(), b.Labels()) < 0
})
} }
return &concreteSeriesSet{ return &concreteSeriesSet{
series: series, series: series,
@ -313,12 +316,6 @@ func MergeLabels(primary, secondary []prompb.Label) []prompb.Label {
return result return result
} }
type byLabel []storage.Series
func (a byLabel) Len() int { return len(a) }
func (a byLabel) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byLabel) Less(i, j int) bool { return labels.Compare(a[i].Labels(), a[j].Labels()) < 0 }
// errSeriesSet implements storage.SeriesSet, just returning an error. // errSeriesSet implements storage.SeriesSet, just returning an error.
type errSeriesSet struct { type errSeriesSet struct {
err error err error

View file

@ -16,12 +16,12 @@ package remote
import ( import (
"context" "context"
"net/http" "net/http"
"sort"
"sync" "sync"
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/go-kit/log/level" "github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
@ -92,8 +92,8 @@ func (h *readHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Value: value, Value: value,
}) })
} }
sort.Slice(sortedExternalLabels, func(i, j int) bool { slices.SortFunc(sortedExternalLabels, func(a, b prompb.Label) bool {
return sortedExternalLabels[i].Name < sortedExternalLabels[j].Name return a.Name < b.Name
}) })
responseType, err := NegotiateResponseType(req.AcceptedResponseTypes) responseType, err := NegotiateResponseType(req.AcceptedResponseTypes)

View file

@ -65,8 +65,8 @@ type Options struct {
// WALSegmentSize > 0, segment size is WALSegmentSize. // WALSegmentSize > 0, segment size is WALSegmentSize.
WALSegmentSize int WALSegmentSize int
// WALCompression will turn on Snappy compression for records on the WAL. // WALCompression configures the compression type to use on records in the WAL.
WALCompression bool WALCompression wlog.CompressionType
// StripeSize is the size (power of 2) in entries of the series hash map. Reducing the size will save memory but impact performance. // StripeSize is the size (power of 2) in entries of the series hash map. Reducing the size will save memory but impact performance.
StripeSize int StripeSize int
@ -87,7 +87,7 @@ type Options struct {
func DefaultOptions() *Options { func DefaultOptions() *Options {
return &Options{ return &Options{
WALSegmentSize: wlog.DefaultSegmentSize, WALSegmentSize: wlog.DefaultSegmentSize,
WALCompression: false, WALCompression: wlog.CompressionNone,
StripeSize: tsdb.DefaultStripeSize, StripeSize: tsdb.DefaultStripeSize,
TruncateFrequency: DefaultTruncateFrequency, TruncateFrequency: DefaultTruncateFrequency,
MinWALTime: DefaultMinWALTime, MinWALTime: DefaultMinWALTime,
@ -318,6 +318,10 @@ func validateOptions(opts *Options) *Options {
opts.WALSegmentSize = wlog.DefaultSegmentSize opts.WALSegmentSize = wlog.DefaultSegmentSize
} }
if opts.WALCompression == "" {
opts.WALCompression = wlog.CompressionNone
}
// Revert Stripesize to DefaultStripsize if Stripsize is either 0 or not a power of 2. // Revert Stripesize to DefaultStripsize if Stripsize is either 0 or not a power of 2.
if opts.StripeSize <= 0 || ((opts.StripeSize & (opts.StripeSize - 1)) != 0) { if opts.StripeSize <= 0 || ((opts.StripeSize & (opts.StripeSize - 1)) != 0) {
opts.StripeSize = tsdb.DefaultStripeSize opts.StripeSize = tsdb.DefaultStripeSize

View file

@ -20,7 +20,6 @@ import (
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"sort"
"sync" "sync"
"time" "time"
@ -30,6 +29,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"go.uber.org/atomic" "go.uber.org/atomic"
"golang.org/x/exp/slices"
"golang.org/x/sync/semaphore" "golang.org/x/sync/semaphore"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
@ -232,8 +232,8 @@ func (c *LeveledCompactor) Plan(dir string) ([]string, error) {
} }
func (c *LeveledCompactor) plan(dms []dirMeta) ([]string, error) { func (c *LeveledCompactor) plan(dms []dirMeta) ([]string, error) {
sort.Slice(dms, func(i, j int) bool { slices.SortFunc(dms, func(a, b dirMeta) bool {
return dms[i].meta.MinTime < dms[j].meta.MinTime return a.meta.MinTime < b.meta.MinTime
}) })
res := c.selectOverlappingDirs(dms) res := c.selectOverlappingDirs(dms)
@ -415,8 +415,8 @@ func CompactBlockMetas(uid ulid.ULID, blocks ...*BlockMeta) *BlockMeta {
for s := range sources { for s := range sources {
res.Compaction.Sources = append(res.Compaction.Sources, s) res.Compaction.Sources = append(res.Compaction.Sources, s)
} }
sort.Slice(res.Compaction.Sources, func(i, j int) bool { slices.SortFunc(res.Compaction.Sources, func(a, b ulid.ULID) bool {
return res.Compaction.Sources[i].Compare(res.Compaction.Sources[j]) < 0 return a.Compare(b) < 0
}) })
res.MinTime = mint res.MinTime = mint

View file

@ -42,6 +42,7 @@ import (
"github.com/prometheus/prometheus/tsdb/index" "github.com/prometheus/prometheus/tsdb/index"
"github.com/prometheus/prometheus/tsdb/tombstones" "github.com/prometheus/prometheus/tsdb/tombstones"
"github.com/prometheus/prometheus/tsdb/tsdbutil" "github.com/prometheus/prometheus/tsdb/tsdbutil"
"github.com/prometheus/prometheus/tsdb/wlog"
) )
func TestSplitByRange(t *testing.T) { func TestSplitByRange(t *testing.T) {
@ -1624,7 +1625,7 @@ func checkBlocks(t *testing.T, blocks []*Block, dirs ...string) {
func TestHeadCompactionWithHistograms(t *testing.T) { func TestHeadCompactionWithHistograms(t *testing.T) {
for _, floatTest := range []bool{true, false} { for _, floatTest := range []bool{true, false} {
t.Run(fmt.Sprintf("float=%t", floatTest), func(t *testing.T) { t.Run(fmt.Sprintf("float=%t", floatTest), func(t *testing.T) {
head, _ := newTestHead(t, DefaultBlockDuration, false, false) head, _ := newTestHead(t, DefaultBlockDuration, wlog.CompressionNone, false)
require.NoError(t, head.Init(0)) require.NoError(t, head.Init(0))
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
@ -1803,11 +1804,11 @@ func TestSparseHistogramSpaceSavings(t *testing.T) {
c.numBuckets, c.numBuckets,
), ),
func(t *testing.T) { func(t *testing.T) {
oldHead, _ := newTestHead(t, DefaultBlockDuration, false, false) oldHead, _ := newTestHead(t, DefaultBlockDuration, wlog.CompressionNone, false)
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, oldHead.Close()) require.NoError(t, oldHead.Close())
}) })
sparseHead, _ := newTestHead(t, DefaultBlockDuration, false, false) sparseHead, _ := newTestHead(t, DefaultBlockDuration, wlog.CompressionNone, false)
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, sparseHead.Close()) require.NoError(t, sparseHead.Close())
}) })

View file

@ -22,7 +22,6 @@ import (
"math" "math"
"os" "os"
"path/filepath" "path/filepath"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -34,6 +33,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"go.uber.org/atomic" "go.uber.org/atomic"
"golang.org/x/exp/slices"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
@ -79,8 +79,8 @@ func DefaultOptions() *Options {
MaxBlockDuration: DefaultBlockDuration, MaxBlockDuration: DefaultBlockDuration,
NoLockfile: false, NoLockfile: false,
AllowOverlappingCompaction: true, AllowOverlappingCompaction: true,
WALCompression: false,
SamplesPerChunk: DefaultSamplesPerChunk, SamplesPerChunk: DefaultSamplesPerChunk,
WALCompression: wlog.CompressionNone,
StripeSize: DefaultStripeSize, StripeSize: DefaultStripeSize,
HeadChunksWriteBufferSize: chunks.DefaultWriteBufferSize, HeadChunksWriteBufferSize: chunks.DefaultWriteBufferSize,
IsolationDisabled: defaultIsolationDisabled, IsolationDisabled: defaultIsolationDisabled,
@ -132,8 +132,8 @@ type Options struct {
// For Prometheus, this will always be true. // For Prometheus, this will always be true.
AllowOverlappingCompaction bool AllowOverlappingCompaction bool
// WALCompression will turn on Snappy compression for records on the WAL. // WALCompression configures the compression type to use on records in the WAL.
WALCompression bool WALCompression wlog.CompressionType
// Maximum number of CPUs that can simultaneously processes WAL replay. // Maximum number of CPUs that can simultaneously processes WAL replay.
// If it is <=0, then GOMAXPROCS is used. // If it is <=0, then GOMAXPROCS is used.
@ -620,8 +620,8 @@ func (db *DBReadOnly) Blocks() ([]BlockReader, error) {
return nil, nil return nil, nil
} }
sort.Slice(loadable, func(i, j int) bool { slices.SortFunc(loadable, func(a, b *Block) bool {
return loadable[i].Meta().MinTime < loadable[j].Meta().MinTime return a.Meta().MinTime < b.Meta().MinTime
}) })
blockMetas := make([]BlockMeta, 0, len(loadable)) blockMetas := make([]BlockMeta, 0, len(loadable))
@ -1493,8 +1493,8 @@ func (db *DB) reloadBlocks() (err error) {
} }
db.metrics.blocksBytes.Set(float64(blocksSize)) db.metrics.blocksBytes.Set(float64(blocksSize))
sort.Slice(toLoad, func(i, j int) bool { slices.SortFunc(toLoad, func(a, b *Block) bool {
return toLoad[i].Meta().MinTime < toLoad[j].Meta().MinTime return a.Meta().MinTime < b.Meta().MinTime
}) })
// Swap new blocks first for subsequently created readers to be seen. // Swap new blocks first for subsequently created readers to be seen.
@ -1568,8 +1568,8 @@ func deletableBlocks(db *DB, blocks []*Block) map[ulid.ULID]struct{} {
// Sort the blocks by time - newest to oldest (largest to smallest timestamp). // Sort the blocks by time - newest to oldest (largest to smallest timestamp).
// This ensures that the retentions will remove the oldest blocks. // This ensures that the retentions will remove the oldest blocks.
sort.Slice(blocks, func(i, j int) bool { slices.SortFunc(blocks, func(a, b *Block) bool {
return blocks[i].Meta().MaxTime > blocks[j].Meta().MaxTime return a.Meta().MaxTime > b.Meta().MaxTime
}) })
for _, block := range blocks { for _, block := range blocks {

View file

@ -1972,7 +1972,7 @@ func TestInitializeHeadTimestamp(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
require.NoError(t, os.MkdirAll(path.Join(dir, "wal"), 0o777)) require.NoError(t, os.MkdirAll(path.Join(dir, "wal"), 0o777))
w, err := wlog.New(nil, nil, path.Join(dir, "wal"), false) w, err := wlog.New(nil, nil, path.Join(dir, "wal"), wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
var enc record.Encoder var enc record.Encoder
@ -2014,7 +2014,7 @@ func TestInitializeHeadTimestamp(t *testing.T) {
createBlock(t, dir, genSeries(1, 1, 1000, 6000)) createBlock(t, dir, genSeries(1, 1, 1000, 6000))
require.NoError(t, os.MkdirAll(path.Join(dir, "wal"), 0o777)) require.NoError(t, os.MkdirAll(path.Join(dir, "wal"), 0o777))
w, err := wlog.New(nil, nil, path.Join(dir, "wal"), false) w, err := wlog.New(nil, nil, path.Join(dir, "wal"), wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
var enc record.Encoder var enc record.Encoder
@ -2415,7 +2415,7 @@ func TestDBReadOnly(t *testing.T) {
} }
// Add head to test DBReadOnly WAL reading capabilities. // Add head to test DBReadOnly WAL reading capabilities.
w, err := wlog.New(logger, nil, filepath.Join(dbDir, "wal"), true) w, err := wlog.New(logger, nil, filepath.Join(dbDir, "wal"), wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
h := createHead(t, w, genSeries(1, 1, 16, 18), dbDir) h := createHead(t, w, genSeries(1, 1, 16, 18), dbDir)
require.NoError(t, h.Close()) require.NoError(t, h.Close())
@ -2979,7 +2979,7 @@ func TestCompactHead(t *testing.T) {
NoLockfile: true, NoLockfile: true,
MinBlockDuration: int64(time.Hour * 2 / time.Millisecond), MinBlockDuration: int64(time.Hour * 2 / time.Millisecond),
MaxBlockDuration: int64(time.Hour * 2 / time.Millisecond), MaxBlockDuration: int64(time.Hour * 2 / time.Millisecond),
WALCompression: true, WALCompression: wlog.CompressionSnappy,
} }
db, err := Open(dbDir, log.NewNopLogger(), prometheus.NewRegistry(), tsdbCfg, nil) db, err := Open(dbDir, log.NewNopLogger(), prometheus.NewRegistry(), tsdbCfg, nil)
@ -3919,7 +3919,7 @@ func TestMetadataCheckpointingOnlyKeepsLatestEntry(t *testing.T) {
ctx := context.Background() ctx := context.Background()
numSamples := 10000 numSamples := 10000
hb, w := newTestHead(t, int64(numSamples)*10, false, false) hb, w := newTestHead(t, int64(numSamples)*10, wlog.CompressionNone, false)
// Add some series so we can append metadata to them. // Add some series so we can append metadata to them.
app := hb.Appender(ctx) app := hb.Appender(ctx)
@ -5106,7 +5106,7 @@ func TestWBLAndMmapReplay(t *testing.T) {
resetMmapToOriginal() // We neet to reset because new duplicate chunks can be written above. resetMmapToOriginal() // We neet to reset because new duplicate chunks can be written above.
// Removing m-map markers in WBL by rewriting it. // Removing m-map markers in WBL by rewriting it.
newWbl, err := wlog.New(log.NewNopLogger(), nil, filepath.Join(t.TempDir(), "new_wbl"), false) newWbl, err := wlog.New(log.NewNopLogger(), nil, filepath.Join(t.TempDir(), "new_wbl"), wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
sr, err := wlog.NewSegmentsReader(originalWblDir) sr, err := wlog.NewSegmentsReader(originalWblDir)
require.NoError(t, err) require.NoError(t, err)

View file

@ -15,11 +15,11 @@ package tsdb
import ( import (
"context" "context"
"sort"
"sync" "sync"
"unicode/utf8" "unicode/utf8"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/model/exemplar" "github.com/prometheus/prometheus/model/exemplar"
@ -185,8 +185,8 @@ func (ce *CircularExemplarStorage) Select(start, end int64, matchers ...[]*label
} }
} }
sort.Slice(ret, func(i, j int) bool { slices.SortFunc(ret, func(a, b exemplar.QueryResult) bool {
return labels.Compare(ret[i].SeriesLabels, ret[j].SeriesLabels) < 0 return labels.Compare(a.SeriesLabels, b.SeriesLabels) < 0
}) })
return ret, nil return ret, nil

View file

@ -1004,7 +1004,7 @@ func (h *Head) DisableNativeHistograms() {
h.opts.EnableNativeHistograms.Store(false) h.opts.EnableNativeHistograms.Store(false)
} }
// PostingsCardinalityStats returns top 10 highest cardinality stats By label and value names. // PostingsCardinalityStats returns highest cardinality stats by label and value names.
func (h *Head) PostingsCardinalityStats(statsByLabelName string, limit int) *index.PostingsStats { func (h *Head) PostingsCardinalityStats(statsByLabelName string, limit int) *index.PostingsStats {
h.cardinalityMutex.Lock() h.cardinalityMutex.Lock()
defer h.cardinalityMutex.Unlock() defer h.cardinalityMutex.Unlock()

View file

@ -16,7 +16,6 @@ package tsdb
import ( import (
"context" "context"
"math" "math"
"sort"
"sync" "sync"
"github.com/go-kit/log/level" "github.com/go-kit/log/level"
@ -141,8 +140,8 @@ func (h *headIndexReader) SortedPostings(p index.Postings) index.Postings {
return index.ErrPostings(errors.Wrap(err, "expand postings")) return index.ErrPostings(errors.Wrap(err, "expand postings"))
} }
sort.Slice(series, func(i, j int) bool { slices.SortFunc(series, func(a, b *memSeries) bool {
return labels.Compare(series[i].lset, series[j].lset) < 0 return labels.Compare(a.lset, b.lset) < 0
}) })
// Convert back to list. // Convert back to list.
@ -479,7 +478,7 @@ func (s *memSeries) oooMergedChunk(meta chunks.Meta, cdm chunkDiskMapper, mint,
// Next we want to sort all the collected chunks by min time so we can find // Next we want to sort all the collected chunks by min time so we can find
// those that overlap and stop when we know the rest don't. // those that overlap and stop when we know the rest don't.
sort.Sort(byMinTimeAndMinRef(tmpChks)) slices.SortFunc(tmpChks, refLessByMinTimeAndMinRef)
mc := &mergedOOOChunks{} mc := &mergedOOOChunks{}
absoluteMax := int64(math.MinInt64) absoluteMax := int64(math.MinInt64)

View file

@ -52,7 +52,7 @@ import (
"github.com/prometheus/prometheus/tsdb/wlog" "github.com/prometheus/prometheus/tsdb/wlog"
) )
func newTestHead(t testing.TB, chunkRange int64, compressWAL, oooEnabled bool) (*Head, *wlog.WL) { func newTestHead(t testing.TB, chunkRange int64, compressWAL wlog.CompressionType, oooEnabled bool) (*Head, *wlog.WL) {
dir := t.TempDir() dir := t.TempDir()
wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, compressWAL) wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, compressWAL)
require.NoError(t, err) require.NoError(t, err)
@ -79,7 +79,7 @@ func newTestHead(t testing.TB, chunkRange int64, compressWAL, oooEnabled bool) (
func BenchmarkCreateSeries(b *testing.B) { func BenchmarkCreateSeries(b *testing.B) {
series := genSeries(b.N, 10, 0, 0) series := genSeries(b.N, 10, 0, 0)
h, _ := newTestHead(b, 10000, false, false) h, _ := newTestHead(b, 10000, wlog.CompressionNone, false)
b.Cleanup(func() { b.Cleanup(func() {
require.NoError(b, h.Close()) require.NoError(b, h.Close())
}) })
@ -100,7 +100,7 @@ func BenchmarkHeadAppender_Append_Commit_ExistingSeries(b *testing.B) {
b.Run(fmt.Sprintf("%d series", seriesCount), func(b *testing.B) { b.Run(fmt.Sprintf("%d series", seriesCount), func(b *testing.B) {
for _, samplesPerAppend := range []int64{1, 2, 5, 100} { for _, samplesPerAppend := range []int64{1, 2, 5, 100} {
b.Run(fmt.Sprintf("%d samples per append", samplesPerAppend), func(b *testing.B) { b.Run(fmt.Sprintf("%d samples per append", samplesPerAppend), func(b *testing.B) {
h, _ := newTestHead(b, 10000, false, false) h, _ := newTestHead(b, 10000, wlog.CompressionNone, false)
b.Cleanup(func() { require.NoError(b, h.Close()) }) b.Cleanup(func() { require.NoError(b, h.Close()) })
ts := int64(1000) ts := int64(1000)
@ -245,7 +245,7 @@ func BenchmarkLoadWAL(b *testing.B) {
func(b *testing.B) { func(b *testing.B) {
dir := b.TempDir() dir := b.TempDir()
w, err := wlog.New(nil, nil, dir, false) w, err := wlog.New(nil, nil, dir, wlog.CompressionNone)
require.NoError(b, err) require.NoError(b, err)
// Write series. // Write series.
@ -338,7 +338,7 @@ func BenchmarkLoadWAL(b *testing.B) {
// While appending the samples to the head it concurrently queries them from multiple go routines and verifies that the // While appending the samples to the head it concurrently queries them from multiple go routines and verifies that the
// returned results are correct. // returned results are correct.
func TestHead_HighConcurrencyReadAndWrite(t *testing.T) { func TestHead_HighConcurrencyReadAndWrite(t *testing.T) {
head, _ := newTestHead(t, DefaultBlockDuration, false, false) head, _ := newTestHead(t, DefaultBlockDuration, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}() }()
@ -528,8 +528,8 @@ func TestHead_HighConcurrencyReadAndWrite(t *testing.T) {
} }
func TestHead_ReadWAL(t *testing.T) { func TestHead_ReadWAL(t *testing.T) {
for _, compress := range []bool{false, true} { for _, compress := range []wlog.CompressionType{wlog.CompressionNone, wlog.CompressionSnappy, wlog.CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
entries := []interface{}{ entries := []interface{}{
[]record.RefSeries{ []record.RefSeries{
{Ref: 10, Labels: labels.FromStrings("a", "1")}, {Ref: 10, Labels: labels.FromStrings("a", "1")},
@ -610,7 +610,7 @@ func TestHead_ReadWAL(t *testing.T) {
} }
func TestHead_WALMultiRef(t *testing.T) { func TestHead_WALMultiRef(t *testing.T) {
head, w := newTestHead(t, 1000, false, false) head, w := newTestHead(t, 1000, wlog.CompressionNone, false)
require.NoError(t, head.Init(0)) require.NoError(t, head.Init(0))
@ -645,7 +645,7 @@ func TestHead_WALMultiRef(t *testing.T) {
require.NotEqual(t, ref1, ref2, "Refs are the same") require.NotEqual(t, ref1, ref2, "Refs are the same")
require.NoError(t, head.Close()) require.NoError(t, head.Close())
w, err = wlog.New(nil, nil, w.Dir(), false) w, err = wlog.New(nil, nil, w.Dir(), wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
opts := DefaultHeadOptions() opts := DefaultHeadOptions()
@ -670,7 +670,7 @@ func TestHead_WALMultiRef(t *testing.T) {
} }
func TestHead_ActiveAppenders(t *testing.T) { func TestHead_ActiveAppenders(t *testing.T) {
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer head.Close() defer head.Close()
require.NoError(t, head.Init(0)) require.NoError(t, head.Init(0))
@ -703,14 +703,14 @@ func TestHead_ActiveAppenders(t *testing.T) {
} }
func TestHead_UnknownWALRecord(t *testing.T) { func TestHead_UnknownWALRecord(t *testing.T) {
head, w := newTestHead(t, 1000, false, false) head, w := newTestHead(t, 1000, wlog.CompressionNone, false)
w.Log([]byte{255, 42}) w.Log([]byte{255, 42})
require.NoError(t, head.Init(0)) require.NoError(t, head.Init(0))
require.NoError(t, head.Close()) require.NoError(t, head.Close())
} }
func TestHead_Truncate(t *testing.T) { func TestHead_Truncate(t *testing.T) {
h, _ := newTestHead(t, 1000, false, false) h, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -849,8 +849,8 @@ func TestMemSeries_truncateChunks(t *testing.T) {
} }
func TestHeadDeleteSeriesWithoutSamples(t *testing.T) { func TestHeadDeleteSeriesWithoutSamples(t *testing.T) {
for _, compress := range []bool{false, true} { for _, compress := range []wlog.CompressionType{wlog.CompressionNone, wlog.CompressionSnappy, wlog.CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
entries := []interface{}{ entries := []interface{}{
[]record.RefSeries{ []record.RefSeries{
{Ref: 10, Labels: labels.FromStrings("a", "1")}, {Ref: 10, Labels: labels.FromStrings("a", "1")},
@ -929,8 +929,8 @@ func TestHeadDeleteSimple(t *testing.T) {
}, },
} }
for _, compress := range []bool{false, true} { for _, compress := range []wlog.CompressionType{wlog.CompressionNone, wlog.CompressionSnappy, wlog.CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
for _, c := range cases { for _, c := range cases {
head, w := newTestHead(t, 1000, compress, false) head, w := newTestHead(t, 1000, compress, false)
require.NoError(t, head.Init(0)) require.NoError(t, head.Init(0))
@ -1013,7 +1013,7 @@ func TestHeadDeleteSimple(t *testing.T) {
} }
func TestDeleteUntilCurMax(t *testing.T) { func TestDeleteUntilCurMax(t *testing.T) {
hb, _ := newTestHead(t, 1000000, false, false) hb, _ := newTestHead(t, 1000000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, hb.Close()) require.NoError(t, hb.Close())
}() }()
@ -1066,7 +1066,7 @@ func TestDeletedSamplesAndSeriesStillInWALAfterCheckpoint(t *testing.T) {
numSamples := 10000 numSamples := 10000
// Enough samples to cause a checkpoint. // Enough samples to cause a checkpoint.
hb, w := newTestHead(t, int64(numSamples)*10, false, false) hb, w := newTestHead(t, int64(numSamples)*10, wlog.CompressionNone, false)
for i := 0; i < numSamples; i++ { for i := 0; i < numSamples; i++ {
app := hb.Appender(context.Background()) app := hb.Appender(context.Background())
@ -1158,7 +1158,7 @@ func TestDelete_e2e(t *testing.T) {
seriesMap[labels.New(l...).String()] = []tsdbutil.Sample{} seriesMap[labels.New(l...).String()] = []tsdbutil.Sample{}
} }
hb, _ := newTestHead(t, 100000, false, false) hb, _ := newTestHead(t, 100000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, hb.Close()) require.NoError(t, hb.Close())
}() }()
@ -1511,7 +1511,7 @@ func TestMemSeries_append_atVariableRate(t *testing.T) {
func TestGCChunkAccess(t *testing.T) { func TestGCChunkAccess(t *testing.T) {
// Put a chunk, select it. GC it and then access it. // Put a chunk, select it. GC it and then access it.
const chunkRange = 1000 const chunkRange = 1000
h, _ := newTestHead(t, chunkRange, false, false) h, _ := newTestHead(t, chunkRange, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -1570,7 +1570,7 @@ func TestGCChunkAccess(t *testing.T) {
func TestGCSeriesAccess(t *testing.T) { func TestGCSeriesAccess(t *testing.T) {
// Put a series, select it. GC it and then access it. // Put a series, select it. GC it and then access it.
const chunkRange = 1000 const chunkRange = 1000
h, _ := newTestHead(t, chunkRange, false, false) h, _ := newTestHead(t, chunkRange, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -1629,7 +1629,7 @@ func TestGCSeriesAccess(t *testing.T) {
} }
func TestUncommittedSamplesNotLostOnTruncate(t *testing.T) { func TestUncommittedSamplesNotLostOnTruncate(t *testing.T) {
h, _ := newTestHead(t, 1000, false, false) h, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -1659,7 +1659,7 @@ func TestUncommittedSamplesNotLostOnTruncate(t *testing.T) {
} }
func TestRemoveSeriesAfterRollbackAndTruncate(t *testing.T) { func TestRemoveSeriesAfterRollbackAndTruncate(t *testing.T) {
h, _ := newTestHead(t, 1000, false, false) h, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -1690,8 +1690,8 @@ func TestRemoveSeriesAfterRollbackAndTruncate(t *testing.T) {
} }
func TestHead_LogRollback(t *testing.T) { func TestHead_LogRollback(t *testing.T) {
for _, compress := range []bool{false, true} { for _, compress := range []wlog.CompressionType{wlog.CompressionNone, wlog.CompressionSnappy, wlog.CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
h, w := newTestHead(t, 1000, compress, false) h, w := newTestHead(t, 1000, compress, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
@ -1748,8 +1748,8 @@ func TestWalRepair_DecodingError(t *testing.T) {
5, 5,
}, },
} { } {
for _, compress := range []bool{false, true} { for _, compress := range []wlog.CompressionType{wlog.CompressionNone, wlog.CompressionSnappy, wlog.CompressionZstd} {
t.Run(fmt.Sprintf("%s,compress=%t", name, compress), func(t *testing.T) { t.Run(fmt.Sprintf("%s,compress=%s", name, compress), func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
// Fill the wal and corrupt it. // Fill the wal and corrupt it.
@ -1817,7 +1817,7 @@ func TestHeadReadWriterRepair(t *testing.T) {
walDir := filepath.Join(dir, "wal") walDir := filepath.Join(dir, "wal")
// Fill the chunk segments and corrupt it. // Fill the chunk segments and corrupt it.
{ {
w, err := wlog.New(nil, nil, walDir, false) w, err := wlog.New(nil, nil, walDir, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
opts := DefaultHeadOptions() opts := DefaultHeadOptions()
@ -1885,7 +1885,7 @@ func TestHeadReadWriterRepair(t *testing.T) {
} }
func TestNewWalSegmentOnTruncate(t *testing.T) { func TestNewWalSegmentOnTruncate(t *testing.T) {
h, wal := newTestHead(t, 1000, false, false) h, wal := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -1915,7 +1915,7 @@ func TestNewWalSegmentOnTruncate(t *testing.T) {
} }
func TestAddDuplicateLabelName(t *testing.T) { func TestAddDuplicateLabelName(t *testing.T) {
h, _ := newTestHead(t, 1000, false, false) h, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -1998,7 +1998,7 @@ func TestMemSeriesIsolation(t *testing.T) {
} }
// Test isolation without restart of Head. // Test isolation without restart of Head.
hb, _ := newTestHead(t, 1000, false, false) hb, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
i := addSamples(hb) i := addSamples(hb)
testIsolation(hb, i) testIsolation(hb, i)
@ -2060,11 +2060,11 @@ func TestMemSeriesIsolation(t *testing.T) {
require.NoError(t, hb.Close()) require.NoError(t, hb.Close())
// Test isolation with restart of Head. This is to verify the num samples of chunks after m-map chunk replay. // Test isolation with restart of Head. This is to verify the num samples of chunks after m-map chunk replay.
hb, w := newTestHead(t, 1000, false, false) hb, w := newTestHead(t, 1000, wlog.CompressionNone, false)
i = addSamples(hb) i = addSamples(hb)
require.NoError(t, hb.Close()) require.NoError(t, hb.Close())
wal, err := wlog.NewSize(nil, nil, w.Dir(), 32768, false) wal, err := wlog.NewSize(nil, nil, w.Dir(), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
opts := DefaultHeadOptions() opts := DefaultHeadOptions()
opts.ChunkRange = 1000 opts.ChunkRange = 1000
@ -2113,7 +2113,7 @@ func TestIsolationRollback(t *testing.T) {
} }
// Rollback after a failed append and test if the low watermark has progressed anyway. // Rollback after a failed append and test if the low watermark has progressed anyway.
hb, _ := newTestHead(t, 1000, false, false) hb, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, hb.Close()) require.NoError(t, hb.Close())
}() }()
@ -2144,7 +2144,7 @@ func TestIsolationLowWatermarkMonotonous(t *testing.T) {
t.Skip("skipping test since tsdb isolation is disabled") t.Skip("skipping test since tsdb isolation is disabled")
} }
hb, _ := newTestHead(t, 1000, false, false) hb, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, hb.Close()) require.NoError(t, hb.Close())
}() }()
@ -2181,7 +2181,7 @@ func TestIsolationAppendIDZeroIsNoop(t *testing.T) {
t.Skip("skipping test since tsdb isolation is disabled") t.Skip("skipping test since tsdb isolation is disabled")
} }
h, _ := newTestHead(t, 1000, false, false) h, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -2212,7 +2212,7 @@ func TestIsolationWithoutAdd(t *testing.T) {
t.Skip("skipping test since tsdb isolation is disabled") t.Skip("skipping test since tsdb isolation is disabled")
} }
hb, _ := newTestHead(t, 1000, false, false) hb, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, hb.Close()) require.NoError(t, hb.Close())
}() }()
@ -2307,7 +2307,7 @@ func TestOutOfOrderSamplesMetric(t *testing.T) {
} }
func testHeadSeriesChunkRace(t *testing.T) { func testHeadSeriesChunkRace(t *testing.T) {
h, _ := newTestHead(t, 1000, false, false) h, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -2342,7 +2342,7 @@ func testHeadSeriesChunkRace(t *testing.T) {
} }
func TestHeadLabelNamesValuesWithMinMaxRange(t *testing.T) { func TestHeadLabelNamesValuesWithMinMaxRange(t *testing.T) {
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}() }()
@ -2402,7 +2402,7 @@ func TestHeadLabelNamesValuesWithMinMaxRange(t *testing.T) {
} }
func TestHeadLabelValuesWithMatchers(t *testing.T) { func TestHeadLabelValuesWithMatchers(t *testing.T) {
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
t.Cleanup(func() { require.NoError(t, head.Close()) }) t.Cleanup(func() { require.NoError(t, head.Close()) })
app := head.Appender(context.Background()) app := head.Appender(context.Background())
@ -2461,7 +2461,7 @@ func TestHeadLabelValuesWithMatchers(t *testing.T) {
} }
func TestHeadLabelNamesWithMatchers(t *testing.T) { func TestHeadLabelNamesWithMatchers(t *testing.T) {
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}() }()
@ -2529,7 +2529,7 @@ func TestHeadLabelNamesWithMatchers(t *testing.T) {
} }
func TestHeadShardedPostings(t *testing.T) { func TestHeadShardedPostings(t *testing.T) {
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}() }()
@ -2590,7 +2590,7 @@ func TestHeadShardedPostings(t *testing.T) {
} }
func TestErrReuseAppender(t *testing.T) { func TestErrReuseAppender(t *testing.T) {
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}() }()
@ -2626,7 +2626,7 @@ func TestErrReuseAppender(t *testing.T) {
func TestHeadMintAfterTruncation(t *testing.T) { func TestHeadMintAfterTruncation(t *testing.T) {
chunkRange := int64(2000) chunkRange := int64(2000)
head, _ := newTestHead(t, chunkRange, false, false) head, _ := newTestHead(t, chunkRange, wlog.CompressionNone, false)
app := head.Appender(context.Background()) app := head.Appender(context.Background())
_, err := app.Append(0, labels.FromStrings("a", "b"), 100, 100) _, err := app.Append(0, labels.FromStrings("a", "b"), 100, 100)
@ -2660,7 +2660,7 @@ func TestHeadMintAfterTruncation(t *testing.T) {
func TestHeadExemplars(t *testing.T) { func TestHeadExemplars(t *testing.T) {
chunkRange := int64(2000) chunkRange := int64(2000)
head, _ := newTestHead(t, chunkRange, false, false) head, _ := newTestHead(t, chunkRange, wlog.CompressionNone, false)
app := head.Appender(context.Background()) app := head.Appender(context.Background())
l := labels.FromStrings("traceId", "123") l := labels.FromStrings("traceId", "123")
@ -2682,7 +2682,7 @@ func TestHeadExemplars(t *testing.T) {
func BenchmarkHeadLabelValuesWithMatchers(b *testing.B) { func BenchmarkHeadLabelValuesWithMatchers(b *testing.B) {
chunkRange := int64(2000) chunkRange := int64(2000)
head, _ := newTestHead(b, chunkRange, false, false) head, _ := newTestHead(b, chunkRange, wlog.CompressionNone, false)
b.Cleanup(func() { require.NoError(b, head.Close()) }) b.Cleanup(func() { require.NoError(b, head.Close()) })
app := head.Appender(context.Background()) app := head.Appender(context.Background())
@ -2997,7 +2997,7 @@ func TestAppendHistogram(t *testing.T) {
l := labels.FromStrings("a", "b") l := labels.FromStrings("a", "b")
for _, numHistograms := range []int{1, 10, 150, 200, 250, 300} { for _, numHistograms := range []int{1, 10, 150, 200, 250, 300} {
t.Run(fmt.Sprintf("%d", numHistograms), func(t *testing.T) { t.Run(fmt.Sprintf("%d", numHistograms), func(t *testing.T) {
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}) })
@ -3101,7 +3101,7 @@ func TestAppendHistogram(t *testing.T) {
} }
func TestHistogramInWALAndMmapChunk(t *testing.T) { func TestHistogramInWALAndMmapChunk(t *testing.T) {
head, _ := newTestHead(t, 3000, false, false) head, _ := newTestHead(t, 3000, wlog.CompressionNone, false)
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}) })
@ -3255,7 +3255,7 @@ func TestHistogramInWALAndMmapChunk(t *testing.T) {
// Restart head. // Restart head.
require.NoError(t, head.Close()) require.NoError(t, head.Close())
startHead := func() { startHead := func() {
w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, false) w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
head, err = NewHead(nil, nil, w, nil, head.opts, nil) head, err = NewHead(nil, nil, w, nil, head.opts, nil)
require.NoError(t, err) require.NoError(t, err)
@ -3284,7 +3284,7 @@ func TestHistogramInWALAndMmapChunk(t *testing.T) {
} }
func TestChunkSnapshot(t *testing.T) { func TestChunkSnapshot(t *testing.T) {
head, _ := newTestHead(t, 120*4, false, false) head, _ := newTestHead(t, 120*4, wlog.CompressionNone, false)
defer func() { defer func() {
head.opts.EnableMemorySnapshotOnShutdown = false head.opts.EnableMemorySnapshotOnShutdown = false
require.NoError(t, head.Close()) require.NoError(t, head.Close())
@ -3377,7 +3377,7 @@ func TestChunkSnapshot(t *testing.T) {
} }
openHeadAndCheckReplay := func() { openHeadAndCheckReplay := func() {
w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, false) w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
head, err = NewHead(nil, nil, w, nil, head.opts, nil) head, err = NewHead(nil, nil, w, nil, head.opts, nil)
require.NoError(t, err) require.NoError(t, err)
@ -3572,7 +3572,7 @@ func TestChunkSnapshot(t *testing.T) {
} }
func TestSnapshotError(t *testing.T) { func TestSnapshotError(t *testing.T) {
head, _ := newTestHead(t, 120*4, false, false) head, _ := newTestHead(t, 120*4, wlog.CompressionNone, false)
defer func() { defer func() {
head.opts.EnableMemorySnapshotOnShutdown = false head.opts.EnableMemorySnapshotOnShutdown = false
require.NoError(t, head.Close()) require.NoError(t, head.Close())
@ -3629,7 +3629,7 @@ func TestSnapshotError(t *testing.T) {
require.NoError(t, f.Close()) require.NoError(t, f.Close())
// Create new Head which should replay this snapshot. // Create new Head which should replay this snapshot.
w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, false) w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
// Testing https://github.com/prometheus/prometheus/issues/9437 with the registry. // Testing https://github.com/prometheus/prometheus/issues/9437 with the registry.
head, err = NewHead(prometheus.NewRegistry(), nil, w, nil, head.opts, nil) head, err = NewHead(prometheus.NewRegistry(), nil, w, nil, head.opts, nil)
@ -3646,7 +3646,7 @@ func TestSnapshotError(t *testing.T) {
func TestHistogramMetrics(t *testing.T) { func TestHistogramMetrics(t *testing.T) {
numHistograms := 10 numHistograms := 10
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}) })
@ -3676,7 +3676,7 @@ func TestHistogramMetrics(t *testing.T) {
require.Equal(t, float64(expHSamples), prom_testutil.ToFloat64(head.metrics.samplesAppended.WithLabelValues(sampleMetricTypeHistogram))) require.Equal(t, float64(expHSamples), prom_testutil.ToFloat64(head.metrics.samplesAppended.WithLabelValues(sampleMetricTypeHistogram)))
require.NoError(t, head.Close()) require.NoError(t, head.Close())
w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, false) w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
head, err = NewHead(nil, nil, w, nil, head.opts, nil) head, err = NewHead(nil, nil, w, nil, head.opts, nil)
require.NoError(t, err) require.NoError(t, err)
@ -3698,7 +3698,7 @@ func testHistogramStaleSampleHelper(t *testing.T, floatHistogram bool) {
t.Helper() t.Helper()
l := labels.FromStrings("a", "b") l := labels.FromStrings("a", "b")
numHistograms := 20 numHistograms := 20
head, _ := newTestHead(t, 100000, false, false) head, _ := newTestHead(t, 100000, wlog.CompressionNone, false)
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}) })
@ -3845,7 +3845,7 @@ func TestHistogramCounterResetHeader(t *testing.T) {
for _, floatHisto := range []bool{true, false} { for _, floatHisto := range []bool{true, false} {
t.Run(fmt.Sprintf("floatHistogram=%t", floatHisto), func(t *testing.T) { t.Run(fmt.Sprintf("floatHistogram=%t", floatHisto), func(t *testing.T) {
l := labels.FromStrings("a", "b") l := labels.FromStrings("a", "b")
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}) })
@ -4108,7 +4108,7 @@ func TestAppendingDifferentEncodingToSameSeries(t *testing.T) {
// Tests https://github.com/prometheus/prometheus/issues/9725. // Tests https://github.com/prometheus/prometheus/issues/9725.
func TestChunkSnapshotReplayBug(t *testing.T) { func TestChunkSnapshotReplayBug(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true) wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
// Write few series records and samples such that the series references are not in order in the WAL // Write few series records and samples such that the series references are not in order in the WAL
@ -4175,7 +4175,7 @@ func TestChunkSnapshotReplayBug(t *testing.T) {
func TestChunkSnapshotTakenAfterIncompleteSnapshot(t *testing.T) { func TestChunkSnapshotTakenAfterIncompleteSnapshot(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wlTemp, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true) wlTemp, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
// Write a snapshot with .tmp suffix. This used to fail taking any further snapshots or replay of snapshots. // Write a snapshot with .tmp suffix. This used to fail taking any further snapshots or replay of snapshots.
@ -4213,9 +4213,9 @@ func TestChunkSnapshotTakenAfterIncompleteSnapshot(t *testing.T) {
// TODO(codesome): Needs test for ooo WAL repair. // TODO(codesome): Needs test for ooo WAL repair.
func TestOOOWalReplay(t *testing.T) { func TestOOOWalReplay(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true) wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
oooWlog, err := wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, true) oooWlog, err := wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
opts := DefaultHeadOptions() opts := DefaultHeadOptions()
@ -4260,9 +4260,9 @@ func TestOOOWalReplay(t *testing.T) {
// Restart head. // Restart head.
require.NoError(t, h.Close()) require.NoError(t, h.Close())
wal, err = wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true) wal, err = wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
oooWlog, err = wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, true) oooWlog, err = wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
h, err = NewHead(nil, nil, wal, oooWlog, opts, nil) h, err = NewHead(nil, nil, wal, oooWlog, opts, nil)
require.NoError(t, err) require.NoError(t, err)
@ -4297,9 +4297,9 @@ func TestOOOWalReplay(t *testing.T) {
// TestOOOMmapReplay checks the replay at a low level. // TestOOOMmapReplay checks the replay at a low level.
func TestOOOMmapReplay(t *testing.T) { func TestOOOMmapReplay(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true) wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
oooWlog, err := wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, true) oooWlog, err := wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
opts := DefaultHeadOptions() opts := DefaultHeadOptions()
@ -4348,9 +4348,9 @@ func TestOOOMmapReplay(t *testing.T) {
// Restart head. // Restart head.
require.NoError(t, h.Close()) require.NoError(t, h.Close())
wal, err = wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true) wal, err = wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
oooWlog, err = wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, true) oooWlog, err = wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
h, err = NewHead(nil, nil, wal, oooWlog, opts, nil) h, err = NewHead(nil, nil, wal, oooWlog, opts, nil)
require.NoError(t, err) require.NoError(t, err)
@ -4379,7 +4379,7 @@ func TestOOOMmapReplay(t *testing.T) {
} }
func TestHeadInit_DiscardChunksWithUnsupportedEncoding(t *testing.T) { func TestHeadInit_DiscardChunksWithUnsupportedEncoding(t *testing.T) {
h, _ := newTestHead(t, 1000, false, false) h, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -4422,7 +4422,7 @@ func TestHeadInit_DiscardChunksWithUnsupportedEncoding(t *testing.T) {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
wal, err := wlog.NewSize(nil, nil, filepath.Join(h.opts.ChunkDirRoot, "wal"), 32768, false) wal, err := wlog.NewSize(nil, nil, filepath.Join(h.opts.ChunkDirRoot, "wal"), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
h, err = NewHead(nil, nil, wal, nil, h.opts, nil) h, err = NewHead(nil, nil, wal, nil, h.opts, nil)
require.NoError(t, err) require.NoError(t, err)
@ -4457,7 +4457,7 @@ func (c *unsupportedChunk) Encoding() chunkenc.Encoding {
// Tests https://github.com/prometheus/prometheus/issues/10277. // Tests https://github.com/prometheus/prometheus/issues/10277.
func TestMmapPanicAfterMmapReplayCorruption(t *testing.T) { func TestMmapPanicAfterMmapReplayCorruption(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, false) wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
opts := DefaultHeadOptions() opts := DefaultHeadOptions()
@ -4490,7 +4490,7 @@ func TestMmapPanicAfterMmapReplayCorruption(t *testing.T) {
addChunks() addChunks()
require.NoError(t, h.Close()) require.NoError(t, h.Close())
wal, err = wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, false) wal, err = wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
mmapFilePath := filepath.Join(dir, "chunks_head", "000001") mmapFilePath := filepath.Join(dir, "chunks_head", "000001")
@ -4516,7 +4516,7 @@ func TestReplayAfterMmapReplayError(t *testing.T) {
var err error var err error
openHead := func() { openHead := func() {
wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, false) wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
opts := DefaultHeadOptions() opts := DefaultHeadOptions()
@ -4734,9 +4734,9 @@ func generateBigTestHistograms(n int) []*histogram.Histogram {
func TestOOOAppendWithNoSeries(t *testing.T) { func TestOOOAppendWithNoSeries(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true) wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
oooWlog, err := wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, true) oooWlog, err := wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
opts := DefaultHeadOptions() opts := DefaultHeadOptions()
@ -4815,9 +4815,9 @@ func TestOOOAppendWithNoSeries(t *testing.T) {
func TestHeadMinOOOTimeUpdate(t *testing.T) { func TestHeadMinOOOTimeUpdate(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true) wal, err := wlog.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
oooWlog, err := wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, true) oooWlog, err := wlog.NewSize(nil, nil, filepath.Join(dir, wlog.WblDirName), 32768, wlog.CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
opts := DefaultHeadOptions() opts := DefaultHeadOptions()
@ -4862,7 +4862,7 @@ func TestHeadMinOOOTimeUpdate(t *testing.T) {
func TestGaugeHistogramWALAndChunkHeader(t *testing.T) { func TestGaugeHistogramWALAndChunkHeader(t *testing.T) {
l := labels.FromStrings("a", "b") l := labels.FromStrings("a", "b")
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}) })
@ -4926,7 +4926,7 @@ func TestGaugeHistogramWALAndChunkHeader(t *testing.T) {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
require.NoError(t, os.RemoveAll(mmappedChunksDir(head.opts.ChunkDirRoot))) require.NoError(t, os.RemoveAll(mmappedChunksDir(head.opts.ChunkDirRoot)))
w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, false) w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
head, err = NewHead(nil, nil, w, nil, head.opts, nil) head, err = NewHead(nil, nil, w, nil, head.opts, nil)
require.NoError(t, err) require.NoError(t, err)
@ -4937,7 +4937,7 @@ func TestGaugeHistogramWALAndChunkHeader(t *testing.T) {
func TestGaugeFloatHistogramWALAndChunkHeader(t *testing.T) { func TestGaugeFloatHistogramWALAndChunkHeader(t *testing.T) {
l := labels.FromStrings("a", "b") l := labels.FromStrings("a", "b")
head, _ := newTestHead(t, 1000, false, false) head, _ := newTestHead(t, 1000, wlog.CompressionNone, false)
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
}) })
@ -5001,7 +5001,7 @@ func TestGaugeFloatHistogramWALAndChunkHeader(t *testing.T) {
require.NoError(t, head.Close()) require.NoError(t, head.Close())
require.NoError(t, os.RemoveAll(mmappedChunksDir(head.opts.ChunkDirRoot))) require.NoError(t, os.RemoveAll(mmappedChunksDir(head.opts.ChunkDirRoot)))
w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, false) w, err := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
head, err = NewHead(nil, nil, w, nil, head.opts, nil) head, err = NewHead(nil, nil, w, nil, head.opts, nil)
require.NoError(t, err) require.NoError(t, err)
@ -5011,7 +5011,7 @@ func TestGaugeFloatHistogramWALAndChunkHeader(t *testing.T) {
} }
func TestSnapshotAheadOfWALError(t *testing.T) { func TestSnapshotAheadOfWALError(t *testing.T) {
head, _ := newTestHead(t, 120*4, false, false) head, _ := newTestHead(t, 120*4, wlog.CompressionNone, false)
head.opts.EnableMemorySnapshotOnShutdown = true head.opts.EnableMemorySnapshotOnShutdown = true
// Add a sample to fill WAL. // Add a sample to fill WAL.
app := head.Appender(context.Background()) app := head.Appender(context.Background())
@ -5034,7 +5034,7 @@ func TestSnapshotAheadOfWALError(t *testing.T) {
// to keep using the same snapshot directory instead of a random one. // to keep using the same snapshot directory instead of a random one.
require.NoError(t, os.RemoveAll(head.wal.Dir())) require.NoError(t, os.RemoveAll(head.wal.Dir()))
head.opts.EnableMemorySnapshotOnShutdown = false head.opts.EnableMemorySnapshotOnShutdown = false
w, _ := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, false) w, _ := wlog.NewSize(nil, nil, head.wal.Dir(), 32768, wlog.CompressionNone)
head, err = NewHead(nil, nil, w, nil, head.opts, nil) head, err = NewHead(nil, nil, w, nil, head.opts, nil)
require.NoError(t, err) require.NoError(t, err)
// Add a sample to fill WAL. // Add a sample to fill WAL.
@ -5053,7 +5053,7 @@ func TestSnapshotAheadOfWALError(t *testing.T) {
// Create new Head which should detect the incorrect index and delete the snapshot. // Create new Head which should detect the incorrect index and delete the snapshot.
head.opts.EnableMemorySnapshotOnShutdown = true head.opts.EnableMemorySnapshotOnShutdown = true
w, _ = wlog.NewSize(nil, nil, head.wal.Dir(), 32768, false) w, _ = wlog.NewSize(nil, nil, head.wal.Dir(), 32768, wlog.CompressionNone)
head, err = NewHead(nil, nil, w, nil, head.opts, nil) head, err = NewHead(nil, nil, w, nil, head.opts, nil)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, head.Init(math.MinInt64)) require.NoError(t, head.Init(math.MinInt64))

View file

@ -1121,7 +1121,7 @@ func (h *Head) ChunkSnapshot() (*ChunkSnapshotStats, error) {
if err := os.MkdirAll(cpdirtmp, 0o777); err != nil { if err := os.MkdirAll(cpdirtmp, 0o777); err != nil {
return stats, errors.Wrap(err, "create chunk snapshot dir") return stats, errors.Wrap(err, "create chunk snapshot dir")
} }
cp, err := wlog.New(nil, nil, cpdirtmp, h.wal.CompressionEnabled()) cp, err := wlog.New(nil, nil, cpdirtmp, h.wal.CompressionType())
if err != nil { if err != nil {
return stats, errors.Wrap(err, "open chunk snapshot") return stats, errors.Wrap(err, "open chunk snapshot")
} }

View file

@ -176,18 +176,15 @@ func NewTOCFromByteSlice(bs ByteSlice) (*TOC, error) {
return nil, errors.Wrap(encoding.ErrInvalidChecksum, "read TOC") return nil, errors.Wrap(encoding.ErrInvalidChecksum, "read TOC")
} }
if err := d.Err(); err != nil { toc := &TOC{
return nil, err
}
return &TOC{
Symbols: d.Be64(), Symbols: d.Be64(),
Series: d.Be64(), Series: d.Be64(),
LabelIndices: d.Be64(), LabelIndices: d.Be64(),
LabelIndicesTable: d.Be64(), LabelIndicesTable: d.Be64(),
Postings: d.Be64(), Postings: d.Be64(),
PostingsTable: d.Be64(), PostingsTable: d.Be64(),
}, nil }
return toc, d.Err()
} }
// NewWriter returns a new Writer to the given filename. It serializes data in format version 2. // NewWriter returns a new Writer to the given filename. It serializes data in format version 2.
@ -925,7 +922,7 @@ func (w *Writer) writePostingsToTmpFiles() error {
values = append(values, v) values = append(values, v)
} }
// Symbol numbers are in order, so the strings will also be in order. // Symbol numbers are in order, so the strings will also be in order.
sort.Sort(uint32slice(values)) slices.Sort(values)
for _, v := range values { for _, v := range values {
value, err := w.symbols.Lookup(v) value, err := w.symbols.Lookup(v)
if err != nil { if err != nil {
@ -1018,12 +1015,6 @@ func (w *Writer) writePostings() error {
return nil return nil
} }
type uint32slice []uint32
func (s uint32slice) Len() int { return len(s) }
func (s uint32slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s uint32slice) Less(i, j int) bool { return s[i] < s[j] }
type labelIndexHashEntry struct { type labelIndexHashEntry struct {
keys []string keys []string
offset uint64 offset uint64

View file

@ -107,11 +107,11 @@ func (p *MemPostings) SortedKeys() []labels.Label {
} }
p.mtx.RUnlock() p.mtx.RUnlock()
sort.Slice(keys, func(i, j int) bool { slices.SortFunc(keys, func(a, b labels.Label) bool {
if keys[i].Name != keys[j].Name { if a.Name != b.Name {
return keys[i].Name < keys[j].Name return a.Name < b.Name
} }
return keys[i].Value < keys[j].Value return a.Value < b.Value
}) })
return keys return keys
} }

View file

@ -15,7 +15,8 @@ package index
import ( import (
"math" "math"
"sort"
"golang.org/x/exp/slices"
) )
// Stat holds values for a single cardinality statistic. // Stat holds values for a single cardinality statistic.
@ -62,8 +63,8 @@ func (m *maxHeap) push(item Stat) {
} }
func (m *maxHeap) get() []Stat { func (m *maxHeap) get() []Stat {
sort.Slice(m.Items, func(i, j int) bool { slices.SortFunc(m.Items, func(a, b Stat) bool {
return m.Items[i].Count > m.Items[j].Count return a.Count > b.Count
}) })
return m.Items return m.Items
} }

View file

@ -17,7 +17,8 @@ package tsdb
import ( import (
"errors" "errors"
"math" "math"
"sort"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/storage"
@ -130,13 +131,13 @@ func (oh *OOOHeadIndexReader) series(ref storage.SeriesRef, builder *labels.Scra
// Next we want to sort all the collected chunks by min time so we can find // Next we want to sort all the collected chunks by min time so we can find
// those that overlap. // those that overlap.
sort.Sort(metaByMinTimeAndMinRef(tmpChks)) slices.SortFunc(tmpChks, lessByMinTimeAndMinRef)
// Next we want to iterate the sorted collected chunks and only return the // Next we want to iterate the sorted collected chunks and only return the
// chunks Meta the first chunk that overlaps with others. // chunks Meta the first chunk that overlaps with others.
// Example chunks of a series: 5:(100, 200) 6:(500, 600) 7:(150, 250) 8:(550, 650) // Example chunks of a series: 5:(100, 200) 6:(500, 600) 7:(150, 250) 8:(550, 650)
// In the example 5 overlaps with 7 and 6 overlaps with 8 so we only want to // In the example 5 overlaps with 7 and 6 overlaps with 8 so we only want to
// to return chunk Metas for chunk 5 and chunk 6e // return chunk Metas for chunk 5 and chunk 6e
*chks = append(*chks, tmpChks[0]) *chks = append(*chks, tmpChks[0])
maxTime := tmpChks[0].MaxTime // Tracks the maxTime of the previous "to be merged chunk". maxTime := tmpChks[0].MaxTime // Tracks the maxTime of the previous "to be merged chunk".
for _, c := range tmpChks[1:] { for _, c := range tmpChks[1:] {
@ -181,30 +182,20 @@ type chunkMetaAndChunkDiskMapperRef struct {
origMaxT int64 origMaxT int64
} }
type byMinTimeAndMinRef []chunkMetaAndChunkDiskMapperRef func refLessByMinTimeAndMinRef(a, b chunkMetaAndChunkDiskMapperRef) bool {
if a.meta.MinTime == b.meta.MinTime {
func (b byMinTimeAndMinRef) Len() int { return len(b) } return a.meta.Ref < b.meta.Ref
func (b byMinTimeAndMinRef) Less(i, j int) bool {
if b[i].meta.MinTime == b[j].meta.MinTime {
return b[i].meta.Ref < b[j].meta.Ref
} }
return b[i].meta.MinTime < b[j].meta.MinTime return a.meta.MinTime < b.meta.MinTime
} }
func (b byMinTimeAndMinRef) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func lessByMinTimeAndMinRef(a, b chunks.Meta) bool {
if a.MinTime == b.MinTime {
type metaByMinTimeAndMinRef []chunks.Meta return a.Ref < b.Ref
func (b metaByMinTimeAndMinRef) Len() int { return len(b) }
func (b metaByMinTimeAndMinRef) Less(i, j int) bool {
if b[i].MinTime == b[j].MinTime {
return b[i].Ref < b[j].Ref
} }
return b[i].MinTime < b[j].MinTime return a.MinTime < b.MinTime
} }
func (b metaByMinTimeAndMinRef) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (oh *OOOHeadIndexReader) Postings(name string, values ...string) (index.Postings, error) { func (oh *OOOHeadIndexReader) Postings(name string, values ...string) (index.Postings, error) {
switch len(values) { switch len(values) {
case 0: case 0:

View file

@ -22,12 +22,14 @@ import (
"time" "time"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/storage"
"github.com/prometheus/prometheus/tsdb/chunkenc" "github.com/prometheus/prometheus/tsdb/chunkenc"
"github.com/prometheus/prometheus/tsdb/chunks" "github.com/prometheus/prometheus/tsdb/chunks"
"github.com/prometheus/prometheus/tsdb/tsdbutil" "github.com/prometheus/prometheus/tsdb/tsdbutil"
"github.com/prometheus/prometheus/tsdb/wlog"
) )
type chunkInterval struct { type chunkInterval struct {
@ -294,7 +296,7 @@ func TestOOOHeadIndexReader_Series(t *testing.T) {
for perm, intervals := range permutations { for perm, intervals := range permutations {
for _, headChunk := range []bool{false, true} { for _, headChunk := range []bool{false, true} {
t.Run(fmt.Sprintf("name=%s, permutation=%d, headChunk=%t", tc.name, perm, headChunk), func(t *testing.T) { t.Run(fmt.Sprintf("name=%s, permutation=%d, headChunk=%t", tc.name, perm, headChunk), func(t *testing.T) {
h, _ := newTestHead(t, 1000, false, true) h, _ := newTestHead(t, 1000, wlog.CompressionNone, true)
defer func() { defer func() {
require.NoError(t, h.Close()) require.NoError(t, h.Close())
}() }()
@ -337,7 +339,7 @@ func TestOOOHeadIndexReader_Series(t *testing.T) {
} }
expChunks = append(expChunks, meta) expChunks = append(expChunks, meta)
} }
sort.Sort(metaByMinTimeAndMinRef(expChunks)) // we always want the chunks to come back sorted by minTime asc slices.SortFunc(expChunks, lessByMinTimeAndMinRef) // We always want the chunks to come back sorted by minTime asc.
if headChunk && len(intervals) > 0 { if headChunk && len(intervals) > 0 {
// Put the last interval in the head chunk // Put the last interval in the head chunk
@ -374,7 +376,7 @@ func TestOOOHeadIndexReader_Series(t *testing.T) {
func TestOOOHeadChunkReader_LabelValues(t *testing.T) { func TestOOOHeadChunkReader_LabelValues(t *testing.T) {
chunkRange := int64(2000) chunkRange := int64(2000)
head, _ := newTestHead(t, chunkRange, false, true) head, _ := newTestHead(t, chunkRange, wlog.CompressionNone, true)
t.Cleanup(func() { require.NoError(t, head.Close()) }) t.Cleanup(func() { require.NoError(t, head.Close()) })
app := head.Appender(context.Background()) app := head.Appender(context.Background())
@ -1116,7 +1118,7 @@ func TestSortByMinTimeAndMinRef(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
t.Run(fmt.Sprintf("name=%s", tc.name), func(t *testing.T) { t.Run(fmt.Sprintf("name=%s", tc.name), func(t *testing.T) {
sort.Sort(byMinTimeAndMinRef(tc.input)) slices.SortFunc(tc.input, refLessByMinTimeAndMinRef)
require.Equal(t, tc.exp, tc.input) require.Equal(t, tc.exp, tc.input)
}) })
} }
@ -1180,7 +1182,7 @@ func TestSortMetaByMinTimeAndMinRef(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
t.Run(fmt.Sprintf("name=%s", tc.name), func(t *testing.T) { t.Run(fmt.Sprintf("name=%s", tc.name), func(t *testing.T) {
sort.Sort(metaByMinTimeAndMinRef(tc.inputMetas)) slices.SortFunc(tc.inputMetas, lessByMinTimeAndMinRef)
require.Equal(t, tc.expMetas, tc.inputMetas) require.Equal(t, tc.expMetas, tc.inputMetas)
}) })
} }

View file

@ -1226,7 +1226,7 @@ func MigrateWAL(logger log.Logger, dir string) (err error) {
if err := os.RemoveAll(tmpdir); err != nil { if err := os.RemoveAll(tmpdir); err != nil {
return errors.Wrap(err, "cleanup replacement dir") return errors.Wrap(err, "cleanup replacement dir")
} }
repl, err := wlog.New(logger, nil, tmpdir, false) repl, err := wlog.New(logger, nil, tmpdir, wlog.CompressionNone)
if err != nil { if err != nil {
return errors.Wrap(err, "open new WAL") return errors.Wrap(err, "open new WAL")
} }

View file

@ -450,7 +450,7 @@ func TestMigrateWAL_Empty(t *testing.T) {
wdir := path.Join(dir, "wal") wdir := path.Join(dir, "wal")
// Initialize empty WAL. // Initialize empty WAL.
w, err := wlog.New(nil, nil, wdir, false) w, err := wlog.New(nil, nil, wdir, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, w.Close()) require.NoError(t, w.Close())
@ -493,7 +493,7 @@ func TestMigrateWAL_Fuzz(t *testing.T) {
// Perform migration. // Perform migration.
require.NoError(t, MigrateWAL(nil, wdir)) require.NoError(t, MigrateWAL(nil, wdir))
w, err := wlog.New(nil, nil, wdir, false) w, err := wlog.New(nil, nil, wdir, wlog.CompressionNone)
require.NoError(t, err) require.NoError(t, err)
// We can properly write some new data after migration. // We can properly write some new data after migration.

View file

@ -20,13 +20,13 @@ import (
"math" "math"
"os" "os"
"path/filepath" "path/filepath"
"sort"
"strconv" "strconv"
"strings" "strings"
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/go-kit/log/level" "github.com/go-kit/log/level"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/tsdb/chunks" "github.com/prometheus/prometheus/tsdb/chunks"
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors" tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
@ -134,7 +134,7 @@ func Checkpoint(logger log.Logger, w *WL, from, to int, keep func(id chunks.Head
if err := os.MkdirAll(cpdirtmp, 0o777); err != nil { if err := os.MkdirAll(cpdirtmp, 0o777); err != nil {
return nil, errors.Wrap(err, "create checkpoint dir") return nil, errors.Wrap(err, "create checkpoint dir")
} }
cp, err := New(nil, nil, cpdirtmp, w.CompressionEnabled()) cp, err := New(nil, nil, cpdirtmp, w.CompressionType())
if err != nil { if err != nil {
return nil, errors.Wrap(err, "open checkpoint") return nil, errors.Wrap(err, "open checkpoint")
} }
@ -374,8 +374,8 @@ func listCheckpoints(dir string) (refs []checkpointRef, err error) {
refs = append(refs, checkpointRef{name: fi.Name(), index: idx}) refs = append(refs, checkpointRef{name: fi.Name(), index: idx})
} }
sort.Slice(refs, func(i, j int) bool { slices.SortFunc(refs, func(a, b checkpointRef) bool {
return refs[i].index < refs[j].index return a.index < b.index
}) })
return refs, nil return refs, nil

View file

@ -126,8 +126,8 @@ func TestCheckpoint(t *testing.T) {
} }
} }
for _, compress := range []bool{false, true} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
var enc record.Encoder var enc record.Encoder
@ -303,7 +303,7 @@ func TestCheckpoint(t *testing.T) {
func TestCheckpointNoTmpFolderAfterError(t *testing.T) { func TestCheckpointNoTmpFolderAfterError(t *testing.T) {
// Create a new wlog with invalid data. // Create a new wlog with invalid data.
dir := t.TempDir() dir := t.TempDir()
w, err := NewSize(nil, nil, dir, 64*1024, false) w, err := NewSize(nil, nil, dir, 64*1024, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
var enc record.Encoder var enc record.Encoder
require.NoError(t, w.Log(enc.Series([]record.RefSeries{ require.NoError(t, w.Log(enc.Series([]record.RefSeries{

View file

@ -23,6 +23,7 @@ import (
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/go-kit/log/level" "github.com/go-kit/log/level"
"github.com/golang/snappy" "github.com/golang/snappy"
"github.com/klauspost/compress/zstd"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -51,10 +52,14 @@ func NewLiveReaderMetrics(reg prometheus.Registerer) *LiveReaderMetrics {
// NewLiveReader returns a new live reader. // NewLiveReader returns a new live reader.
func NewLiveReader(logger log.Logger, metrics *LiveReaderMetrics, r io.Reader) *LiveReader { func NewLiveReader(logger log.Logger, metrics *LiveReaderMetrics, r io.Reader) *LiveReader {
// Calling zstd.NewReader with a nil io.Reader and no options cannot return an error.
zstdReader, _ := zstd.NewReader(nil)
lr := &LiveReader{ lr := &LiveReader{
logger: logger, logger: logger,
rdr: r, rdr: r,
metrics: metrics, zstdReader: zstdReader,
metrics: metrics,
// Until we understand how they come about, make readers permissive // Until we understand how they come about, make readers permissive
// to records spanning pages. // to records spanning pages.
@ -68,17 +73,18 @@ func NewLiveReader(logger log.Logger, metrics *LiveReaderMetrics, r io.Reader) *
// that are still in the process of being written, and returns records as soon // that are still in the process of being written, and returns records as soon
// as they can be read. // as they can be read.
type LiveReader struct { type LiveReader struct {
logger log.Logger logger log.Logger
rdr io.Reader rdr io.Reader
err error err error
rec []byte rec []byte
snappyBuf []byte compressBuf []byte
hdr [recordHeaderSize]byte zstdReader *zstd.Decoder
buf [pageSize]byte hdr [recordHeaderSize]byte
readIndex int // Index in buf to start at for next read. buf [pageSize]byte
writeIndex int // Index in buf to start at for next write. readIndex int // Index in buf to start at for next read.
total int64 // Total bytes processed during reading in calls to Next(). writeIndex int // Index in buf to start at for next write.
index int // Used to track partial records, should be 0 at the start of every new record. total int64 // Total bytes processed during reading in calls to Next().
index int // Used to track partial records, should be 0 at the start of every new record.
// For testing, we can treat EOF as a non-error. // For testing, we can treat EOF as a non-error.
eofNonErr bool eofNonErr bool
@ -191,12 +197,14 @@ func (r *LiveReader) buildRecord() (bool, error) {
rt := recTypeFromHeader(r.hdr[0]) rt := recTypeFromHeader(r.hdr[0])
if rt == recFirst || rt == recFull { if rt == recFirst || rt == recFull {
r.rec = r.rec[:0] r.rec = r.rec[:0]
r.snappyBuf = r.snappyBuf[:0] r.compressBuf = r.compressBuf[:0]
} }
compressed := r.hdr[0]&snappyMask != 0 isSnappyCompressed := r.hdr[0]&snappyMask == snappyMask
if compressed { isZstdCompressed := r.hdr[0]&zstdMask == zstdMask
r.snappyBuf = append(r.snappyBuf, temp...)
if isSnappyCompressed || isZstdCompressed {
r.compressBuf = append(r.compressBuf, temp...)
} else { } else {
r.rec = append(r.rec, temp...) r.rec = append(r.rec, temp...)
} }
@ -207,12 +215,17 @@ func (r *LiveReader) buildRecord() (bool, error) {
} }
if rt == recLast || rt == recFull { if rt == recLast || rt == recFull {
r.index = 0 r.index = 0
if compressed && len(r.snappyBuf) > 0 { if isSnappyCompressed && len(r.compressBuf) > 0 {
// The snappy library uses `len` to calculate if we need a new buffer. // The snappy library uses `len` to calculate if we need a new buffer.
// In order to allocate as few buffers as possible make the length // In order to allocate as few buffers as possible make the length
// equal to the capacity. // equal to the capacity.
r.rec = r.rec[:cap(r.rec)] r.rec = r.rec[:cap(r.rec)]
r.rec, err = snappy.Decode(r.rec, r.snappyBuf) r.rec, err = snappy.Decode(r.rec, r.compressBuf)
if err != nil {
return false, err
}
} else if isZstdCompressed && len(r.compressBuf) > 0 {
r.rec, err = r.zstdReader.DecodeAll(r.compressBuf, r.rec[:0])
if err != nil { if err != nil {
return false, err return false, err
} }

View file

@ -20,23 +20,27 @@ import (
"io" "io"
"github.com/golang/snappy" "github.com/golang/snappy"
"github.com/klauspost/compress/zstd"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// Reader reads WAL records from an io.Reader. // Reader reads WAL records from an io.Reader.
type Reader struct { type Reader struct {
rdr io.Reader rdr io.Reader
err error err error
rec []byte rec []byte
snappyBuf []byte compressBuf []byte
buf [pageSize]byte zstdReader *zstd.Decoder
total int64 // Total bytes processed. buf [pageSize]byte
curRecTyp recType // Used for checking that the last record is not torn. total int64 // Total bytes processed.
curRecTyp recType // Used for checking that the last record is not torn.
} }
// NewReader returns a new reader. // NewReader returns a new reader.
func NewReader(r io.Reader) *Reader { func NewReader(r io.Reader) *Reader {
return &Reader{rdr: r} // Calling zstd.NewReader with a nil io.Reader and no options cannot return an error.
zstdReader, _ := zstd.NewReader(nil)
return &Reader{rdr: r, zstdReader: zstdReader}
} }
// Next advances the reader to the next records and returns true if it exists. // Next advances the reader to the next records and returns true if it exists.
@ -63,7 +67,7 @@ func (r *Reader) next() (err error) {
buf := r.buf[recordHeaderSize:] buf := r.buf[recordHeaderSize:]
r.rec = r.rec[:0] r.rec = r.rec[:0]
r.snappyBuf = r.snappyBuf[:0] r.compressBuf = r.compressBuf[:0]
i := 0 i := 0
for { for {
@ -72,7 +76,8 @@ func (r *Reader) next() (err error) {
} }
r.total++ r.total++
r.curRecTyp = recTypeFromHeader(hdr[0]) r.curRecTyp = recTypeFromHeader(hdr[0])
compressed := hdr[0]&snappyMask != 0 isSnappyCompressed := hdr[0]&snappyMask == snappyMask
isZstdCompressed := hdr[0]&zstdMask == zstdMask
// Gobble up zero bytes. // Gobble up zero bytes.
if r.curRecTyp == recPageTerm { if r.curRecTyp == recPageTerm {
@ -128,8 +133,8 @@ func (r *Reader) next() (err error) {
return errors.Errorf("unexpected checksum %x, expected %x", c, crc) return errors.Errorf("unexpected checksum %x, expected %x", c, crc)
} }
if compressed { if isSnappyCompressed || isZstdCompressed {
r.snappyBuf = append(r.snappyBuf, buf[:length]...) r.compressBuf = append(r.compressBuf, buf[:length]...)
} else { } else {
r.rec = append(r.rec, buf[:length]...) r.rec = append(r.rec, buf[:length]...)
} }
@ -138,12 +143,15 @@ func (r *Reader) next() (err error) {
return err return err
} }
if r.curRecTyp == recLast || r.curRecTyp == recFull { if r.curRecTyp == recLast || r.curRecTyp == recFull {
if compressed && len(r.snappyBuf) > 0 { if isSnappyCompressed && len(r.compressBuf) > 0 {
// The snappy library uses `len` to calculate if we need a new buffer. // The snappy library uses `len` to calculate if we need a new buffer.
// In order to allocate as few buffers as possible make the length // In order to allocate as few buffers as possible make the length
// equal to the capacity. // equal to the capacity.
r.rec = r.rec[:cap(r.rec)] r.rec = r.rec[:cap(r.rec)]
r.rec, err = snappy.Decode(r.rec, r.snappyBuf) r.rec, err = snappy.Decode(r.rec, r.compressBuf)
return err
} else if isZstdCompressed && len(r.compressBuf) > 0 {
r.rec, err = r.zstdReader.DecodeAll(r.compressBuf, r.rec[:0])
return err return err
} }
return nil return nil

View file

@ -310,8 +310,8 @@ func allSegments(dir string) (io.ReadCloser, error) {
func TestReaderFuzz(t *testing.T) { func TestReaderFuzz(t *testing.T) {
for name, fn := range readerConstructors { for name, fn := range readerConstructors {
for _, compress := range []bool{false, true} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
t.Run(fmt.Sprintf("%s,compress=%t", name, compress), func(t *testing.T) { t.Run(fmt.Sprintf("%s,compress=%s", name, compress), func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
w, err := NewSize(nil, nil, dir, 128*pageSize, compress) w, err := NewSize(nil, nil, dir, 128*pageSize, compress)
@ -349,8 +349,8 @@ func TestReaderFuzz(t *testing.T) {
func TestReaderFuzz_Live(t *testing.T) { func TestReaderFuzz_Live(t *testing.T) {
logger := testutil.NewLogger(t) logger := testutil.NewLogger(t)
for _, compress := range []bool{false, true} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
w, err := NewSize(nil, nil, dir, 128*pageSize, compress) w, err := NewSize(nil, nil, dir, 128*pageSize, compress)
@ -439,7 +439,7 @@ func TestLiveReaderCorrupt_ShortFile(t *testing.T) {
logger := testutil.NewLogger(t) logger := testutil.NewLogger(t)
dir := t.TempDir() dir := t.TempDir()
w, err := NewSize(nil, nil, dir, pageSize, false) w, err := NewSize(nil, nil, dir, pageSize, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
rec := make([]byte, pageSize-recordHeaderSize) rec := make([]byte, pageSize-recordHeaderSize)
@ -479,7 +479,7 @@ func TestLiveReaderCorrupt_RecordTooLongAndShort(t *testing.T) {
logger := testutil.NewLogger(t) logger := testutil.NewLogger(t)
dir := t.TempDir() dir := t.TempDir()
w, err := NewSize(nil, nil, dir, pageSize*2, false) w, err := NewSize(nil, nil, dir, pageSize*2, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
rec := make([]byte, pageSize-recordHeaderSize) rec := make([]byte, pageSize-recordHeaderSize)
@ -526,7 +526,7 @@ func TestReaderData(t *testing.T) {
for name, fn := range readerConstructors { for name, fn := range readerConstructors {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
w, err := New(nil, nil, dir, true) w, err := New(nil, nil, dir, CompressionSnappy)
require.NoError(t, err) require.NoError(t, err)
sr, err := allSegments(dir) sr, err := allSegments(dir)

View file

@ -122,8 +122,8 @@ func TestTailSamples(t *testing.T) {
const samplesCount = 250 const samplesCount = 250
const exemplarsCount = 25 const exemplarsCount = 25
const histogramsCount = 50 const histogramsCount = 50
for _, compress := range []bool{false, true} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
now := time.Now() now := time.Now()
dir := t.TempDir() dir := t.TempDir()
@ -246,8 +246,8 @@ func TestReadToEndNoCheckpoint(t *testing.T) {
const seriesCount = 10 const seriesCount = 10
const samplesCount = 250 const samplesCount = 250
for _, compress := range []bool{false, true} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wdir := path.Join(dir, "wal") wdir := path.Join(dir, "wal")
err := os.Mkdir(wdir, 0o777) err := os.Mkdir(wdir, 0o777)
@ -314,8 +314,8 @@ func TestReadToEndWithCheckpoint(t *testing.T) {
const seriesCount = 10 const seriesCount = 10
const samplesCount = 250 const samplesCount = 250
for _, compress := range []bool{false, true} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wdir := path.Join(dir, "wal") wdir := path.Join(dir, "wal")
@ -402,8 +402,8 @@ func TestReadCheckpoint(t *testing.T) {
const seriesCount = 10 const seriesCount = 10
const samplesCount = 250 const samplesCount = 250
for _, compress := range []bool{false, true} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wdir := path.Join(dir, "wal") wdir := path.Join(dir, "wal")
@ -475,8 +475,8 @@ func TestReadCheckpointMultipleSegments(t *testing.T) {
const seriesCount = 20 const seriesCount = 20
const samplesCount = 300 const samplesCount = 300
for _, compress := range []bool{false, true} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
t.Run(fmt.Sprintf("compress=%t", compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", compress), func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wdir := path.Join(dir, "wal") wdir := path.Join(dir, "wal")
@ -546,15 +546,15 @@ func TestCheckpointSeriesReset(t *testing.T) {
const seriesCount = 20 const seriesCount = 20
const samplesCount = 350 const samplesCount = 350
testCases := []struct { testCases := []struct {
compress bool compress CompressionType
segments int segments int
}{ }{
{compress: false, segments: 14}, {compress: CompressionNone, segments: 14},
{compress: true, segments: 13}, {compress: CompressionSnappy, segments: 13},
} }
for _, tc := range testCases { for _, tc := range testCases {
t.Run(fmt.Sprintf("compress=%t", tc.compress), func(t *testing.T) { t.Run(fmt.Sprintf("compress=%s", tc.compress), func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
wdir := path.Join(dir, "wal") wdir := path.Join(dir, "wal")

View file

@ -22,7 +22,6 @@ import (
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"sort"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@ -30,8 +29,10 @@ import (
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/go-kit/log/level" "github.com/go-kit/log/level"
"github.com/golang/snappy" "github.com/golang/snappy"
"github.com/klauspost/compress/zstd"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/tsdb/fileutil" "github.com/prometheus/prometheus/tsdb/fileutil"
) )
@ -164,6 +165,26 @@ func OpenReadSegment(fn string) (*Segment, error) {
return &Segment{SegmentFile: f, i: k, dir: filepath.Dir(fn)}, nil return &Segment{SegmentFile: f, i: k, dir: filepath.Dir(fn)}, nil
} }
type CompressionType string
const (
CompressionNone CompressionType = "none"
CompressionSnappy CompressionType = "snappy"
CompressionZstd CompressionType = "zstd"
)
// ParseCompressionType parses the two compression-related configuration values and returns the CompressionType. If
// compression is enabled but the compressType is unrecognized, we default to Snappy compression.
func ParseCompressionType(compress bool, compressType string) CompressionType {
if compress {
if compressType == "zstd" {
return CompressionZstd
}
return CompressionSnappy
}
return CompressionNone
}
// WL is a write log that stores records in segment files. // WL is a write log that stores records in segment files.
// It must be read from start to end once before logging new data. // It must be read from start to end once before logging new data.
// If an error occurs during read, the repair procedure must be called // If an error occurs during read, the repair procedure must be called
@ -185,8 +206,9 @@ type WL struct {
stopc chan chan struct{} stopc chan chan struct{}
actorc chan func() actorc chan func()
closed bool // To allow calling Close() more than once without blocking. closed bool // To allow calling Close() more than once without blocking.
compress bool compress CompressionType
snappyBuf []byte compressBuf []byte
zstdWriter *zstd.Encoder
WriteNotified WriteNotified WriteNotified WriteNotified
@ -265,13 +287,13 @@ func newWLMetrics(w *WL, r prometheus.Registerer) *wlMetrics {
} }
// New returns a new WAL over the given directory. // New returns a new WAL over the given directory.
func New(logger log.Logger, reg prometheus.Registerer, dir string, compress bool) (*WL, error) { func New(logger log.Logger, reg prometheus.Registerer, dir string, compress CompressionType) (*WL, error) {
return NewSize(logger, reg, dir, DefaultSegmentSize, compress) return NewSize(logger, reg, dir, DefaultSegmentSize, compress)
} }
// NewSize returns a new write log over the given directory. // NewSize returns a new write log over the given directory.
// New segments are created with the specified size. // New segments are created with the specified size.
func NewSize(logger log.Logger, reg prometheus.Registerer, dir string, segmentSize int, compress bool) (*WL, error) { func NewSize(logger log.Logger, reg prometheus.Registerer, dir string, segmentSize int, compress CompressionType) (*WL, error) {
if segmentSize%pageSize != 0 { if segmentSize%pageSize != 0 {
return nil, errors.New("invalid segment size") return nil, errors.New("invalid segment size")
} }
@ -281,6 +303,16 @@ func NewSize(logger log.Logger, reg prometheus.Registerer, dir string, segmentSi
if logger == nil { if logger == nil {
logger = log.NewNopLogger() logger = log.NewNopLogger()
} }
var zstdWriter *zstd.Encoder
if compress == CompressionZstd {
var err error
zstdWriter, err = zstd.NewWriter(nil)
if err != nil {
return nil, err
}
}
w := &WL{ w := &WL{
dir: dir, dir: dir,
logger: logger, logger: logger,
@ -289,6 +321,7 @@ func NewSize(logger log.Logger, reg prometheus.Registerer, dir string, segmentSi
actorc: make(chan func(), 100), actorc: make(chan func(), 100),
stopc: make(chan chan struct{}), stopc: make(chan chan struct{}),
compress: compress, compress: compress,
zstdWriter: zstdWriter,
} }
prefix := "prometheus_tsdb_wal_" prefix := "prometheus_tsdb_wal_"
if filepath.Base(dir) == WblDirName { if filepath.Base(dir) == WblDirName {
@ -327,16 +360,22 @@ func Open(logger log.Logger, dir string) (*WL, error) {
if logger == nil { if logger == nil {
logger = log.NewNopLogger() logger = log.NewNopLogger()
} }
zstdWriter, err := zstd.NewWriter(nil)
if err != nil {
return nil, err
}
w := &WL{ w := &WL{
dir: dir, dir: dir,
logger: logger, logger: logger,
zstdWriter: zstdWriter,
} }
return w, nil return w, nil
} }
// CompressionEnabled returns if compression is enabled on this WAL. // CompressionType returns if compression is enabled on this WAL.
func (w *WL) CompressionEnabled() bool { func (w *WL) CompressionType() CompressionType {
return w.compress return w.compress
} }
@ -583,9 +622,10 @@ func (w *WL) flushPage(clear bool) error {
} }
// First Byte of header format: // First Byte of header format:
// [ 4 bits unallocated] [1 bit snappy compression flag] [ 3 bit record type ] // [3 bits unallocated] [1 bit zstd compression flag] [1 bit snappy compression flag] [3 bit record type ]
const ( const (
snappyMask = 1 << 3 snappyMask = 1 << 3
zstdMask = 1 << 4
recTypeMask = snappyMask - 1 recTypeMask = snappyMask - 1
) )
@ -655,17 +695,23 @@ func (w *WL) log(rec []byte, final bool) error {
// Compress the record before calculating if a new segment is needed. // Compress the record before calculating if a new segment is needed.
compressed := false compressed := false
if w.compress && if w.compress == CompressionSnappy && len(rec) > 0 {
len(rec) > 0 &&
// If MaxEncodedLen is less than 0 the record is too large to be compressed. // If MaxEncodedLen is less than 0 the record is too large to be compressed.
snappy.MaxEncodedLen(len(rec)) >= 0 { if len(rec) > 0 && snappy.MaxEncodedLen(len(rec)) >= 0 {
// The snappy library uses `len` to calculate if we need a new buffer. // The snappy library uses `len` to calculate if we need a new buffer.
// In order to allocate as few buffers as possible make the length // In order to allocate as few buffers as possible make the length
// equal to the capacity. // equal to the capacity.
w.snappyBuf = w.snappyBuf[:cap(w.snappyBuf)] w.compressBuf = w.compressBuf[:cap(w.compressBuf)]
w.snappyBuf = snappy.Encode(w.snappyBuf, rec) w.compressBuf = snappy.Encode(w.compressBuf, rec)
if len(w.snappyBuf) < len(rec) { if len(w.compressBuf) < len(rec) {
rec = w.snappyBuf rec = w.compressBuf
compressed = true
}
}
} else if w.compress == CompressionZstd && len(rec) > 0 {
w.compressBuf = w.zstdWriter.EncodeAll(rec, w.compressBuf[:0])
if len(w.compressBuf) < len(rec) {
rec = w.compressBuf
compressed = true compressed = true
} }
} }
@ -706,7 +752,11 @@ func (w *WL) log(rec []byte, final bool) error {
typ = recMiddle typ = recMiddle
} }
if compressed { if compressed {
typ |= snappyMask if w.compress == CompressionSnappy {
typ |= snappyMask
} else if w.compress == CompressionZstd {
typ |= zstdMask
}
} }
buf[0] = byte(typ) buf[0] = byte(typ)
@ -859,8 +909,8 @@ func listSegments(dir string) (refs []segmentRef, err error) {
} }
refs = append(refs, segmentRef{name: fn, index: k}) refs = append(refs, segmentRef{name: fn, index: k})
} }
sort.Slice(refs, func(i, j int) bool { slices.SortFunc(refs, func(a, b segmentRef) bool {
return refs[i].index < refs[j].index return a.index < b.index
}) })
for i := 0; i < len(refs)-1; i++ { for i := 0; i < len(refs)-1; i++ {
if refs[i].index+1 != refs[i+1].index { if refs[i].index+1 != refs[i+1].index {

View file

@ -123,7 +123,7 @@ func TestWALRepair_ReadingError(t *testing.T) {
// then corrupt a given record in a given segment. // then corrupt a given record in a given segment.
// As a result we want a repaired WAL with given intact records. // As a result we want a repaired WAL with given intact records.
segSize := 3 * pageSize segSize := 3 * pageSize
w, err := NewSize(nil, nil, dir, segSize, false) w, err := NewSize(nil, nil, dir, segSize, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
var records [][]byte var records [][]byte
@ -148,7 +148,7 @@ func TestWALRepair_ReadingError(t *testing.T) {
require.NoError(t, f.Close()) require.NoError(t, f.Close())
w, err = NewSize(nil, nil, dir, segSize, false) w, err = NewSize(nil, nil, dir, segSize, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
defer w.Close() defer w.Close()
@ -222,7 +222,7 @@ func TestCorruptAndCarryOn(t *testing.T) {
// Produce a WAL with a two segments of 3 pages with 3 records each, // Produce a WAL with a two segments of 3 pages with 3 records each,
// so when we truncate the file we're guaranteed to split a record. // so when we truncate the file we're guaranteed to split a record.
{ {
w, err := NewSize(logger, nil, dir, segmentSize, false) w, err := NewSize(logger, nil, dir, segmentSize, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
for i := 0; i < 18; i++ { for i := 0; i < 18; i++ {
@ -293,7 +293,7 @@ func TestCorruptAndCarryOn(t *testing.T) {
err = sr.Close() err = sr.Close()
require.NoError(t, err) require.NoError(t, err)
w, err := NewSize(logger, nil, dir, segmentSize, false) w, err := NewSize(logger, nil, dir, segmentSize, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
err = w.Repair(corruptionErr) err = w.Repair(corruptionErr)
@ -336,7 +336,7 @@ func TestCorruptAndCarryOn(t *testing.T) {
// TestClose ensures that calling Close more than once doesn't panic and doesn't block. // TestClose ensures that calling Close more than once doesn't panic and doesn't block.
func TestClose(t *testing.T) { func TestClose(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
w, err := NewSize(nil, nil, dir, pageSize, false) w, err := NewSize(nil, nil, dir, pageSize, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, w.Close()) require.NoError(t, w.Close())
require.Error(t, w.Close()) require.Error(t, w.Close())
@ -349,7 +349,7 @@ func TestSegmentMetric(t *testing.T) {
) )
dir := t.TempDir() dir := t.TempDir()
w, err := NewSize(nil, nil, dir, segmentSize, false) w, err := NewSize(nil, nil, dir, segmentSize, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
initialSegment := client_testutil.ToFloat64(w.metrics.currentSegment) initialSegment := client_testutil.ToFloat64(w.metrics.currentSegment)
@ -368,7 +368,7 @@ func TestSegmentMetric(t *testing.T) {
} }
func TestCompression(t *testing.T) { func TestCompression(t *testing.T) {
bootstrap := func(compressed bool) string { bootstrap := func(compressed CompressionType) string {
const ( const (
segmentSize = pageSize segmentSize = pageSize
recordSize = (pageSize / 2) - recordHeaderSize recordSize = (pageSize / 2) - recordHeaderSize
@ -389,21 +389,27 @@ func TestCompression(t *testing.T) {
return dirPath return dirPath
} }
dirCompressed := bootstrap(true) tmpDirs := make([]string, 0, 3)
defer func() { defer func() {
require.NoError(t, os.RemoveAll(dirCompressed)) for _, dir := range tmpDirs {
}() require.NoError(t, os.RemoveAll(dir))
dirUnCompressed := bootstrap(false) }
defer func() {
require.NoError(t, os.RemoveAll(dirUnCompressed))
}() }()
uncompressedSize, err := fileutil.DirSize(dirUnCompressed) dirUnCompressed := bootstrap(CompressionNone)
require.NoError(t, err) tmpDirs = append(tmpDirs, dirUnCompressed)
compressedSize, err := fileutil.DirSize(dirCompressed)
require.NoError(t, err)
require.Greater(t, float64(uncompressedSize)*0.75, float64(compressedSize), "Compressing zeroes should save at least 25%% space - uncompressedSize: %d, compressedSize: %d", uncompressedSize, compressedSize) for _, compressionType := range []CompressionType{CompressionSnappy, CompressionZstd} {
dirCompressed := bootstrap(compressionType)
tmpDirs = append(tmpDirs, dirCompressed)
uncompressedSize, err := fileutil.DirSize(dirUnCompressed)
require.NoError(t, err)
compressedSize, err := fileutil.DirSize(dirCompressed)
require.NoError(t, err)
require.Greater(t, float64(uncompressedSize)*0.75, float64(compressedSize), "Compressing zeroes should save at least 25%% space - uncompressedSize: %d, compressedSize: %d", uncompressedSize, compressedSize)
}
} }
func TestLogPartialWrite(t *testing.T) { func TestLogPartialWrite(t *testing.T) {
@ -437,7 +443,7 @@ func TestLogPartialWrite(t *testing.T) {
t.Run(testName, func(t *testing.T) { t.Run(testName, func(t *testing.T) {
dirPath := t.TempDir() dirPath := t.TempDir()
w, err := NewSize(nil, nil, dirPath, segmentSize, false) w, err := NewSize(nil, nil, dirPath, segmentSize, CompressionNone)
require.NoError(t, err) require.NoError(t, err)
// Replace the underlying segment file with a mocked one that injects a failure. // Replace the underlying segment file with a mocked one that injects a failure.
@ -504,8 +510,8 @@ func (f *faultySegmentFile) Write(p []byte) (int, error) {
} }
func BenchmarkWAL_LogBatched(b *testing.B) { func BenchmarkWAL_LogBatched(b *testing.B) {
for _, compress := range []bool{true, false} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
b.Run(fmt.Sprintf("compress=%t", compress), func(b *testing.B) { b.Run(fmt.Sprintf("compress=%s", compress), func(b *testing.B) {
dir := b.TempDir() dir := b.TempDir()
w, err := New(nil, nil, dir, compress) w, err := New(nil, nil, dir, compress)
@ -534,8 +540,8 @@ func BenchmarkWAL_LogBatched(b *testing.B) {
} }
func BenchmarkWAL_Log(b *testing.B) { func BenchmarkWAL_Log(b *testing.B) {
for _, compress := range []bool{true, false} { for _, compress := range []CompressionType{CompressionNone, CompressionSnappy, CompressionZstd} {
b.Run(fmt.Sprintf("compress=%t", compress), func(b *testing.B) { b.Run(fmt.Sprintf("compress=%s", compress), func(b *testing.B) {
dir := b.TempDir() dir := b.TempDir()
w, err := New(nil, nil, dir, compress) w, err := New(nil, nil, dir, compress)

View file

@ -26,6 +26,7 @@ import (
"strings" "strings"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/grafana/regexp"
) )
// GenerateMarkdown generates the markdown documentation for an application from // GenerateMarkdown generates the markdown documentation for an application from
@ -230,6 +231,7 @@ func writeSubcommands(writer io.Writer, level int, modelName string, commands []
if cmd.HelpLong != "" { if cmd.HelpLong != "" {
help = cmd.HelpLong help = cmd.HelpLong
} }
help = formatHyphenatedWords(help)
if _, err := writer.Write([]byte(fmt.Sprintf("\n\n%s `%s %s`\n\n%s\n\n", strings.Repeat("#", level+1), modelName, cmd.FullCommand, help))); err != nil { if _, err := writer.Write([]byte(fmt.Sprintf("\n\n%s `%s %s`\n\n%s\n\n", strings.Repeat("#", level+1), modelName, cmd.FullCommand, help))); err != nil {
return err return err
} }
@ -250,3 +252,11 @@ func writeSubcommands(writer io.Writer, level int, modelName string, commands []
} }
return nil return nil
} }
func formatHyphenatedWords(input string) string {
hyphenRegex := regexp.MustCompile(`\B--\w+\b`)
replacer := func(s string) string {
return fmt.Sprintf("`%s`", s)
}
return hyphenRegex.ReplaceAllStringFunc(input, replacer)
}

View file

@ -16,8 +16,9 @@ package stats
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"sort"
"time" "time"
"golang.org/x/exp/slices"
) )
// A Timer that can be started and stopped and accumulates the total time it // A Timer that can be started and stopped and accumulates the total time it
@ -78,35 +79,17 @@ func (t *TimerGroup) GetTimer(name fmt.Stringer) *Timer {
return timer return timer
} }
// Timers is a slice of Timer pointers that implements Len and Swap from
// sort.Interface.
type Timers []*Timer
type byCreationTimeSorter struct{ Timers }
// Len implements sort.Interface.
func (t Timers) Len() int {
return len(t)
}
// Swap implements sort.Interface.
func (t Timers) Swap(i, j int) {
t[i], t[j] = t[j], t[i]
}
func (s byCreationTimeSorter) Less(i, j int) bool {
return s.Timers[i].created < s.Timers[j].created
}
// Return a string representation of a TimerGroup. // Return a string representation of a TimerGroup.
func (t *TimerGroup) String() string { func (t *TimerGroup) String() string {
timers := byCreationTimeSorter{} timers := make([]*Timer, 0, len(t.timers))
for _, timer := range t.timers { for _, timer := range t.timers {
timers.Timers = append(timers.Timers, timer) timers = append(timers, timer)
} }
sort.Sort(timers) slices.SortFunc(timers, func(a, b *Timer) bool {
return a.created < b.created
})
result := &bytes.Buffer{} result := &bytes.Buffer{}
for _, timer := range timers.Timers { for _, timer := range timers {
fmt.Fprintf(result, "%s\n", timer) fmt.Fprintf(result, "%s\n", timer)
} }
return result.String() return result.String()

View file

@ -569,11 +569,11 @@ func (api *API) queryRange(r *http.Request) (result apiFuncResult) {
} }
func (api *API) queryExemplars(r *http.Request) apiFuncResult { func (api *API) queryExemplars(r *http.Request) apiFuncResult {
start, err := parseTimeParam(r, "start", minTime) start, err := parseTimeParam(r, "start", MinTime)
if err != nil { if err != nil {
return invalidParamError(err, "start") return invalidParamError(err, "start")
} }
end, err := parseTimeParam(r, "end", maxTime) end, err := parseTimeParam(r, "end", MaxTime)
if err != nil { if err != nil {
return invalidParamError(err, "end") return invalidParamError(err, "end")
} }
@ -633,11 +633,11 @@ func returnAPIError(err error) *apiError {
} }
func (api *API) labelNames(r *http.Request) apiFuncResult { func (api *API) labelNames(r *http.Request) apiFuncResult {
start, err := parseTimeParam(r, "start", minTime) start, err := parseTimeParam(r, "start", MinTime)
if err != nil { if err != nil {
return invalidParamError(err, "start") return invalidParamError(err, "start")
} }
end, err := parseTimeParam(r, "end", maxTime) end, err := parseTimeParam(r, "end", MaxTime)
if err != nil { if err != nil {
return invalidParamError(err, "end") return invalidParamError(err, "end")
} }
@ -699,11 +699,11 @@ func (api *API) labelValues(r *http.Request) (result apiFuncResult) {
return apiFuncResult{nil, &apiError{errorBadData, errors.Errorf("invalid label name: %q", name)}, nil, nil} return apiFuncResult{nil, &apiError{errorBadData, errors.Errorf("invalid label name: %q", name)}, nil, nil}
} }
start, err := parseTimeParam(r, "start", minTime) start, err := parseTimeParam(r, "start", MinTime)
if err != nil { if err != nil {
return invalidParamError(err, "start") return invalidParamError(err, "start")
} }
end, err := parseTimeParam(r, "end", maxTime) end, err := parseTimeParam(r, "end", MaxTime)
if err != nil { if err != nil {
return invalidParamError(err, "end") return invalidParamError(err, "end")
} }
@ -768,11 +768,16 @@ func (api *API) labelValues(r *http.Request) (result apiFuncResult) {
} }
var ( var (
minTime = time.Unix(math.MinInt64/1000+62135596801, 0).UTC() // MinTime is the default timestamp used for the begin of optional time ranges.
maxTime = time.Unix(math.MaxInt64/1000-62135596801, 999999999).UTC() // Exposed to let downstream projects to reference it.
MinTime = time.Unix(math.MinInt64/1000+62135596801, 0).UTC()
minTimeFormatted = minTime.Format(time.RFC3339Nano) // MaxTime is the default timestamp used for the end of optional time ranges.
maxTimeFormatted = maxTime.Format(time.RFC3339Nano) // Exposed to let downstream projects to reference it.
MaxTime = time.Unix(math.MaxInt64/1000-62135596801, 999999999).UTC()
minTimeFormatted = MinTime.Format(time.RFC3339Nano)
maxTimeFormatted = MaxTime.Format(time.RFC3339Nano)
) )
func (api *API) series(r *http.Request) (result apiFuncResult) { func (api *API) series(r *http.Request) (result apiFuncResult) {
@ -783,11 +788,11 @@ func (api *API) series(r *http.Request) (result apiFuncResult) {
return apiFuncResult{nil, &apiError{errorBadData, errors.New("no match[] parameter provided")}, nil, nil} return apiFuncResult{nil, &apiError{errorBadData, errors.New("no match[] parameter provided")}, nil, nil}
} }
start, err := parseTimeParam(r, "start", minTime) start, err := parseTimeParam(r, "start", MinTime)
if err != nil { if err != nil {
return invalidParamError(err, "start") return invalidParamError(err, "start")
} }
end, err := parseTimeParam(r, "end", maxTime) end, err := parseTimeParam(r, "end", MaxTime)
if err != nil { if err != nil {
return invalidParamError(err, "end") return invalidParamError(err, "end")
} }
@ -1587,11 +1592,11 @@ func (api *API) deleteSeries(r *http.Request) apiFuncResult {
return apiFuncResult{nil, &apiError{errorBadData, errors.New("no match[] parameter provided")}, nil, nil} return apiFuncResult{nil, &apiError{errorBadData, errors.New("no match[] parameter provided")}, nil, nil}
} }
start, err := parseTimeParam(r, "start", minTime) start, err := parseTimeParam(r, "start", MinTime)
if err != nil { if err != nil {
return invalidParamError(err, "start") return invalidParamError(err, "start")
} }
end, err := parseTimeParam(r, "end", maxTime) end, err := parseTimeParam(r, "end", MaxTime)
if err != nil { if err != nil {
return invalidParamError(err, "end") return invalidParamError(err, "end")
} }
@ -1773,9 +1778,9 @@ func parseTime(s string) (time.Time, error) {
// Upstream issue: https://github.com/golang/go/issues/20555 // Upstream issue: https://github.com/golang/go/issues/20555
switch s { switch s {
case minTimeFormatted: case minTimeFormatted:
return minTime, nil return MinTime, nil
case maxTimeFormatted: case maxTimeFormatted:
return maxTime, nil return MaxTime, nil
} }
return time.Time{}, errors.Errorf("cannot parse %q to a valid timestamp", s) return time.Time{}, errors.Errorf("cannot parse %q to a valid timestamp", s)
} }

View file

@ -3141,7 +3141,7 @@ func TestParseTimeParam(t *testing.T) {
{ // When data is valid. { // When data is valid.
paramName: "start", paramName: "start",
paramValue: "1582468023986", paramValue: "1582468023986",
defaultValue: minTime, defaultValue: MinTime,
result: resultType{ result: resultType{
asTime: ts, asTime: ts,
asError: nil, asError: nil,
@ -3150,16 +3150,16 @@ func TestParseTimeParam(t *testing.T) {
{ // When data is empty string. { // When data is empty string.
paramName: "end", paramName: "end",
paramValue: "", paramValue: "",
defaultValue: maxTime, defaultValue: MaxTime,
result: resultType{ result: resultType{
asTime: maxTime, asTime: MaxTime,
asError: nil, asError: nil,
}, },
}, },
{ // When data is not valid. { // When data is not valid.
paramName: "foo", paramName: "foo",
paramValue: "baz", paramValue: "baz",
defaultValue: maxTime, defaultValue: MaxTime,
result: resultType{ result: resultType{
asTime: time.Time{}, asTime: time.Time{},
asError: func() error { asError: func() error {
@ -3230,12 +3230,12 @@ func TestParseTime(t *testing.T) {
result: time.Unix(1543578564, 705*1e6), result: time.Unix(1543578564, 705*1e6),
}, },
{ {
input: minTime.Format(time.RFC3339Nano), input: MinTime.Format(time.RFC3339Nano),
result: minTime, result: MinTime,
}, },
{ {
input: maxTime.Format(time.RFC3339Nano), input: MaxTime.Format(time.RFC3339Nano),
result: maxTime, result: MaxTime,
}, },
} }

View file

@ -25,6 +25,7 @@ import (
dto "github.com/prometheus/client_model/go" dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt" "github.com/prometheus/common/expfmt"
"github.com/prometheus/common/model" "github.com/prometheus/common/model"
"golang.org/x/exp/slices"
"github.com/prometheus/prometheus/model/histogram" "github.com/prometheus/prometheus/model/histogram"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
@ -166,7 +167,11 @@ Loop:
return return
} }
sort.Sort(byName(vec)) slices.SortFunc(vec, func(a, b promql.Sample) bool {
ni := a.Metric.Get(labels.MetricName)
nj := b.Metric.Get(labels.MetricName)
return ni < nj
})
externalLabels := h.config.GlobalConfig.ExternalLabels.Map() externalLabels := h.config.GlobalConfig.ExternalLabels.Map()
if _, ok := externalLabels[model.InstanceLabel]; !ok { if _, ok := externalLabels[model.InstanceLabel]; !ok {
@ -313,15 +318,3 @@ Loop:
} }
} }
} }
// byName makes a model.Vector sortable by metric name.
type byName promql.Vector
func (vec byName) Len() int { return len(vec) }
func (vec byName) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] }
func (vec byName) Less(i, j int) bool {
ni := vec[i].Metric.Get(labels.MetricName)
nj := vec[j].Metric.Get(labels.MetricName)
return ni < nj
}