summaryrefslogtreecommitdiff
path: root/vendor/github.com/prometheus/client_golang
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/prometheus/client_golang')
-rw-r--r--vendor/github.com/prometheus/client_golang/LICENSE201
-rw-r--r--vendor/github.com/prometheus/client_golang/NOTICE18
-rw-r--r--vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/LICENSE27
-rw-r--r--vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go145
-rw-r--r--vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/negotiate.go36
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/.gitignore1
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/README.md1
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go38
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/collector.go128
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/counter.go358
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/desc.go207
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/doc.go210
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go86
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/fnv.go42
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/gauge.go311
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/get_pid.go26
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go23
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/go_collector.go274
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go122
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go574
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/histogram.go1837
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go60
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go654
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go34
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go142
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go101
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/labels.go188
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/metric.go257
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/num_threads.go25
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go22
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/observer.go64
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/process_collector.go177
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go26
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go80
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go26
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go116
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go380
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go467
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go249
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go576
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go84
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/registry.go1076
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/summary.go827
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/timer.go81
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/untyped.go42
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/value.go274
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/vec.go709
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/vnext.go23
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/wrap.go214
49 files changed, 0 insertions, 11639 deletions
diff --git a/vendor/github.com/prometheus/client_golang/LICENSE b/vendor/github.com/prometheus/client_golang/LICENSE
deleted file mode 100644
index 261eeb9e9..000000000
--- a/vendor/github.com/prometheus/client_golang/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/vendor/github.com/prometheus/client_golang/NOTICE b/vendor/github.com/prometheus/client_golang/NOTICE
deleted file mode 100644
index b9cc55abb..000000000
--- a/vendor/github.com/prometheus/client_golang/NOTICE
+++ /dev/null
@@ -1,18 +0,0 @@
-Prometheus instrumentation library for Go applications
-Copyright 2012-2015 The Prometheus Authors
-
-This product includes software developed at
-SoundCloud Ltd. (http://soundcloud.com/).
-
-
-The following components are included in this product:
-
-perks - a fork of https://github.com/bmizerany/perks
-https://github.com/beorn7/perks
-Copyright 2013-2015 Blake Mizerany, Björn Rabenstein
-See https://github.com/beorn7/perks/blob/master/README.md for license details.
-
-Go support for Protocol Buffers - Google's data interchange format
-http://github.com/golang/protobuf/
-Copyright 2010 The Go Authors
-See source code for license details.
diff --git a/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/LICENSE b/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/LICENSE
deleted file mode 100644
index 65d761bc9..000000000
--- a/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2013 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go b/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go
deleted file mode 100644
index 8547c8dfd..000000000
--- a/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-//
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file or at
-// https://developers.google.com/open-source/licenses/bsd.
-
-// Package header provides functions for parsing HTTP headers.
-package header
-
-import (
- "net/http"
- "strings"
-)
-
-// Octet types from RFC 2616.
-var octetTypes [256]octetType
-
-type octetType byte
-
-const (
- isToken octetType = 1 << iota
- isSpace
-)
-
-func init() {
- // OCTET = <any 8-bit sequence of data>
- // CHAR = <any US-ASCII character (octets 0 - 127)>
- // CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
- // CR = <US-ASCII CR, carriage return (13)>
- // LF = <US-ASCII LF, linefeed (10)>
- // SP = <US-ASCII SP, space (32)>
- // HT = <US-ASCII HT, horizontal-tab (9)>
- // <"> = <US-ASCII double-quote mark (34)>
- // CRLF = CR LF
- // LWS = [CRLF] 1*( SP | HT )
- // TEXT = <any OCTET except CTLs, but including LWS>
- // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
- // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
- // token = 1*<any CHAR except CTLs or separators>
- // qdtext = <any TEXT except <">>
-
- for c := 0; c < 256; c++ {
- var t octetType
- isCtl := c <= 31 || c == 127
- isChar := 0 <= c && c <= 127
- isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c))
- if strings.ContainsRune(" \t\r\n", rune(c)) {
- t |= isSpace
- }
- if isChar && !isCtl && !isSeparator {
- t |= isToken
- }
- octetTypes[c] = t
- }
-}
-
-// AcceptSpec describes an Accept* header.
-type AcceptSpec struct {
- Value string
- Q float64
-}
-
-// ParseAccept parses Accept* headers.
-func ParseAccept(header http.Header, key string) (specs []AcceptSpec) {
-loop:
- for _, s := range header[key] {
- for {
- var spec AcceptSpec
- spec.Value, s = expectTokenSlash(s)
- if spec.Value == "" {
- continue loop
- }
- spec.Q = 1.0
- s = skipSpace(s)
- if strings.HasPrefix(s, ";") {
- s = skipSpace(s[1:])
- if !strings.HasPrefix(s, "q=") {
- continue loop
- }
- spec.Q, s = expectQuality(s[2:])
- if spec.Q < 0.0 {
- continue loop
- }
- }
- specs = append(specs, spec)
- s = skipSpace(s)
- if !strings.HasPrefix(s, ",") {
- continue loop
- }
- s = skipSpace(s[1:])
- }
- }
- return
-}
-
-func skipSpace(s string) (rest string) {
- i := 0
- for ; i < len(s); i++ {
- if octetTypes[s[i]]&isSpace == 0 {
- break
- }
- }
- return s[i:]
-}
-
-func expectTokenSlash(s string) (token, rest string) {
- i := 0
- for ; i < len(s); i++ {
- b := s[i]
- if (octetTypes[b]&isToken == 0) && b != '/' {
- break
- }
- }
- return s[:i], s[i:]
-}
-
-func expectQuality(s string) (q float64, rest string) {
- switch {
- case len(s) == 0:
- return -1, ""
- case s[0] == '0':
- q = 0
- case s[0] == '1':
- q = 1
- default:
- return -1, ""
- }
- s = s[1:]
- if !strings.HasPrefix(s, ".") {
- return q, s
- }
- s = s[1:]
- i := 0
- n := 0
- d := 1
- for ; i < len(s); i++ {
- b := s[i]
- if b < '0' || b > '9' {
- break
- }
- n = n*10 + int(b) - '0'
- d *= 10
- }
- return q + float64(n)/float64(d), s[i:]
-}
diff --git a/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/negotiate.go b/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/negotiate.go
deleted file mode 100644
index 2e45780b7..000000000
--- a/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/negotiate.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-//
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file or at
-// https://developers.google.com/open-source/licenses/bsd.
-
-package httputil
-
-import (
- "net/http"
-
- "github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header"
-)
-
-// NegotiateContentEncoding returns the best offered content encoding for the
-// request's Accept-Encoding header. If two offers match with equal weight and
-// then the offer earlier in the list is preferred. If no offers are
-// acceptable, then "" is returned.
-func NegotiateContentEncoding(r *http.Request, offers []string) string {
- bestOffer := "identity"
- bestQ := -1.0
- specs := header.ParseAccept(r.Header, "Accept-Encoding")
- for _, offer := range offers {
- for _, spec := range specs {
- if spec.Q > bestQ &&
- (spec.Value == "*" || spec.Value == offer) {
- bestQ = spec.Q
- bestOffer = offer
- }
- }
- }
- if bestQ == 0 {
- bestOffer = ""
- }
- return bestOffer
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/.gitignore b/vendor/github.com/prometheus/client_golang/prometheus/.gitignore
deleted file mode 100644
index 3460f0346..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-command-line-arguments.test
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/README.md b/vendor/github.com/prometheus/client_golang/prometheus/README.md
deleted file mode 100644
index c67ff1b7f..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/README.md
+++ /dev/null
@@ -1 +0,0 @@
-See [![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/client_golang/prometheus.svg)](https://pkg.go.dev/github.com/prometheus/client_golang/prometheus).
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go
deleted file mode 100644
index 450189f35..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2021 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import "runtime/debug"
-
-// NewBuildInfoCollector is the obsolete version of collectors.NewBuildInfoCollector.
-// See there for documentation.
-//
-// Deprecated: Use collectors.NewBuildInfoCollector instead.
-func NewBuildInfoCollector() Collector {
- path, version, sum := "unknown", "unknown", "unknown"
- if bi, ok := debug.ReadBuildInfo(); ok {
- path = bi.Main.Path
- version = bi.Main.Version
- sum = bi.Main.Sum
- }
- c := &selfCollector{MustNewConstMetric(
- NewDesc(
- "go_build_info",
- "Build information about the main Go module.",
- nil, Labels{"path": path, "version": version, "checksum": sum},
- ),
- GaugeValue, 1)}
- c.init(c.self)
- return c
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collector.go
deleted file mode 100644
index cf05079fb..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/collector.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-// Collector is the interface implemented by anything that can be used by
-// Prometheus to collect metrics. A Collector has to be registered for
-// collection. See Registerer.Register.
-//
-// The stock metrics provided by this package (Gauge, Counter, Summary,
-// Histogram, Untyped) are also Collectors (which only ever collect one metric,
-// namely itself). An implementer of Collector may, however, collect multiple
-// metrics in a coordinated fashion and/or create metrics on the fly. Examples
-// for collectors already implemented in this library are the metric vectors
-// (i.e. collection of multiple instances of the same Metric but with different
-// label values) like GaugeVec or SummaryVec, and the ExpvarCollector.
-type Collector interface {
- // Describe sends the super-set of all possible descriptors of metrics
- // collected by this Collector to the provided channel and returns once
- // the last descriptor has been sent. The sent descriptors fulfill the
- // consistency and uniqueness requirements described in the Desc
- // documentation.
- //
- // It is valid if one and the same Collector sends duplicate
- // descriptors. Those duplicates are simply ignored. However, two
- // different Collectors must not send duplicate descriptors.
- //
- // Sending no descriptor at all marks the Collector as “unchecked”,
- // i.e. no checks will be performed at registration time, and the
- // Collector may yield any Metric it sees fit in its Collect method.
- //
- // This method idempotently sends the same descriptors throughout the
- // lifetime of the Collector. It may be called concurrently and
- // therefore must be implemented in a concurrency safe way.
- //
- // If a Collector encounters an error while executing this method, it
- // must send an invalid descriptor (created with NewInvalidDesc) to
- // signal the error to the registry.
- Describe(chan<- *Desc)
- // Collect is called by the Prometheus registry when collecting
- // metrics. The implementation sends each collected metric via the
- // provided channel and returns once the last metric has been sent. The
- // descriptor of each sent metric is one of those returned by Describe
- // (unless the Collector is unchecked, see above). Returned metrics that
- // share the same descriptor must differ in their variable label
- // values.
- //
- // This method may be called concurrently and must therefore be
- // implemented in a concurrency safe way. Blocking occurs at the expense
- // of total performance of rendering all registered metrics. Ideally,
- // Collector implementations support concurrent readers.
- Collect(chan<- Metric)
-}
-
-// DescribeByCollect is a helper to implement the Describe method of a custom
-// Collector. It collects the metrics from the provided Collector and sends
-// their descriptors to the provided channel.
-//
-// If a Collector collects the same metrics throughout its lifetime, its
-// Describe method can simply be implemented as:
-//
-// func (c customCollector) Describe(ch chan<- *Desc) {
-// DescribeByCollect(c, ch)
-// }
-//
-// However, this will not work if the metrics collected change dynamically over
-// the lifetime of the Collector in a way that their combined set of descriptors
-// changes as well. The shortcut implementation will then violate the contract
-// of the Describe method. If a Collector sometimes collects no metrics at all
-// (for example vectors like CounterVec, GaugeVec, etc., which only collect
-// metrics after a metric with a fully specified label set has been accessed),
-// it might even get registered as an unchecked Collector (cf. the Register
-// method of the Registerer interface). Hence, only use this shortcut
-// implementation of Describe if you are certain to fulfill the contract.
-//
-// The Collector example demonstrates a use of DescribeByCollect.
-func DescribeByCollect(c Collector, descs chan<- *Desc) {
- metrics := make(chan Metric)
- go func() {
- c.Collect(metrics)
- close(metrics)
- }()
- for m := range metrics {
- descs <- m.Desc()
- }
-}
-
-// selfCollector implements Collector for a single Metric so that the Metric
-// collects itself. Add it as an anonymous field to a struct that implements
-// Metric, and call init with the Metric itself as an argument.
-type selfCollector struct {
- self Metric
-}
-
-// init provides the selfCollector with a reference to the metric it is supposed
-// to collect. It is usually called within the factory function to create a
-// metric. See example.
-func (c *selfCollector) init(self Metric) {
- c.self = self
-}
-
-// Describe implements Collector.
-func (c *selfCollector) Describe(ch chan<- *Desc) {
- ch <- c.self.Desc()
-}
-
-// Collect implements Collector.
-func (c *selfCollector) Collect(ch chan<- Metric) {
- ch <- c.self
-}
-
-// collectorMetric is a metric that is also a collector.
-// Because of selfCollector, most (if not all) Metrics in
-// this package are also collectors.
-type collectorMetric interface {
- Metric
- Collector
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go
deleted file mode 100644
index 4ce84e7a8..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/counter.go
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "errors"
- "math"
- "sync/atomic"
- "time"
-
- dto "github.com/prometheus/client_model/go"
- "google.golang.org/protobuf/types/known/timestamppb"
-)
-
-// Counter is a Metric that represents a single numerical value that only ever
-// goes up. That implies that it cannot be used to count items whose number can
-// also go down, e.g. the number of currently running goroutines. Those
-// "counters" are represented by Gauges.
-//
-// A Counter is typically used to count requests served, tasks completed, errors
-// occurred, etc.
-//
-// To create Counter instances, use NewCounter.
-type Counter interface {
- Metric
- Collector
-
- // Inc increments the counter by 1. Use Add to increment it by arbitrary
- // non-negative values.
- Inc()
- // Add adds the given value to the counter. It panics if the value is <
- // 0.
- Add(float64)
-}
-
-// ExemplarAdder is implemented by Counters that offer the option of adding a
-// value to the Counter together with an exemplar. Its AddWithExemplar method
-// works like the Add method of the Counter interface but also replaces the
-// currently saved exemplar (if any) with a new one, created from the provided
-// value, the current time as timestamp, and the provided labels. Empty Labels
-// will lead to a valid (label-less) exemplar. But if Labels is nil, the current
-// exemplar is left in place. AddWithExemplar panics if the value is < 0, if any
-// of the provided labels are invalid, or if the provided labels contain more
-// than 128 runes in total.
-type ExemplarAdder interface {
- AddWithExemplar(value float64, exemplar Labels)
-}
-
-// CounterOpts is an alias for Opts. See there for doc comments.
-type CounterOpts Opts
-
-// CounterVecOpts bundles the options to create a CounterVec metric.
-// It is mandatory to set CounterOpts, see there for mandatory fields. VariableLabels
-// is optional and can safely be left to its default value.
-type CounterVecOpts struct {
- CounterOpts
-
- // VariableLabels are used to partition the metric vector by the given set
- // of labels. Each label value will be constrained with the optional Constraint
- // function, if provided.
- VariableLabels ConstrainableLabels
-}
-
-// NewCounter creates a new Counter based on the provided CounterOpts.
-//
-// The returned implementation also implements ExemplarAdder. It is safe to
-// perform the corresponding type assertion.
-//
-// The returned implementation tracks the counter value in two separate
-// variables, a float64 and a uint64. The latter is used to track calls of the
-// Inc method and calls of the Add method with a value that can be represented
-// as a uint64. This allows atomic increments of the counter with optimal
-// performance. (It is common to have an Inc call in very hot execution paths.)
-// Both internal tracking values are added up in the Write method. This has to
-// be taken into account when it comes to precision and overflow behavior.
-func NewCounter(opts CounterOpts) Counter {
- desc := NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- nil,
- opts.ConstLabels,
- )
- if opts.now == nil {
- opts.now = time.Now
- }
- result := &counter{desc: desc, labelPairs: desc.constLabelPairs, now: opts.now}
- result.init(result) // Init self-collection.
- result.createdTs = timestamppb.New(opts.now())
- return result
-}
-
-type counter struct {
- // valBits contains the bits of the represented float64 value, while
- // valInt stores values that are exact integers. Both have to go first
- // in the struct to guarantee alignment for atomic operations.
- // http://golang.org/pkg/sync/atomic/#pkg-note-BUG
- valBits uint64
- valInt uint64
-
- selfCollector
- desc *Desc
-
- createdTs *timestamppb.Timestamp
- labelPairs []*dto.LabelPair
- exemplar atomic.Value // Containing nil or a *dto.Exemplar.
-
- // now is for testing purposes, by default it's time.Now.
- now func() time.Time
-}
-
-func (c *counter) Desc() *Desc {
- return c.desc
-}
-
-func (c *counter) Add(v float64) {
- if v < 0 {
- panic(errors.New("counter cannot decrease in value"))
- }
-
- ival := uint64(v)
- if float64(ival) == v {
- atomic.AddUint64(&c.valInt, ival)
- return
- }
-
- for {
- oldBits := atomic.LoadUint64(&c.valBits)
- newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
- if atomic.CompareAndSwapUint64(&c.valBits, oldBits, newBits) {
- return
- }
- }
-}
-
-func (c *counter) AddWithExemplar(v float64, e Labels) {
- c.Add(v)
- c.updateExemplar(v, e)
-}
-
-func (c *counter) Inc() {
- atomic.AddUint64(&c.valInt, 1)
-}
-
-func (c *counter) get() float64 {
- fval := math.Float64frombits(atomic.LoadUint64(&c.valBits))
- ival := atomic.LoadUint64(&c.valInt)
- return fval + float64(ival)
-}
-
-func (c *counter) Write(out *dto.Metric) error {
- // Read the Exemplar first and the value second. This is to avoid a race condition
- // where users see an exemplar for a not-yet-existing observation.
- var exemplar *dto.Exemplar
- if e := c.exemplar.Load(); e != nil {
- exemplar = e.(*dto.Exemplar)
- }
- val := c.get()
- return populateMetric(CounterValue, val, c.labelPairs, exemplar, out, c.createdTs)
-}
-
-func (c *counter) updateExemplar(v float64, l Labels) {
- if l == nil {
- return
- }
- e, err := newExemplar(v, c.now(), l)
- if err != nil {
- panic(err)
- }
- c.exemplar.Store(e)
-}
-
-// CounterVec is a Collector that bundles a set of Counters that all share the
-// same Desc, but have different values for their variable labels. This is used
-// if you want to count the same thing partitioned by various dimensions
-// (e.g. number of HTTP requests, partitioned by response code and
-// method). Create instances with NewCounterVec.
-type CounterVec struct {
- *MetricVec
-}
-
-// NewCounterVec creates a new CounterVec based on the provided CounterOpts and
-// partitioned by the given label names.
-func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
- return V2.NewCounterVec(CounterVecOpts{
- CounterOpts: opts,
- VariableLabels: UnconstrainedLabels(labelNames),
- })
-}
-
-// NewCounterVec creates a new CounterVec based on the provided CounterVecOpts.
-func (v2) NewCounterVec(opts CounterVecOpts) *CounterVec {
- desc := V2.NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- opts.VariableLabels,
- opts.ConstLabels,
- )
- if opts.now == nil {
- opts.now = time.Now
- }
- return &CounterVec{
- MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
- if len(lvs) != len(desc.variableLabels.names) {
- panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs))
- }
- result := &counter{desc: desc, labelPairs: MakeLabelPairs(desc, lvs), now: opts.now}
- result.init(result) // Init self-collection.
- result.createdTs = timestamppb.New(opts.now())
- return result
- }),
- }
-}
-
-// GetMetricWithLabelValues returns the Counter for the given slice of label
-// values (same order as the variable labels in Desc). If that combination of
-// label values is accessed for the first time, a new Counter is created.
-//
-// It is possible to call this method without using the returned Counter to only
-// create the new Counter but leave it at its starting value 0. See also the
-// SummaryVec example.
-//
-// Keeping the Counter for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Counter from the CounterVec. In that case,
-// the Counter will still exist, but it will not be exported anymore, even if a
-// Counter with the same label values is created later.
-//
-// An error is returned if the number of label values is not the same as the
-// number of variable labels in Desc (minus any curried labels).
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
-func (v *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) {
- metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)
- if metric != nil {
- return metric.(Counter), err
- }
- return nil, err
-}
-
-// GetMetricWith returns the Counter for the given Labels map (the label names
-// must match those of the variable labels in Desc). If that label map is
-// accessed for the first time, a new Counter is created. Implications of
-// creating a Counter without using it and keeping the Counter for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the variable labels in Desc (minus any curried labels).
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (v *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
- metric, err := v.MetricVec.GetMetricWith(labels)
- if metric != nil {
- return metric.(Counter), err
- }
- return nil, err
-}
-
-// WithLabelValues works as GetMetricWithLabelValues, but panics where
-// GetMetricWithLabelValues would have returned an error. Not returning an
-// error allows shortcuts like
-//
-// myVec.WithLabelValues("404", "GET").Add(42)
-func (v *CounterVec) WithLabelValues(lvs ...string) Counter {
- c, err := v.GetMetricWithLabelValues(lvs...)
- if err != nil {
- panic(err)
- }
- return c
-}
-
-// With works as GetMetricWith, but panics where GetMetricWithLabels would have
-// returned an error. Not returning an error allows shortcuts like
-//
-// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42)
-func (v *CounterVec) With(labels Labels) Counter {
- c, err := v.GetMetricWith(labels)
- if err != nil {
- panic(err)
- }
- return c
-}
-
-// CurryWith returns a vector curried with the provided labels, i.e. the
-// returned vector has those labels pre-set for all labeled operations performed
-// on it. The cardinality of the curried vector is reduced accordingly. The
-// order of the remaining labels stays the same (just with the curried labels
-// taken out of the sequence – which is relevant for the
-// (GetMetric)WithLabelValues methods). It is possible to curry a curried
-// vector, but only with labels not yet used for currying before.
-//
-// The metrics contained in the CounterVec are shared between the curried and
-// uncurried vectors. They are just accessed differently. Curried and uncurried
-// vectors behave identically in terms of collection. Only one must be
-// registered with a given registry (usually the uncurried version). The Reset
-// method deletes all metrics, even if called on a curried vector.
-func (v *CounterVec) CurryWith(labels Labels) (*CounterVec, error) {
- vec, err := v.MetricVec.CurryWith(labels)
- if vec != nil {
- return &CounterVec{vec}, err
- }
- return nil, err
-}
-
-// MustCurryWith works as CurryWith but panics where CurryWith would have
-// returned an error.
-func (v *CounterVec) MustCurryWith(labels Labels) *CounterVec {
- vec, err := v.CurryWith(labels)
- if err != nil {
- panic(err)
- }
- return vec
-}
-
-// CounterFunc is a Counter whose value is determined at collect time by calling a
-// provided function.
-//
-// To create CounterFunc instances, use NewCounterFunc.
-type CounterFunc interface {
- Metric
- Collector
-}
-
-// NewCounterFunc creates a new CounterFunc based on the provided
-// CounterOpts. The value reported is determined by calling the given function
-// from within the Write method. Take into account that metric collection may
-// happen concurrently. If that results in concurrent calls to Write, like in
-// the case where a CounterFunc is directly registered with Prometheus, the
-// provided function must be concurrency-safe. The function should also honor
-// the contract for a Counter (values only go up, not down), but compliance will
-// not be checked.
-//
-// Check out the ExampleGaugeFunc examples for the similar GaugeFunc.
-func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc {
- return newValueFunc(NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- nil,
- opts.ConstLabels,
- ), CounterValue, function)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/vendor/github.com/prometheus/client_golang/prometheus/desc.go
deleted file mode 100644
index 68ffe3c24..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/desc.go
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 2016 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "fmt"
- "sort"
- "strings"
-
- "github.com/cespare/xxhash/v2"
- dto "github.com/prometheus/client_model/go"
- "github.com/prometheus/common/model"
- "google.golang.org/protobuf/proto"
-
- "github.com/prometheus/client_golang/prometheus/internal"
-)
-
-// Desc is the descriptor used by every Prometheus Metric. It is essentially
-// the immutable meta-data of a Metric. The normal Metric implementations
-// included in this package manage their Desc under the hood. Users only have to
-// deal with Desc if they use advanced features like the ExpvarCollector or
-// custom Collectors and Metrics.
-//
-// Descriptors registered with the same registry have to fulfill certain
-// consistency and uniqueness criteria if they share the same fully-qualified
-// name: They must have the same help string and the same label names (aka label
-// dimensions) in each, constLabels and variableLabels, but they must differ in
-// the values of the constLabels.
-//
-// Descriptors that share the same fully-qualified names and the same label
-// values of their constLabels are considered equal.
-//
-// Use NewDesc to create new Desc instances.
-type Desc struct {
- // fqName has been built from Namespace, Subsystem, and Name.
- fqName string
- // help provides some helpful information about this metric.
- help string
- // constLabelPairs contains precalculated DTO label pairs based on
- // the constant labels.
- constLabelPairs []*dto.LabelPair
- // variableLabels contains names of labels and normalization function for
- // which the metric maintains variable values.
- variableLabels *compiledLabels
- // id is a hash of the values of the ConstLabels and fqName. This
- // must be unique among all registered descriptors and can therefore be
- // used as an identifier of the descriptor.
- id uint64
- // dimHash is a hash of the label names (preset and variable) and the
- // Help string. Each Desc with the same fqName must have the same
- // dimHash.
- dimHash uint64
- // err is an error that occurred during construction. It is reported on
- // registration time.
- err error
-}
-
-// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc
-// and will be reported on registration time. variableLabels and constLabels can
-// be nil if no such labels should be set. fqName must not be empty.
-//
-// variableLabels only contain the label names. Their label values are variable
-// and therefore not part of the Desc. (They are managed within the Metric.)
-//
-// For constLabels, the label values are constant. Therefore, they are fully
-// specified in the Desc. See the Collector example for a usage pattern.
-func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *Desc {
- return V2.NewDesc(fqName, help, UnconstrainedLabels(variableLabels), constLabels)
-}
-
-// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc
-// and will be reported on registration time. variableLabels and constLabels can
-// be nil if no such labels should be set. fqName must not be empty.
-//
-// variableLabels only contain the label names and normalization functions. Their
-// label values are variable and therefore not part of the Desc. (They are managed
-// within the Metric.)
-//
-// For constLabels, the label values are constant. Therefore, they are fully
-// specified in the Desc. See the Collector example for a usage pattern.
-func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, constLabels Labels) *Desc {
- d := &Desc{
- fqName: fqName,
- help: help,
- variableLabels: variableLabels.compile(),
- }
- if !model.IsValidMetricName(model.LabelValue(fqName)) {
- d.err = fmt.Errorf("%q is not a valid metric name", fqName)
- return d
- }
- // labelValues contains the label values of const labels (in order of
- // their sorted label names) plus the fqName (at position 0).
- labelValues := make([]string, 1, len(constLabels)+1)
- labelValues[0] = fqName
- labelNames := make([]string, 0, len(constLabels)+len(d.variableLabels.names))
- labelNameSet := map[string]struct{}{}
- // First add only the const label names and sort them...
- for labelName := range constLabels {
- if !checkLabelName(labelName) {
- d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName)
- return d
- }
- labelNames = append(labelNames, labelName)
- labelNameSet[labelName] = struct{}{}
- }
- sort.Strings(labelNames)
- // ... so that we can now add const label values in the order of their names.
- for _, labelName := range labelNames {
- labelValues = append(labelValues, constLabels[labelName])
- }
- // Validate the const label values. They can't have a wrong cardinality, so
- // use in len(labelValues) as expectedNumberOfValues.
- if err := validateLabelValues(labelValues, len(labelValues)); err != nil {
- d.err = err
- return d
- }
- // Now add the variable label names, but prefix them with something that
- // cannot be in a regular label name. That prevents matching the label
- // dimension with a different mix between preset and variable labels.
- for _, label := range d.variableLabels.names {
- if !checkLabelName(label) {
- d.err = fmt.Errorf("%q is not a valid label name for metric %q", label, fqName)
- return d
- }
- labelNames = append(labelNames, "$"+label)
- labelNameSet[label] = struct{}{}
- }
- if len(labelNames) != len(labelNameSet) {
- d.err = fmt.Errorf("duplicate label names in constant and variable labels for metric %q", fqName)
- return d
- }
-
- xxh := xxhash.New()
- for _, val := range labelValues {
- xxh.WriteString(val)
- xxh.Write(separatorByteSlice)
- }
- d.id = xxh.Sum64()
- // Sort labelNames so that order doesn't matter for the hash.
- sort.Strings(labelNames)
- // Now hash together (in this order) the help string and the sorted
- // label names.
- xxh.Reset()
- xxh.WriteString(help)
- xxh.Write(separatorByteSlice)
- for _, labelName := range labelNames {
- xxh.WriteString(labelName)
- xxh.Write(separatorByteSlice)
- }
- d.dimHash = xxh.Sum64()
-
- d.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels))
- for n, v := range constLabels {
- d.constLabelPairs = append(d.constLabelPairs, &dto.LabelPair{
- Name: proto.String(n),
- Value: proto.String(v),
- })
- }
- sort.Sort(internal.LabelPairSorter(d.constLabelPairs))
- return d
-}
-
-// NewInvalidDesc returns an invalid descriptor, i.e. a descriptor with the
-// provided error set. If a collector returning such a descriptor is registered,
-// registration will fail with the provided error. NewInvalidDesc can be used by
-// a Collector to signal inability to describe itself.
-func NewInvalidDesc(err error) *Desc {
- return &Desc{
- err: err,
- }
-}
-
-func (d *Desc) String() string {
- lpStrings := make([]string, 0, len(d.constLabelPairs))
- for _, lp := range d.constLabelPairs {
- lpStrings = append(
- lpStrings,
- fmt.Sprintf("%s=%q", lp.GetName(), lp.GetValue()),
- )
- }
- vlStrings := make([]string, 0, len(d.variableLabels.names))
- for _, vl := range d.variableLabels.names {
- if fn, ok := d.variableLabels.labelConstraints[vl]; ok && fn != nil {
- vlStrings = append(vlStrings, fmt.Sprintf("c(%s)", vl))
- } else {
- vlStrings = append(vlStrings, vl)
- }
- }
- return fmt.Sprintf(
- "Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: {%s}}",
- d.fqName,
- d.help,
- strings.Join(lpStrings, ","),
- strings.Join(vlStrings, ","),
- )
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/doc.go b/vendor/github.com/prometheus/client_golang/prometheus/doc.go
deleted file mode 100644
index 962608f02..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/doc.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package prometheus is the core instrumentation package. It provides metrics
-// primitives to instrument code for monitoring. It also offers a registry for
-// metrics. Sub-packages allow to expose the registered metrics via HTTP
-// (package promhttp) or push them to a Pushgateway (package push). There is
-// also a sub-package promauto, which provides metrics constructors with
-// automatic registration.
-//
-// All exported functions and methods are safe to be used concurrently unless
-// specified otherwise.
-//
-// # A Basic Example
-//
-// As a starting point, a very basic usage example:
-//
-// package main
-//
-// import (
-// "log"
-// "net/http"
-//
-// "github.com/prometheus/client_golang/prometheus"
-// "github.com/prometheus/client_golang/prometheus/promhttp"
-// )
-//
-// type metrics struct {
-// cpuTemp prometheus.Gauge
-// hdFailures *prometheus.CounterVec
-// }
-//
-// func NewMetrics(reg prometheus.Registerer) *metrics {
-// m := &metrics{
-// cpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{
-// Name: "cpu_temperature_celsius",
-// Help: "Current temperature of the CPU.",
-// }),
-// hdFailures: prometheus.NewCounterVec(
-// prometheus.CounterOpts{
-// Name: "hd_errors_total",
-// Help: "Number of hard-disk errors.",
-// },
-// []string{"device"},
-// ),
-// }
-// reg.MustRegister(m.cpuTemp)
-// reg.MustRegister(m.hdFailures)
-// return m
-// }
-//
-// func main() {
-// // Create a non-global registry.
-// reg := prometheus.NewRegistry()
-//
-// // Create new metrics and register them using the custom registry.
-// m := NewMetrics(reg)
-// // Set values for the new created metrics.
-// m.cpuTemp.Set(65.3)
-// m.hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc()
-//
-// // Expose metrics and custom registry via an HTTP server
-// // using the HandleFor function. "/metrics" is the usual endpoint for that.
-// http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}))
-// log.Fatal(http.ListenAndServe(":8080", nil))
-// }
-//
-// This is a complete program that exports two metrics, a Gauge and a Counter,
-// the latter with a label attached to turn it into a (one-dimensional) vector.
-// It register the metrics using a custom registry and exposes them via an HTTP server
-// on the /metrics endpoint.
-//
-// # Metrics
-//
-// The number of exported identifiers in this package might appear a bit
-// overwhelming. However, in addition to the basic plumbing shown in the example
-// above, you only need to understand the different metric types and their
-// vector versions for basic usage. Furthermore, if you are not concerned with
-// fine-grained control of when and how to register metrics with the registry,
-// have a look at the promauto package, which will effectively allow you to
-// ignore registration altogether in simple cases.
-//
-// Above, you have already touched the Counter and the Gauge. There are two more
-// advanced metric types: the Summary and Histogram. A more thorough description
-// of those four metric types can be found in the Prometheus docs:
-// https://prometheus.io/docs/concepts/metric_types/
-//
-// In addition to the fundamental metric types Gauge, Counter, Summary, and
-// Histogram, a very important part of the Prometheus data model is the
-// partitioning of samples along dimensions called labels, which results in
-// metric vectors. The fundamental types are GaugeVec, CounterVec, SummaryVec,
-// and HistogramVec.
-//
-// While only the fundamental metric types implement the Metric interface, both
-// the metrics and their vector versions implement the Collector interface. A
-// Collector manages the collection of a number of Metrics, but for convenience,
-// a Metric can also “collect itself”. Note that Gauge, Counter, Summary, and
-// Histogram are interfaces themselves while GaugeVec, CounterVec, SummaryVec,
-// and HistogramVec are not.
-//
-// To create instances of Metrics and their vector versions, you need a suitable
-// …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, or HistogramOpts.
-//
-// # Custom Collectors and constant Metrics
-//
-// While you could create your own implementations of Metric, most likely you
-// will only ever implement the Collector interface on your own. At a first
-// glance, a custom Collector seems handy to bundle Metrics for common
-// registration (with the prime example of the different metric vectors above,
-// which bundle all the metrics of the same name but with different labels).
-//
-// There is a more involved use case, too: If you already have metrics
-// available, created outside of the Prometheus context, you don't need the
-// interface of the various Metric types. You essentially want to mirror the
-// existing numbers into Prometheus Metrics during collection. An own
-// implementation of the Collector interface is perfect for that. You can create
-// Metric instances “on the fly” using NewConstMetric, NewConstHistogram, and
-// NewConstSummary (and their respective Must… versions). NewConstMetric is used
-// for all metric types with just a float64 as their value: Counter, Gauge, and
-// a special “type” called Untyped. Use the latter if you are not sure if the
-// mirrored metric is a Counter or a Gauge. Creation of the Metric instance
-// happens in the Collect method. The Describe method has to return separate
-// Desc instances, representative of the “throw-away” metrics to be created
-// later. NewDesc comes in handy to create those Desc instances. Alternatively,
-// you could return no Desc at all, which will mark the Collector “unchecked”.
-// No checks are performed at registration time, but metric consistency will
-// still be ensured at scrape time, i.e. any inconsistencies will lead to scrape
-// errors. Thus, with unchecked Collectors, the responsibility to not collect
-// metrics that lead to inconsistencies in the total scrape result lies with the
-// implementer of the Collector. While this is not a desirable state, it is
-// sometimes necessary. The typical use case is a situation where the exact
-// metrics to be returned by a Collector cannot be predicted at registration
-// time, but the implementer has sufficient knowledge of the whole system to
-// guarantee metric consistency.
-//
-// The Collector example illustrates the use case. You can also look at the
-// source code of the processCollector (mirroring process metrics), the
-// goCollector (mirroring Go metrics), or the expvarCollector (mirroring expvar
-// metrics) as examples that are used in this package itself.
-//
-// If you just need to call a function to get a single float value to collect as
-// a metric, GaugeFunc, CounterFunc, or UntypedFunc might be interesting
-// shortcuts.
-//
-// # Advanced Uses of the Registry
-//
-// While MustRegister is the by far most common way of registering a Collector,
-// sometimes you might want to handle the errors the registration might cause.
-// As suggested by the name, MustRegister panics if an error occurs. With the
-// Register function, the error is returned and can be handled.
-//
-// An error is returned if the registered Collector is incompatible or
-// inconsistent with already registered metrics. The registry aims for
-// consistency of the collected metrics according to the Prometheus data model.
-// Inconsistencies are ideally detected at registration time, not at collect
-// time. The former will usually be detected at start-up time of a program,
-// while the latter will only happen at scrape time, possibly not even on the
-// first scrape if the inconsistency only becomes relevant later. That is the
-// main reason why a Collector and a Metric have to describe themselves to the
-// registry.
-//
-// So far, everything we did operated on the so-called default registry, as it
-// can be found in the global DefaultRegisterer variable. With NewRegistry, you
-// can create a custom registry, or you can even implement the Registerer or
-// Gatherer interfaces yourself. The methods Register and Unregister work in the
-// same way on a custom registry as the global functions Register and Unregister
-// on the default registry.
-//
-// There are a number of uses for custom registries: You can use registries with
-// special properties, see NewPedanticRegistry. You can avoid global state, as
-// it is imposed by the DefaultRegisterer. You can use multiple registries at
-// the same time to expose different metrics in different ways. You can use
-// separate registries for testing purposes.
-//
-// Also note that the DefaultRegisterer comes registered with a Collector for Go
-// runtime metrics (via NewGoCollector) and a Collector for process metrics (via
-// NewProcessCollector). With a custom registry, you are in control and decide
-// yourself about the Collectors to register.
-//
-// # HTTP Exposition
-//
-// The Registry implements the Gatherer interface. The caller of the Gather
-// method can then expose the gathered metrics in some way. Usually, the metrics
-// are served via HTTP on the /metrics endpoint. That's happening in the example
-// above. The tools to expose metrics via HTTP are in the promhttp sub-package.
-//
-// # Pushing to the Pushgateway
-//
-// Function for pushing to the Pushgateway can be found in the push sub-package.
-//
-// # Graphite Bridge
-//
-// Functions and examples to push metrics from a Gatherer to Graphite can be
-// found in the graphite sub-package.
-//
-// # Other Means of Exposition
-//
-// More ways of exposing metrics can easily be added by following the approaches
-// of the existing implementations.
-package prometheus
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go
deleted file mode 100644
index de5a85629..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "encoding/json"
- "expvar"
-)
-
-type expvarCollector struct {
- exports map[string]*Desc
-}
-
-// NewExpvarCollector is the obsolete version of collectors.NewExpvarCollector.
-// See there for documentation.
-//
-// Deprecated: Use collectors.NewExpvarCollector instead.
-func NewExpvarCollector(exports map[string]*Desc) Collector {
- return &expvarCollector{
- exports: exports,
- }
-}
-
-// Describe implements Collector.
-func (e *expvarCollector) Describe(ch chan<- *Desc) {
- for _, desc := range e.exports {
- ch <- desc
- }
-}
-
-// Collect implements Collector.
-func (e *expvarCollector) Collect(ch chan<- Metric) {
- for name, desc := range e.exports {
- var m Metric
- expVar := expvar.Get(name)
- if expVar == nil {
- continue
- }
- var v interface{}
- labels := make([]string, len(desc.variableLabels.names))
- if err := json.Unmarshal([]byte(expVar.String()), &v); err != nil {
- ch <- NewInvalidMetric(desc, err)
- continue
- }
- var processValue func(v interface{}, i int)
- processValue = func(v interface{}, i int) {
- if i >= len(labels) {
- copiedLabels := append(make([]string, 0, len(labels)), labels...)
- switch v := v.(type) {
- case float64:
- m = MustNewConstMetric(desc, UntypedValue, v, copiedLabels...)
- case bool:
- if v {
- m = MustNewConstMetric(desc, UntypedValue, 1, copiedLabels...)
- } else {
- m = MustNewConstMetric(desc, UntypedValue, 0, copiedLabels...)
- }
- default:
- return
- }
- ch <- m
- return
- }
- vm, ok := v.(map[string]interface{})
- if !ok {
- return
- }
- for lv, val := range vm {
- labels[i] = lv
- processValue(val, i+1)
- }
- }
- processValue(v, 0)
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/fnv.go b/vendor/github.com/prometheus/client_golang/prometheus/fnv.go
deleted file mode 100644
index 3d383a735..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/fnv.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-// Inline and byte-free variant of hash/fnv's fnv64a.
-
-const (
- offset64 = 14695981039346656037
- prime64 = 1099511628211
-)
-
-// hashNew initializies a new fnv64a hash value.
-func hashNew() uint64 {
- return offset64
-}
-
-// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
-func hashAdd(h uint64, s string) uint64 {
- for i := 0; i < len(s); i++ {
- h ^= uint64(s[i])
- h *= prime64
- }
- return h
-}
-
-// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
-func hashAddByte(h uint64, b byte) uint64 {
- h ^= uint64(b)
- h *= prime64
- return h
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
deleted file mode 100644
index dd2eac940..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "math"
- "sync/atomic"
- "time"
-
- dto "github.com/prometheus/client_model/go"
-)
-
-// Gauge is a Metric that represents a single numerical value that can
-// arbitrarily go up and down.
-//
-// A Gauge is typically used for measured values like temperatures or current
-// memory usage, but also "counts" that can go up and down, like the number of
-// running goroutines.
-//
-// To create Gauge instances, use NewGauge.
-type Gauge interface {
- Metric
- Collector
-
- // Set sets the Gauge to an arbitrary value.
- Set(float64)
- // Inc increments the Gauge by 1. Use Add to increment it by arbitrary
- // values.
- Inc()
- // Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary
- // values.
- Dec()
- // Add adds the given value to the Gauge. (The value can be negative,
- // resulting in a decrease of the Gauge.)
- Add(float64)
- // Sub subtracts the given value from the Gauge. (The value can be
- // negative, resulting in an increase of the Gauge.)
- Sub(float64)
-
- // SetToCurrentTime sets the Gauge to the current Unix time in seconds.
- SetToCurrentTime()
-}
-
-// GaugeOpts is an alias for Opts. See there for doc comments.
-type GaugeOpts Opts
-
-// GaugeVecOpts bundles the options to create a GaugeVec metric.
-// It is mandatory to set GaugeOpts, see there for mandatory fields. VariableLabels
-// is optional and can safely be left to its default value.
-type GaugeVecOpts struct {
- GaugeOpts
-
- // VariableLabels are used to partition the metric vector by the given set
- // of labels. Each label value will be constrained with the optional Constraint
- // function, if provided.
- VariableLabels ConstrainableLabels
-}
-
-// NewGauge creates a new Gauge based on the provided GaugeOpts.
-//
-// The returned implementation is optimized for a fast Set method. If you have a
-// choice for managing the value of a Gauge via Set vs. Inc/Dec/Add/Sub, pick
-// the former. For example, the Inc method of the returned Gauge is slower than
-// the Inc method of a Counter returned by NewCounter. This matches the typical
-// scenarios for Gauges and Counters, where the former tends to be Set-heavy and
-// the latter Inc-heavy.
-func NewGauge(opts GaugeOpts) Gauge {
- desc := NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- nil,
- opts.ConstLabels,
- )
- result := &gauge{desc: desc, labelPairs: desc.constLabelPairs}
- result.init(result) // Init self-collection.
- return result
-}
-
-type gauge struct {
- // valBits contains the bits of the represented float64 value. It has
- // to go first in the struct to guarantee alignment for atomic
- // operations. http://golang.org/pkg/sync/atomic/#pkg-note-BUG
- valBits uint64
-
- selfCollector
-
- desc *Desc
- labelPairs []*dto.LabelPair
-}
-
-func (g *gauge) Desc() *Desc {
- return g.desc
-}
-
-func (g *gauge) Set(val float64) {
- atomic.StoreUint64(&g.valBits, math.Float64bits(val))
-}
-
-func (g *gauge) SetToCurrentTime() {
- g.Set(float64(time.Now().UnixNano()) / 1e9)
-}
-
-func (g *gauge) Inc() {
- g.Add(1)
-}
-
-func (g *gauge) Dec() {
- g.Add(-1)
-}
-
-func (g *gauge) Add(val float64) {
- for {
- oldBits := atomic.LoadUint64(&g.valBits)
- newBits := math.Float64bits(math.Float64frombits(oldBits) + val)
- if atomic.CompareAndSwapUint64(&g.valBits, oldBits, newBits) {
- return
- }
- }
-}
-
-func (g *gauge) Sub(val float64) {
- g.Add(val * -1)
-}
-
-func (g *gauge) Write(out *dto.Metric) error {
- val := math.Float64frombits(atomic.LoadUint64(&g.valBits))
- return populateMetric(GaugeValue, val, g.labelPairs, nil, out, nil)
-}
-
-// GaugeVec is a Collector that bundles a set of Gauges that all share the same
-// Desc, but have different values for their variable labels. This is used if
-// you want to count the same thing partitioned by various dimensions
-// (e.g. number of operations queued, partitioned by user and operation
-// type). Create instances with NewGaugeVec.
-type GaugeVec struct {
- *MetricVec
-}
-
-// NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and
-// partitioned by the given label names.
-func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
- return V2.NewGaugeVec(GaugeVecOpts{
- GaugeOpts: opts,
- VariableLabels: UnconstrainedLabels(labelNames),
- })
-}
-
-// NewGaugeVec creates a new GaugeVec based on the provided GaugeVecOpts.
-func (v2) NewGaugeVec(opts GaugeVecOpts) *GaugeVec {
- desc := V2.NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- opts.VariableLabels,
- opts.ConstLabels,
- )
- return &GaugeVec{
- MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
- if len(lvs) != len(desc.variableLabels.names) {
- panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs))
- }
- result := &gauge{desc: desc, labelPairs: MakeLabelPairs(desc, lvs)}
- result.init(result) // Init self-collection.
- return result
- }),
- }
-}
-
-// GetMetricWithLabelValues returns the Gauge for the given slice of label
-// values (same order as the variable labels in Desc). If that combination of
-// label values is accessed for the first time, a new Gauge is created.
-//
-// It is possible to call this method without using the returned Gauge to only
-// create the new Gauge but leave it at its starting value 0. See also the
-// SummaryVec example.
-//
-// Keeping the Gauge for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Gauge from the GaugeVec. In that case, the
-// Gauge will still exist, but it will not be exported anymore, even if a
-// Gauge with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of variable labels in Desc (minus any curried labels).
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-func (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) {
- metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)
- if metric != nil {
- return metric.(Gauge), err
- }
- return nil, err
-}
-
-// GetMetricWith returns the Gauge for the given Labels map (the label names
-// must match those of the variable labels in Desc). If that label map is
-// accessed for the first time, a new Gauge is created. Implications of
-// creating a Gauge without using it and keeping the Gauge for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the variable labels in Desc (minus any curried labels).
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
- metric, err := v.MetricVec.GetMetricWith(labels)
- if metric != nil {
- return metric.(Gauge), err
- }
- return nil, err
-}
-
-// WithLabelValues works as GetMetricWithLabelValues, but panics where
-// GetMetricWithLabelValues would have returned an error. Not returning an
-// error allows shortcuts like
-//
-// myVec.WithLabelValues("404", "GET").Add(42)
-func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge {
- g, err := v.GetMetricWithLabelValues(lvs...)
- if err != nil {
- panic(err)
- }
- return g
-}
-
-// With works as GetMetricWith, but panics where GetMetricWithLabels would have
-// returned an error. Not returning an error allows shortcuts like
-//
-// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42)
-func (v *GaugeVec) With(labels Labels) Gauge {
- g, err := v.GetMetricWith(labels)
- if err != nil {
- panic(err)
- }
- return g
-}
-
-// CurryWith returns a vector curried with the provided labels, i.e. the
-// returned vector has those labels pre-set for all labeled operations performed
-// on it. The cardinality of the curried vector is reduced accordingly. The
-// order of the remaining labels stays the same (just with the curried labels
-// taken out of the sequence – which is relevant for the
-// (GetMetric)WithLabelValues methods). It is possible to curry a curried
-// vector, but only with labels not yet used for currying before.
-//
-// The metrics contained in the GaugeVec are shared between the curried and
-// uncurried vectors. They are just accessed differently. Curried and uncurried
-// vectors behave identically in terms of collection. Only one must be
-// registered with a given registry (usually the uncurried version). The Reset
-// method deletes all metrics, even if called on a curried vector.
-func (v *GaugeVec) CurryWith(labels Labels) (*GaugeVec, error) {
- vec, err := v.MetricVec.CurryWith(labels)
- if vec != nil {
- return &GaugeVec{vec}, err
- }
- return nil, err
-}
-
-// MustCurryWith works as CurryWith but panics where CurryWith would have
-// returned an error.
-func (v *GaugeVec) MustCurryWith(labels Labels) *GaugeVec {
- vec, err := v.CurryWith(labels)
- if err != nil {
- panic(err)
- }
- return vec
-}
-
-// GaugeFunc is a Gauge whose value is determined at collect time by calling a
-// provided function.
-//
-// To create GaugeFunc instances, use NewGaugeFunc.
-type GaugeFunc interface {
- Metric
- Collector
-}
-
-// NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The
-// value reported is determined by calling the given function from within the
-// Write method. Take into account that metric collection may happen
-// concurrently. Therefore, it must be safe to call the provided function
-// concurrently.
-//
-// NewGaugeFunc is a good way to create an “info” style metric with a constant
-// value of 1. Example:
-// https://github.com/prometheus/common/blob/8558a5b7db3c84fa38b4766966059a7bd5bfa2ee/version/info.go#L36-L56
-func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc {
- return newValueFunc(NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- nil,
- opts.ConstLabels,
- ), GaugeValue, function)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go b/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go
deleted file mode 100644
index 614fd61be..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build !js || wasm
-// +build !js wasm
-
-package prometheus
-
-import "os"
-
-func getPIDFn() func() (int, error) {
- pid := os.Getpid()
- return func() (int, error) {
- return pid, nil
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go b/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go
deleted file mode 100644
index eaf8059ee..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build js && !wasm
-// +build js,!wasm
-
-package prometheus
-
-func getPIDFn() func() (int, error) {
- return func() (int, error) {
- return 1, nil
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
deleted file mode 100644
index 520cbd7d4..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "runtime"
- "runtime/debug"
- "time"
-)
-
-// goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats.
-// From Go 1.17 those similar (and better) statistics are provided by runtime/metrics, so
-// while eval closure works on runtime.MemStats, the struct from Go 1.17+ is
-// populated using runtime/metrics. Those are the defaults we can't alter.
-func goRuntimeMemStats() memStatsMetrics {
- return memStatsMetrics{
- {
- desc: NewDesc(
- memstatNamespace("alloc_bytes"),
- "Number of bytes allocated in heap and currently in use. Equals to /memory/classes/heap/objects:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("alloc_bytes_total"),
- "Total number of bytes allocated in heap until now, even if released already. Equals to /gc/heap/allocs:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) },
- valType: CounterValue,
- }, {
- desc: NewDesc(
- memstatNamespace("sys_bytes"),
- "Number of bytes obtained from system. Equals to /memory/classes/total:byte.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.Sys) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("mallocs_total"),
- // TODO(bwplotka): We could add go_memstats_heap_objects, probably useful for discovery. Let's gather more feedback, kind of a waste of bytes for everybody for compatibility reasons to keep both, and we can't really rename/remove useful metric.
- "Total number of heap objects allocated, both live and gc-ed. Semantically a counter version for go_memstats_heap_objects gauge. Equals to /gc/heap/allocs:objects + /gc/heap/tiny/allocs:objects.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) },
- valType: CounterValue,
- }, {
- desc: NewDesc(
- memstatNamespace("frees_total"),
- "Total number of heap objects frees. Equals to /gc/heap/frees:objects + /gc/heap/tiny/allocs:objects.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.Frees) },
- valType: CounterValue,
- }, {
- desc: NewDesc(
- memstatNamespace("heap_alloc_bytes"),
- "Number of heap bytes allocated and currently in use, same as go_memstats_alloc_bytes. Equals to /memory/classes/heap/objects:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("heap_sys_bytes"),
- "Number of heap bytes obtained from system. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes + /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("heap_idle_bytes"),
- "Number of heap bytes waiting to be used. Equals to /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("heap_inuse_bytes"),
- "Number of heap bytes that are in use. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("heap_released_bytes"),
- "Number of heap bytes released to OS. Equals to /memory/classes/heap/released:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("heap_objects"),
- "Number of currently allocated objects. Equals to /gc/heap/objects:objects.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("stack_inuse_bytes"),
- "Number of bytes obtained from system for stack allocator in non-CGO environments. Equals to /memory/classes/heap/stacks:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("stack_sys_bytes"),
- "Number of bytes obtained from system for stack allocator. Equals to /memory/classes/heap/stacks:bytes + /memory/classes/os-stacks:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("mspan_inuse_bytes"),
- "Number of bytes in use by mspan structures. Equals to /memory/classes/metadata/mspan/inuse:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("mspan_sys_bytes"),
- "Number of bytes used for mspan structures obtained from system. Equals to /memory/classes/metadata/mspan/inuse:bytes + /memory/classes/metadata/mspan/free:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("mcache_inuse_bytes"),
- "Number of bytes in use by mcache structures. Equals to /memory/classes/metadata/mcache/inuse:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("mcache_sys_bytes"),
- "Number of bytes used for mcache structures obtained from system. Equals to /memory/classes/metadata/mcache/inuse:bytes + /memory/classes/metadata/mcache/free:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("buck_hash_sys_bytes"),
- "Number of bytes used by the profiling bucket hash table. Equals to /memory/classes/profiling/buckets:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("gc_sys_bytes"),
- "Number of bytes used for garbage collection system metadata. Equals to /memory/classes/metadata/other:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("other_sys_bytes"),
- "Number of bytes used for other system allocations. Equals to /memory/classes/other:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) },
- valType: GaugeValue,
- }, {
- desc: NewDesc(
- memstatNamespace("next_gc_bytes"),
- "Number of heap bytes when next garbage collection will take place. Equals to /gc/heap/goal:bytes.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) },
- valType: GaugeValue,
- },
- }
-}
-
-type baseGoCollector struct {
- goroutinesDesc *Desc
- threadsDesc *Desc
- gcDesc *Desc
- gcLastTimeDesc *Desc
- goInfoDesc *Desc
-}
-
-func newBaseGoCollector() baseGoCollector {
- return baseGoCollector{
- goroutinesDesc: NewDesc(
- "go_goroutines",
- "Number of goroutines that currently exist.",
- nil, nil),
- threadsDesc: NewDesc(
- "go_threads",
- "Number of OS threads created.",
- nil, nil),
- gcDesc: NewDesc(
- "go_gc_duration_seconds",
- "A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.",
- nil, nil),
- gcLastTimeDesc: NewDesc(
- "go_memstats_last_gc_time_seconds",
- "Number of seconds since 1970 of last garbage collection.",
- nil, nil),
- goInfoDesc: NewDesc(
- "go_info",
- "Information about the Go environment.",
- nil, Labels{"version": runtime.Version()}),
- }
-}
-
-// Describe returns all descriptions of the collector.
-func (c *baseGoCollector) Describe(ch chan<- *Desc) {
- ch <- c.goroutinesDesc
- ch <- c.threadsDesc
- ch <- c.gcDesc
- ch <- c.gcLastTimeDesc
- ch <- c.goInfoDesc
-}
-
-// Collect returns the current state of all metrics of the collector.
-func (c *baseGoCollector) Collect(ch chan<- Metric) {
- ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine()))
-
- n := getRuntimeNumThreads()
- ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, n)
-
- var stats debug.GCStats
- stats.PauseQuantiles = make([]time.Duration, 5)
- debug.ReadGCStats(&stats)
-
- quantiles := make(map[float64]float64)
- for idx, pq := range stats.PauseQuantiles[1:] {
- quantiles[float64(idx+1)/float64(len(stats.PauseQuantiles)-1)] = pq.Seconds()
- }
- quantiles[0.0] = stats.PauseQuantiles[0].Seconds()
- ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), stats.PauseTotal.Seconds(), quantiles)
- ch <- MustNewConstMetric(c.gcLastTimeDesc, GaugeValue, float64(stats.LastGC.UnixNano())/1e9)
- ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1)
-}
-
-func memstatNamespace(s string) string {
- return "go_memstats_" + s
-}
-
-// memStatsMetrics provide description, evaluator, runtime/metrics name, and
-// value type for memstat metrics.
-type memStatsMetrics []struct {
- desc *Desc
- eval func(*runtime.MemStats) float64
- valType ValueType
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go
deleted file mode 100644
index 897a6e906..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2021 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build !go1.17
-// +build !go1.17
-
-package prometheus
-
-import (
- "runtime"
- "sync"
- "time"
-)
-
-type goCollector struct {
- base baseGoCollector
-
- // ms... are memstats related.
- msLast *runtime.MemStats // Previously collected memstats.
- msLastTimestamp time.Time
- msMtx sync.Mutex // Protects msLast and msLastTimestamp.
- msMetrics memStatsMetrics
- msRead func(*runtime.MemStats) // For mocking in tests.
- msMaxWait time.Duration // Wait time for fresh memstats.
- msMaxAge time.Duration // Maximum allowed age of old memstats.
-}
-
-// NewGoCollector is the obsolete version of collectors.NewGoCollector.
-// See there for documentation.
-//
-// Deprecated: Use collectors.NewGoCollector instead.
-func NewGoCollector() Collector {
- msMetrics := goRuntimeMemStats()
- msMetrics = append(msMetrics, struct {
- desc *Desc
- eval func(*runtime.MemStats) float64
- valType ValueType
- }{
- // This metric is omitted in Go1.17+, see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034
- desc: NewDesc(
- memstatNamespace("gc_cpu_fraction"),
- "The fraction of this program's available CPU time used by the GC since the program started.",
- nil, nil,
- ),
- eval: func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction },
- valType: GaugeValue,
- })
- return &goCollector{
- base: newBaseGoCollector(),
- msLast: &runtime.MemStats{},
- msRead: runtime.ReadMemStats,
- msMaxWait: time.Second,
- msMaxAge: 5 * time.Minute,
- msMetrics: msMetrics,
- }
-}
-
-// Describe returns all descriptions of the collector.
-func (c *goCollector) Describe(ch chan<- *Desc) {
- c.base.Describe(ch)
- for _, i := range c.msMetrics {
- ch <- i.desc
- }
-}
-
-// Collect returns the current state of all metrics of the collector.
-func (c *goCollector) Collect(ch chan<- Metric) {
- var (
- ms = &runtime.MemStats{}
- done = make(chan struct{})
- )
- // Start reading memstats first as it might take a while.
- go func() {
- c.msRead(ms)
- c.msMtx.Lock()
- c.msLast = ms
- c.msLastTimestamp = time.Now()
- c.msMtx.Unlock()
- close(done)
- }()
-
- // Collect base non-memory metrics.
- c.base.Collect(ch)
-
- timer := time.NewTimer(c.msMaxWait)
- select {
- case <-done: // Our own ReadMemStats succeeded in time. Use it.
- timer.Stop() // Important for high collection frequencies to not pile up timers.
- c.msCollect(ch, ms)
- return
- case <-timer.C: // Time out, use last memstats if possible. Continue below.
- }
- c.msMtx.Lock()
- if time.Since(c.msLastTimestamp) < c.msMaxAge {
- // Last memstats are recent enough. Collect from them under the lock.
- c.msCollect(ch, c.msLast)
- c.msMtx.Unlock()
- return
- }
- // If we are here, the last memstats are too old or don't exist. We have
- // to wait until our own ReadMemStats finally completes. For that to
- // happen, we have to release the lock.
- c.msMtx.Unlock()
- <-done
- c.msCollect(ch, ms)
-}
-
-func (c *goCollector) msCollect(ch chan<- Metric, ms *runtime.MemStats) {
- for _, i := range c.msMetrics {
- ch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms))
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go
deleted file mode 100644
index 511746417..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go
+++ /dev/null
@@ -1,574 +0,0 @@
-// Copyright 2021 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build go1.17
-// +build go1.17
-
-package prometheus
-
-import (
- "fmt"
- "math"
- "runtime"
- "runtime/metrics"
- "strings"
- "sync"
-
- "github.com/prometheus/client_golang/prometheus/internal"
-
- dto "github.com/prometheus/client_model/go"
- "google.golang.org/protobuf/proto"
-)
-
-const (
- // constants for strings referenced more than once.
- goGCHeapTinyAllocsObjects = "/gc/heap/tiny/allocs:objects"
- goGCHeapAllocsObjects = "/gc/heap/allocs:objects"
- goGCHeapFreesObjects = "/gc/heap/frees:objects"
- goGCHeapFreesBytes = "/gc/heap/frees:bytes"
- goGCHeapAllocsBytes = "/gc/heap/allocs:bytes"
- goGCHeapObjects = "/gc/heap/objects:objects"
- goGCHeapGoalBytes = "/gc/heap/goal:bytes"
- goMemoryClassesTotalBytes = "/memory/classes/total:bytes"
- goMemoryClassesHeapObjectsBytes = "/memory/classes/heap/objects:bytes"
- goMemoryClassesHeapUnusedBytes = "/memory/classes/heap/unused:bytes"
- goMemoryClassesHeapReleasedBytes = "/memory/classes/heap/released:bytes"
- goMemoryClassesHeapFreeBytes = "/memory/classes/heap/free:bytes"
- goMemoryClassesHeapStacksBytes = "/memory/classes/heap/stacks:bytes"
- goMemoryClassesOSStacksBytes = "/memory/classes/os-stacks:bytes"
- goMemoryClassesMetadataMSpanInuseBytes = "/memory/classes/metadata/mspan/inuse:bytes"
- goMemoryClassesMetadataMSPanFreeBytes = "/memory/classes/metadata/mspan/free:bytes"
- goMemoryClassesMetadataMCacheInuseBytes = "/memory/classes/metadata/mcache/inuse:bytes"
- goMemoryClassesMetadataMCacheFreeBytes = "/memory/classes/metadata/mcache/free:bytes"
- goMemoryClassesProfilingBucketsBytes = "/memory/classes/profiling/buckets:bytes"
- goMemoryClassesMetadataOtherBytes = "/memory/classes/metadata/other:bytes"
- goMemoryClassesOtherBytes = "/memory/classes/other:bytes"
-)
-
-// rmNamesForMemStatsMetrics represents runtime/metrics names required to populate goRuntimeMemStats from like logic.
-var rmNamesForMemStatsMetrics = []string{
- goGCHeapTinyAllocsObjects,
- goGCHeapAllocsObjects,
- goGCHeapFreesObjects,
- goGCHeapAllocsBytes,
- goGCHeapObjects,
- goGCHeapGoalBytes,
- goMemoryClassesTotalBytes,
- goMemoryClassesHeapObjectsBytes,
- goMemoryClassesHeapUnusedBytes,
- goMemoryClassesHeapReleasedBytes,
- goMemoryClassesHeapFreeBytes,
- goMemoryClassesHeapStacksBytes,
- goMemoryClassesOSStacksBytes,
- goMemoryClassesMetadataMSpanInuseBytes,
- goMemoryClassesMetadataMSPanFreeBytes,
- goMemoryClassesMetadataMCacheInuseBytes,
- goMemoryClassesMetadataMCacheFreeBytes,
- goMemoryClassesProfilingBucketsBytes,
- goMemoryClassesMetadataOtherBytes,
- goMemoryClassesOtherBytes,
-}
-
-func bestEffortLookupRM(lookup []string) []metrics.Description {
- ret := make([]metrics.Description, 0, len(lookup))
- for _, rm := range metrics.All() {
- for _, m := range lookup {
- if m == rm.Name {
- ret = append(ret, rm)
- }
- }
- }
- return ret
-}
-
-type goCollector struct {
- base baseGoCollector
-
- // mu protects updates to all fields ensuring a consistent
- // snapshot is always produced by Collect.
- mu sync.Mutex
-
- // Contains all samples that has to retrieved from runtime/metrics (not all of them will be exposed).
- sampleBuf []metrics.Sample
- // sampleMap allows lookup for MemStats metrics and runtime/metrics histograms for exact sums.
- sampleMap map[string]*metrics.Sample
-
- // rmExposedMetrics represents all runtime/metrics package metrics
- // that were configured to be exposed.
- rmExposedMetrics []collectorMetric
- rmExactSumMapForHist map[string]string
-
- // With Go 1.17, the runtime/metrics package was introduced.
- // From that point on, metric names produced by the runtime/metrics
- // package could be generated from runtime/metrics names. However,
- // these differ from the old names for the same values.
- //
- // This field exists to export the same values under the old names
- // as well.
- msMetrics memStatsMetrics
- msMetricsEnabled bool
-}
-
-type rmMetricDesc struct {
- metrics.Description
-}
-
-func matchRuntimeMetricsRules(rules []internal.GoCollectorRule) []rmMetricDesc {
- var descs []rmMetricDesc
- for _, d := range metrics.All() {
- var (
- deny = true
- desc rmMetricDesc
- )
-
- for _, r := range rules {
- if !r.Matcher.MatchString(d.Name) {
- continue
- }
- deny = r.Deny
- }
- if deny {
- continue
- }
-
- desc.Description = d
- descs = append(descs, desc)
- }
- return descs
-}
-
-func defaultGoCollectorOptions() internal.GoCollectorOptions {
- return internal.GoCollectorOptions{
- RuntimeMetricSumForHist: map[string]string{
- "/gc/heap/allocs-by-size:bytes": goGCHeapAllocsBytes,
- "/gc/heap/frees-by-size:bytes": goGCHeapFreesBytes,
- },
- RuntimeMetricRules: []internal.GoCollectorRule{
- // Recommended metrics we want by default from runtime/metrics.
- {Matcher: internal.GoCollectorDefaultRuntimeMetrics},
- },
- }
-}
-
-// NewGoCollector is the obsolete version of collectors.NewGoCollector.
-// See there for documentation.
-//
-// Deprecated: Use collectors.NewGoCollector instead.
-func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
- opt := defaultGoCollectorOptions()
- for _, o := range opts {
- o(&opt)
- }
-
- exposedDescriptions := matchRuntimeMetricsRules(opt.RuntimeMetricRules)
-
- // Collect all histogram samples so that we can get their buckets.
- // The API guarantees that the buckets are always fixed for the lifetime
- // of the process.
- var histograms []metrics.Sample
- for _, d := range exposedDescriptions {
- if d.Kind == metrics.KindFloat64Histogram {
- histograms = append(histograms, metrics.Sample{Name: d.Name})
- }
- }
-
- if len(histograms) > 0 {
- metrics.Read(histograms)
- }
-
- bucketsMap := make(map[string][]float64)
- for i := range histograms {
- bucketsMap[histograms[i].Name] = histograms[i].Value.Float64Histogram().Buckets
- }
-
- // Generate a collector for each exposed runtime/metrics metric.
- metricSet := make([]collectorMetric, 0, len(exposedDescriptions))
- // SampleBuf is used for reading from runtime/metrics.
- // We are assuming the largest case to have stable pointers for sampleMap purposes.
- sampleBuf := make([]metrics.Sample, 0, len(exposedDescriptions)+len(opt.RuntimeMetricSumForHist)+len(rmNamesForMemStatsMetrics))
- sampleMap := make(map[string]*metrics.Sample, len(exposedDescriptions))
- for _, d := range exposedDescriptions {
- namespace, subsystem, name, ok := internal.RuntimeMetricsToProm(&d.Description)
- if !ok {
- // Just ignore this metric; we can't do anything with it here.
- // If a user decides to use the latest version of Go, we don't want
- // to fail here. This condition is tested in TestExpectedRuntimeMetrics.
- continue
- }
- help := attachOriginalName(d.Description.Description, d.Name)
-
- sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name})
- sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1]
-
- var m collectorMetric
- if d.Kind == metrics.KindFloat64Histogram {
- _, hasSum := opt.RuntimeMetricSumForHist[d.Name]
- unit := d.Name[strings.IndexRune(d.Name, ':')+1:]
- m = newBatchHistogram(
- NewDesc(
- BuildFQName(namespace, subsystem, name),
- help,
- nil,
- nil,
- ),
- internal.RuntimeMetricsBucketsForUnit(bucketsMap[d.Name], unit),
- hasSum,
- )
- } else if d.Cumulative {
- m = NewCounter(CounterOpts{
- Namespace: namespace,
- Subsystem: subsystem,
- Name: name,
- Help: help,
- },
- )
- } else {
- m = NewGauge(GaugeOpts{
- Namespace: namespace,
- Subsystem: subsystem,
- Name: name,
- Help: help,
- })
- }
- metricSet = append(metricSet, m)
- }
-
- // Add exact sum metrics to sampleBuf if not added before.
- for _, h := range histograms {
- sumMetric, ok := opt.RuntimeMetricSumForHist[h.Name]
- if !ok {
- continue
- }
-
- if _, ok := sampleMap[sumMetric]; ok {
- continue
- }
- sampleBuf = append(sampleBuf, metrics.Sample{Name: sumMetric})
- sampleMap[sumMetric] = &sampleBuf[len(sampleBuf)-1]
- }
-
- var (
- msMetrics memStatsMetrics
- msDescriptions []metrics.Description
- )
-
- if !opt.DisableMemStatsLikeMetrics {
- msMetrics = goRuntimeMemStats()
- msDescriptions = bestEffortLookupRM(rmNamesForMemStatsMetrics)
-
- // Check if metric was not exposed before and if not, add to sampleBuf.
- for _, mdDesc := range msDescriptions {
- if _, ok := sampleMap[mdDesc.Name]; ok {
- continue
- }
- sampleBuf = append(sampleBuf, metrics.Sample{Name: mdDesc.Name})
- sampleMap[mdDesc.Name] = &sampleBuf[len(sampleBuf)-1]
- }
- }
-
- return &goCollector{
- base: newBaseGoCollector(),
- sampleBuf: sampleBuf,
- sampleMap: sampleMap,
- rmExposedMetrics: metricSet,
- rmExactSumMapForHist: opt.RuntimeMetricSumForHist,
- msMetrics: msMetrics,
- msMetricsEnabled: !opt.DisableMemStatsLikeMetrics,
- }
-}
-
-func attachOriginalName(desc, origName string) string {
- return fmt.Sprintf("%s Sourced from %s", desc, origName)
-}
-
-// Describe returns all descriptions of the collector.
-func (c *goCollector) Describe(ch chan<- *Desc) {
- c.base.Describe(ch)
- for _, i := range c.msMetrics {
- ch <- i.desc
- }
- for _, m := range c.rmExposedMetrics {
- ch <- m.Desc()
- }
-}
-
-// Collect returns the current state of all metrics of the collector.
-func (c *goCollector) Collect(ch chan<- Metric) {
- // Collect base non-memory metrics.
- c.base.Collect(ch)
-
- if len(c.sampleBuf) == 0 {
- return
- }
-
- // Collect must be thread-safe, so prevent concurrent use of
- // sampleBuf elements. Just read into sampleBuf but write all the data
- // we get into our Metrics or MemStats.
- //
- // This lock also ensures that the Metrics we send out are all from
- // the same updates, ensuring their mutual consistency insofar as
- // is guaranteed by the runtime/metrics package.
- //
- // N.B. This locking is heavy-handed, but Collect is expected to be called
- // relatively infrequently. Also the core operation here, metrics.Read,
- // is fast (O(tens of microseconds)) so contention should certainly be
- // low, though channel operations and any allocations may add to that.
- c.mu.Lock()
- defer c.mu.Unlock()
-
- // Populate runtime/metrics sample buffer.
- metrics.Read(c.sampleBuf)
-
- // Collect all our runtime/metrics user chose to expose from sampleBuf (if any).
- for i, metric := range c.rmExposedMetrics {
- // We created samples for exposed metrics first in order, so indexes match.
- sample := c.sampleBuf[i]
-
- // N.B. switch on concrete type because it's significantly more efficient
- // than checking for the Counter and Gauge interface implementations. In
- // this case, we control all the types here.
- switch m := metric.(type) {
- case *counter:
- // Guard against decreases. This should never happen, but a failure
- // to do so will result in a panic, which is a harsh consequence for
- // a metrics collection bug.
- v0, v1 := m.get(), unwrapScalarRMValue(sample.Value)
- if v1 > v0 {
- m.Add(unwrapScalarRMValue(sample.Value) - m.get())
- }
- m.Collect(ch)
- case *gauge:
- m.Set(unwrapScalarRMValue(sample.Value))
- m.Collect(ch)
- case *batchHistogram:
- m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name))
- m.Collect(ch)
- default:
- panic("unexpected metric type")
- }
- }
-
- if c.msMetricsEnabled {
- // ms is a dummy MemStats that we populate ourselves so that we can
- // populate the old metrics from it if goMemStatsCollection is enabled.
- var ms runtime.MemStats
- memStatsFromRM(&ms, c.sampleMap)
- for _, i := range c.msMetrics {
- ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms))
- }
- }
-}
-
-// unwrapScalarRMValue unwraps a runtime/metrics value that is assumed
-// to be scalar and returns the equivalent float64 value. Panics if the
-// value is not scalar.
-func unwrapScalarRMValue(v metrics.Value) float64 {
- switch v.Kind() {
- case metrics.KindUint64:
- return float64(v.Uint64())
- case metrics.KindFloat64:
- return v.Float64()
- case metrics.KindBad:
- // Unsupported metric.
- //
- // This should never happen because we always populate our metric
- // set from the runtime/metrics package.
- panic("unexpected bad kind metric")
- default:
- // Unsupported metric kind.
- //
- // This should never happen because we check for this during initialization
- // and flag and filter metrics whose kinds we don't understand.
- panic(fmt.Sprintf("unexpected unsupported metric: %v", v.Kind()))
- }
-}
-
-// exactSumFor takes a runtime/metrics metric name (that is assumed to
-// be of kind KindFloat64Histogram) and returns its exact sum and whether
-// its exact sum exists.
-//
-// The runtime/metrics API for histograms doesn't currently expose exact
-// sums, but some of the other metrics are in fact exact sums of histograms.
-func (c *goCollector) exactSumFor(rmName string) float64 {
- sumName, ok := c.rmExactSumMapForHist[rmName]
- if !ok {
- return 0
- }
- s, ok := c.sampleMap[sumName]
- if !ok {
- return 0
- }
- return unwrapScalarRMValue(s.Value)
-}
-
-func memStatsFromRM(ms *runtime.MemStats, rm map[string]*metrics.Sample) {
- lookupOrZero := func(name string) uint64 {
- if s, ok := rm[name]; ok {
- return s.Value.Uint64()
- }
- return 0
- }
-
- // Currently, MemStats adds tiny alloc count to both Mallocs AND Frees.
- // The reason for this is because MemStats couldn't be extended at the time
- // but there was a desire to have Mallocs at least be a little more representative,
- // while having Mallocs - Frees still represent a live object count.
- // Unfortunately, MemStats doesn't actually export a large allocation count,
- // so it's impossible to pull this number out directly.
- tinyAllocs := lookupOrZero(goGCHeapTinyAllocsObjects)
- ms.Mallocs = lookupOrZero(goGCHeapAllocsObjects) + tinyAllocs
- ms.Frees = lookupOrZero(goGCHeapFreesObjects) + tinyAllocs
-
- ms.TotalAlloc = lookupOrZero(goGCHeapAllocsBytes)
- ms.Sys = lookupOrZero(goMemoryClassesTotalBytes)
- ms.Lookups = 0 // Already always zero.
- ms.HeapAlloc = lookupOrZero(goMemoryClassesHeapObjectsBytes)
- ms.Alloc = ms.HeapAlloc
- ms.HeapInuse = ms.HeapAlloc + lookupOrZero(goMemoryClassesHeapUnusedBytes)
- ms.HeapReleased = lookupOrZero(goMemoryClassesHeapReleasedBytes)
- ms.HeapIdle = ms.HeapReleased + lookupOrZero(goMemoryClassesHeapFreeBytes)
- ms.HeapSys = ms.HeapInuse + ms.HeapIdle
- ms.HeapObjects = lookupOrZero(goGCHeapObjects)
- ms.StackInuse = lookupOrZero(goMemoryClassesHeapStacksBytes)
- ms.StackSys = ms.StackInuse + lookupOrZero(goMemoryClassesOSStacksBytes)
- ms.MSpanInuse = lookupOrZero(goMemoryClassesMetadataMSpanInuseBytes)
- ms.MSpanSys = ms.MSpanInuse + lookupOrZero(goMemoryClassesMetadataMSPanFreeBytes)
- ms.MCacheInuse = lookupOrZero(goMemoryClassesMetadataMCacheInuseBytes)
- ms.MCacheSys = ms.MCacheInuse + lookupOrZero(goMemoryClassesMetadataMCacheFreeBytes)
- ms.BuckHashSys = lookupOrZero(goMemoryClassesProfilingBucketsBytes)
- ms.GCSys = lookupOrZero(goMemoryClassesMetadataOtherBytes)
- ms.OtherSys = lookupOrZero(goMemoryClassesOtherBytes)
- ms.NextGC = lookupOrZero(goGCHeapGoalBytes)
-
- // N.B. GCCPUFraction is intentionally omitted. This metric is not useful,
- // and often misleading due to the fact that it's an average over the lifetime
- // of the process.
- // See https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034
- // for more details.
- ms.GCCPUFraction = 0
-}
-
-// batchHistogram is a mutable histogram that is updated
-// in batches.
-type batchHistogram struct {
- selfCollector
-
- // Static fields updated only once.
- desc *Desc
- hasSum bool
-
- // Because this histogram operates in batches, it just uses a
- // single mutex for everything. updates are always serialized
- // but Write calls may operate concurrently with updates.
- // Contention between these two sources should be rare.
- mu sync.Mutex
- buckets []float64 // Inclusive lower bounds, like runtime/metrics.
- counts []uint64
- sum float64 // Used if hasSum is true.
-}
-
-// newBatchHistogram creates a new batch histogram value with the given
-// Desc, buckets, and whether or not it has an exact sum available.
-//
-// buckets must always be from the runtime/metrics package, following
-// the same conventions.
-func newBatchHistogram(desc *Desc, buckets []float64, hasSum bool) *batchHistogram {
- // We need to remove -Inf values. runtime/metrics keeps them around.
- // But -Inf bucket should not be allowed for prometheus histograms.
- if buckets[0] == math.Inf(-1) {
- buckets = buckets[1:]
- }
- h := &batchHistogram{
- desc: desc,
- buckets: buckets,
- // Because buckets follows runtime/metrics conventions, there's
- // 1 more value in the buckets list than there are buckets represented,
- // because in runtime/metrics, the bucket values represent *boundaries*,
- // and non-Inf boundaries are inclusive lower bounds for that bucket.
- counts: make([]uint64, len(buckets)-1),
- hasSum: hasSum,
- }
- h.init(h)
- return h
-}
-
-// update updates the batchHistogram from a runtime/metrics histogram.
-//
-// sum must be provided if the batchHistogram was created to have an exact sum.
-// h.buckets must be a strict subset of his.Buckets.
-func (h *batchHistogram) update(his *metrics.Float64Histogram, sum float64) {
- counts, buckets := his.Counts, his.Buckets
-
- h.mu.Lock()
- defer h.mu.Unlock()
-
- // Clear buckets.
- for i := range h.counts {
- h.counts[i] = 0
- }
- // Copy and reduce buckets.
- var j int
- for i, count := range counts {
- h.counts[j] += count
- if buckets[i+1] == h.buckets[j+1] {
- j++
- }
- }
- if h.hasSum {
- h.sum = sum
- }
-}
-
-func (h *batchHistogram) Desc() *Desc {
- return h.desc
-}
-
-func (h *batchHistogram) Write(out *dto.Metric) error {
- h.mu.Lock()
- defer h.mu.Unlock()
-
- sum := float64(0)
- if h.hasSum {
- sum = h.sum
- }
- dtoBuckets := make([]*dto.Bucket, 0, len(h.counts))
- totalCount := uint64(0)
- for i, count := range h.counts {
- totalCount += count
- if !h.hasSum {
- if count != 0 {
- // N.B. This computed sum is an underestimate.
- sum += h.buckets[i] * float64(count)
- }
- }
-
- // Skip the +Inf bucket, but only for the bucket list.
- // It must still count for sum and totalCount.
- if math.IsInf(h.buckets[i+1], 1) {
- break
- }
- // Float64Histogram's upper bound is exclusive, so make it inclusive
- // by obtaining the next float64 value down, in order.
- upperBound := math.Nextafter(h.buckets[i+1], h.buckets[i])
- dtoBuckets = append(dtoBuckets, &dto.Bucket{
- CumulativeCount: proto.Uint64(totalCount),
- UpperBound: proto.Float64(upperBound),
- })
- }
- out.Histogram = &dto.Histogram{
- Bucket: dtoBuckets,
- SampleCount: proto.Uint64(totalCount),
- SampleSum: proto.Float64(sum),
- }
- return nil
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
deleted file mode 100644
index 519db348a..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
+++ /dev/null
@@ -1,1837 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "fmt"
- "math"
- "runtime"
- "sort"
- "sync"
- "sync/atomic"
- "time"
-
- dto "github.com/prometheus/client_model/go"
-
- "google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/types/known/timestamppb"
-)
-
-// nativeHistogramBounds for the frac of observed values. Only relevant for
-// schema > 0. The position in the slice is the schema. (0 is never used, just
-// here for convenience of using the schema directly as the index.)
-//
-// TODO(beorn7): Currently, we do a binary search into these slices. There are
-// ways to turn it into a small number of simple array lookups. It probably only
-// matters for schema 5 and beyond, but should be investigated. See this comment
-// as a starting point:
-// https://github.com/open-telemetry/opentelemetry-specification/issues/1776#issuecomment-870164310
-var nativeHistogramBounds = [][]float64{
- // Schema "0":
- {0.5},
- // Schema 1:
- {0.5, 0.7071067811865475},
- // Schema 2:
- {0.5, 0.5946035575013605, 0.7071067811865475, 0.8408964152537144},
- // Schema 3:
- {
- 0.5, 0.5452538663326288, 0.5946035575013605, 0.6484197773255048,
- 0.7071067811865475, 0.7711054127039704, 0.8408964152537144, 0.9170040432046711,
- },
- // Schema 4:
- {
- 0.5, 0.5221368912137069, 0.5452538663326288, 0.5693943173783458,
- 0.5946035575013605, 0.620928906036742, 0.6484197773255048, 0.6771277734684463,
- 0.7071067811865475, 0.7384130729697496, 0.7711054127039704, 0.805245165974627,
- 0.8408964152537144, 0.8781260801866495, 0.9170040432046711, 0.9576032806985735,
- },
- // Schema 5:
- {
- 0.5, 0.5109485743270583, 0.5221368912137069, 0.5335702003384117,
- 0.5452538663326288, 0.5571933712979462, 0.5693943173783458, 0.5818624293887887,
- 0.5946035575013605, 0.6076236799902344, 0.620928906036742, 0.6345254785958666,
- 0.6484197773255048, 0.6626183215798706, 0.6771277734684463, 0.6919549409819159,
- 0.7071067811865475, 0.7225904034885232, 0.7384130729697496, 0.7545822137967112,
- 0.7711054127039704, 0.7879904225539431, 0.805245165974627, 0.8228777390769823,
- 0.8408964152537144, 0.8593096490612387, 0.8781260801866495, 0.8973545375015533,
- 0.9170040432046711, 0.9370838170551498, 0.9576032806985735, 0.9785720620876999,
- },
- // Schema 6:
- {
- 0.5, 0.5054446430258502, 0.5109485743270583, 0.5165124395106142,
- 0.5221368912137069, 0.5278225891802786, 0.5335702003384117, 0.5393803988785598,
- 0.5452538663326288, 0.5511912916539204, 0.5571933712979462, 0.5632608093041209,
- 0.5693943173783458, 0.5755946149764913, 0.5818624293887887, 0.5881984958251406,
- 0.5946035575013605, 0.6010783657263515, 0.6076236799902344, 0.6142402680534349,
- 0.620928906036742, 0.6276903785123455, 0.6345254785958666, 0.6414350080393891,
- 0.6484197773255048, 0.6554806057623822, 0.6626183215798706, 0.6698337620266515,
- 0.6771277734684463, 0.6845012114872953, 0.6919549409819159, 0.6994898362691555,
- 0.7071067811865475, 0.7148066691959849, 0.7225904034885232, 0.7304588970903234,
- 0.7384130729697496, 0.7464538641456323, 0.7545822137967112, 0.762799075372269,
- 0.7711054127039704, 0.7795022001189185, 0.7879904225539431, 0.7965710756711334,
- 0.805245165974627, 0.8140137109286738, 0.8228777390769823, 0.8318382901633681,
- 0.8408964152537144, 0.8500531768592616, 0.8593096490612387, 0.8686669176368529,
- 0.8781260801866495, 0.8876882462632604, 0.8973545375015533, 0.9071260877501991,
- 0.9170040432046711, 0.9269895625416926, 0.9370838170551498, 0.9472879907934827,
- 0.9576032806985735, 0.9680308967461471, 0.9785720620876999, 0.9892280131939752,
- },
- // Schema 7:
- {
- 0.5, 0.5027149505564014, 0.5054446430258502, 0.5081891574554764,
- 0.5109485743270583, 0.5137229745593818, 0.5165124395106142, 0.5193170509806894,
- 0.5221368912137069, 0.5249720429003435, 0.5278225891802786, 0.5306886136446309,
- 0.5335702003384117, 0.5364674337629877, 0.5393803988785598, 0.5423091811066545,
- 0.5452538663326288, 0.5482145409081883, 0.5511912916539204, 0.5541842058618393,
- 0.5571933712979462, 0.5602188762048033, 0.5632608093041209, 0.5663192597993595,
- 0.5693943173783458, 0.572486072215902, 0.5755946149764913, 0.5787200368168754,
- 0.5818624293887887, 0.585021884841625, 0.5881984958251406, 0.5913923554921704,
- 0.5946035575013605, 0.5978321960199137, 0.6010783657263515, 0.6043421618132907,
- 0.6076236799902344, 0.6109230164863786, 0.6142402680534349, 0.6175755319684665,
- 0.620928906036742, 0.6243004885946023, 0.6276903785123455, 0.6310986751971253,
- 0.6345254785958666, 0.637970889198196, 0.6414350080393891, 0.6449179367033329,
- 0.6484197773255048, 0.6519406325959679, 0.6554806057623822, 0.659039800633032,
- 0.6626183215798706, 0.6662162735415805, 0.6698337620266515, 0.6734708931164728,
- 0.6771277734684463, 0.6808045103191123, 0.6845012114872953, 0.688217985377265,
- 0.6919549409819159, 0.6957121878859629, 0.6994898362691555, 0.7032879969095076,
- 0.7071067811865475, 0.7109463010845827, 0.7148066691959849, 0.718687998724491,
- 0.7225904034885232, 0.7265139979245261, 0.7304588970903234, 0.7344252166684908,
- 0.7384130729697496, 0.7424225829363761, 0.7464538641456323, 0.7505070348132126,
- 0.7545822137967112, 0.7586795205991071, 0.762799075372269, 0.7669409989204777,
- 0.7711054127039704, 0.7752924388424999, 0.7795022001189185, 0.7837348199827764,
- 0.7879904225539431, 0.7922691326262467, 0.7965710756711334, 0.8008963778413465,
- 0.805245165974627, 0.8096175675974316, 0.8140137109286738, 0.8184337248834821,
- 0.8228777390769823, 0.8273458838280969, 0.8318382901633681, 0.8363550898207981,
- 0.8408964152537144, 0.8454623996346523, 0.8500531768592616, 0.8546688815502312,
- 0.8593096490612387, 0.8639756154809185, 0.8686669176368529, 0.8733836930995842,
- 0.8781260801866495, 0.8828942179666361, 0.8876882462632604, 0.8925083056594671,
- 0.8973545375015533, 0.9022270839033115, 0.9071260877501991, 0.9120516927035263,
- 0.9170040432046711, 0.9219832844793128, 0.9269895625416926, 0.9320230241988943,
- 0.9370838170551498, 0.9421720895161669, 0.9472879907934827, 0.9524316709088368,
- 0.9576032806985735, 0.9628029718180622, 0.9680308967461471, 0.9732872087896164,
- 0.9785720620876999, 0.9838856116165875, 0.9892280131939752, 0.9945994234836328,
- },
- // Schema 8:
- {
- 0.5, 0.5013556375251013, 0.5027149505564014, 0.5040779490592088,
- 0.5054446430258502, 0.5068150424757447, 0.5081891574554764, 0.509566998038869,
- 0.5109485743270583, 0.5123338964485679, 0.5137229745593818, 0.5151158188430205,
- 0.5165124395106142, 0.5179128468009786, 0.5193170509806894, 0.520725062344158,
- 0.5221368912137069, 0.5235525479396449, 0.5249720429003435, 0.526395386502313,
- 0.5278225891802786, 0.5292536613972564, 0.5306886136446309, 0.5321274564422321,
- 0.5335702003384117, 0.5350168559101208, 0.5364674337629877, 0.5379219445313954,
- 0.5393803988785598, 0.5408428074966075, 0.5423091811066545, 0.5437795304588847,
- 0.5452538663326288, 0.5467321995364429, 0.5482145409081883, 0.549700901315111,
- 0.5511912916539204, 0.5526857228508706, 0.5541842058618393, 0.5556867516724088,
- 0.5571933712979462, 0.5587040757836845, 0.5602188762048033, 0.5617377836665098,
- 0.5632608093041209, 0.564787964283144, 0.5663192597993595, 0.5678547070789026,
- 0.5693943173783458, 0.5709381019847808, 0.572486072215902, 0.5740382394200894,
- 0.5755946149764913, 0.5771552102951081, 0.5787200368168754, 0.5802891060137493,
- 0.5818624293887887, 0.5834400184762408, 0.585021884841625, 0.5866080400818185,
- 0.5881984958251406, 0.5897932637314379, 0.5913923554921704, 0.5929957828304968,
- 0.5946035575013605, 0.5962156912915756, 0.5978321960199137, 0.5994530835371903,
- 0.6010783657263515, 0.6027080545025619, 0.6043421618132907, 0.6059806996384005,
- 0.6076236799902344, 0.6092711149137041, 0.6109230164863786, 0.6125793968185725,
- 0.6142402680534349, 0.6159056423670379, 0.6175755319684665, 0.6192499490999082,
- 0.620928906036742, 0.622612415087629, 0.6243004885946023, 0.6259931389331581,
- 0.6276903785123455, 0.6293922197748583, 0.6310986751971253, 0.6328097572894031,
- 0.6345254785958666, 0.6362458516947014, 0.637970889198196, 0.6397006037528346,
- 0.6414350080393891, 0.6431741147730128, 0.6449179367033329, 0.6466664866145447,
- 0.6484197773255048, 0.6501778216898253, 0.6519406325959679, 0.6537082229673385,
- 0.6554806057623822, 0.6572577939746774, 0.659039800633032, 0.6608266388015788,
- 0.6626183215798706, 0.6644148621029772, 0.6662162735415805, 0.6680225691020727,
- 0.6698337620266515, 0.6716498655934177, 0.6734708931164728, 0.6752968579460171,
- 0.6771277734684463, 0.6789636531064505, 0.6808045103191123, 0.6826503586020058,
- 0.6845012114872953, 0.6863570825438342, 0.688217985377265, 0.690083933630119,
- 0.6919549409819159, 0.6938310211492645, 0.6957121878859629, 0.6975984549830999,
- 0.6994898362691555, 0.7013863456101023, 0.7032879969095076, 0.7051948041086352,
- 0.7071067811865475, 0.7090239421602076, 0.7109463010845827, 0.7128738720527471,
- 0.7148066691959849, 0.7167447066838943, 0.718687998724491, 0.7206365595643126,
- 0.7225904034885232, 0.7245495448210174, 0.7265139979245261, 0.7284837772007218,
- 0.7304588970903234, 0.7324393720732029, 0.7344252166684908, 0.7364164454346837,
- 0.7384130729697496, 0.7404151139112358, 0.7424225829363761, 0.7444354947621984,
- 0.7464538641456323, 0.7484777058836176, 0.7505070348132126, 0.7525418658117031,
- 0.7545822137967112, 0.7566280937263048, 0.7586795205991071, 0.7607365094544071,
- 0.762799075372269, 0.7648672334736434, 0.7669409989204777, 0.7690203869158282,
- 0.7711054127039704, 0.7731960915705107, 0.7752924388424999, 0.7773944698885442,
- 0.7795022001189185, 0.7816156449856788, 0.7837348199827764, 0.7858597406461707,
- 0.7879904225539431, 0.7901268813264122, 0.7922691326262467, 0.7944171921585818,
- 0.7965710756711334, 0.7987307989543135, 0.8008963778413465, 0.8030678282083853,
- 0.805245165974627, 0.8074284071024302, 0.8096175675974316, 0.8118126635086642,
- 0.8140137109286738, 0.8162207259936375, 0.8184337248834821, 0.820652723822003,
- 0.8228777390769823, 0.8251087869603088, 0.8273458838280969, 0.8295890460808079,
- 0.8318382901633681, 0.8340936325652911, 0.8363550898207981, 0.8386226785089391,
- 0.8408964152537144, 0.8431763167241966, 0.8454623996346523, 0.8477546807446661,
- 0.8500531768592616, 0.8523579048290255, 0.8546688815502312, 0.8569861239649629,
- 0.8593096490612387, 0.8616394738731368, 0.8639756154809185, 0.8663180910111553,
- 0.8686669176368529, 0.871022112577578, 0.8733836930995842, 0.8757516765159389,
- 0.8781260801866495, 0.8805069215187917, 0.8828942179666361, 0.8852879870317771,
- 0.8876882462632604, 0.890095013257712, 0.8925083056594671, 0.8949281411607002,
- 0.8973545375015533, 0.8997875124702672, 0.9022270839033115, 0.9046732696855155,
- 0.9071260877501991, 0.909585556079304, 0.9120516927035263, 0.9145245157024483,
- 0.9170040432046711, 0.9194902933879467, 0.9219832844793128, 0.9244830347552253,
- 0.9269895625416926, 0.92950288621441, 0.9320230241988943, 0.9345499949706191,
- 0.9370838170551498, 0.93962450902828, 0.9421720895161669, 0.9447265771954693,
- 0.9472879907934827, 0.9498563490882775, 0.9524316709088368, 0.9550139751351947,
- 0.9576032806985735, 0.9601996065815236, 0.9628029718180622, 0.9654133954938133,
- 0.9680308967461471, 0.9706554947643201, 0.9732872087896164, 0.9759260581154889,
- 0.9785720620876999, 0.9812252401044634, 0.9838856116165875, 0.9865531961276168,
- 0.9892280131939752, 0.9919100824251095, 0.9945994234836328, 0.9972960560854698,
- },
-}
-
-// The nativeHistogramBounds above can be generated with the code below.
-//
-// TODO(beorn7): It's tempting to actually use `go generate` to generate the
-// code above. However, this could lead to slightly different numbers on
-// different architectures. We still need to come to terms if we are fine with
-// that, or if we might prefer to specify precise numbers in the standard.
-//
-// var nativeHistogramBounds [][]float64 = make([][]float64, 9)
-//
-// func init() {
-// // Populate nativeHistogramBounds.
-// numBuckets := 1
-// for i := range nativeHistogramBounds {
-// bounds := []float64{0.5}
-// factor := math.Exp2(math.Exp2(float64(-i)))
-// for j := 0; j < numBuckets-1; j++ {
-// var bound float64
-// if (j+1)%2 == 0 {
-// // Use previously calculated value for increased precision.
-// bound = nativeHistogramBounds[i-1][j/2+1]
-// } else {
-// bound = bounds[j] * factor
-// }
-// bounds = append(bounds, bound)
-// }
-// numBuckets *= 2
-// nativeHistogramBounds[i] = bounds
-// }
-// }
-
-// A Histogram counts individual observations from an event or sample stream in
-// configurable static buckets (or in dynamic sparse buckets as part of the
-// experimental Native Histograms, see below for more details). Similar to a
-// Summary, it also provides a sum of observations and an observation count.
-//
-// On the Prometheus server, quantiles can be calculated from a Histogram using
-// the histogram_quantile PromQL function.
-//
-// Note that Histograms, in contrast to Summaries, can be aggregated in PromQL
-// (see the documentation for detailed procedures). However, Histograms require
-// the user to pre-define suitable buckets, and they are in general less
-// accurate. (Both problems are addressed by the experimental Native
-// Histograms. To use them, configure a NativeHistogramBucketFactor in the
-// HistogramOpts. They also require a Prometheus server v2.40+ with the
-// corresponding feature flag enabled.)
-//
-// The Observe method of a Histogram has a very low performance overhead in
-// comparison with the Observe method of a Summary.
-//
-// To create Histogram instances, use NewHistogram.
-type Histogram interface {
- Metric
- Collector
-
- // Observe adds a single observation to the histogram. Observations are
- // usually positive or zero. Negative observations are accepted but
- // prevent current versions of Prometheus from properly detecting
- // counter resets in the sum of observations. (The experimental Native
- // Histograms handle negative observations properly.) See
- // https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations
- // for details.
- Observe(float64)
-}
-
-// bucketLabel is used for the label that defines the upper bound of a
-// bucket of a histogram ("le" -> "less or equal").
-const bucketLabel = "le"
-
-// DefBuckets are the default Histogram buckets. The default buckets are
-// tailored to broadly measure the response time (in seconds) of a network
-// service. Most likely, however, you will be required to define buckets
-// customized to your use case.
-var DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}
-
-// DefNativeHistogramZeroThreshold is the default value for
-// NativeHistogramZeroThreshold in the HistogramOpts.
-//
-// The value is 2^-128 (or 0.5*2^-127 in the actual IEEE 754 representation),
-// which is a bucket boundary at all possible resolutions.
-const DefNativeHistogramZeroThreshold = 2.938735877055719e-39
-
-// NativeHistogramZeroThresholdZero can be used as NativeHistogramZeroThreshold
-// in the HistogramOpts to create a zero bucket of width zero, i.e. a zero
-// bucket that only receives observations of precisely zero.
-const NativeHistogramZeroThresholdZero = -1
-
-var errBucketLabelNotAllowed = fmt.Errorf(
- "%q is not allowed as label name in histograms", bucketLabel,
-)
-
-// LinearBuckets creates 'count' regular buckets, each 'width' wide, where the
-// lowest bucket has an upper bound of 'start'. The final +Inf bucket is not
-// counted and not included in the returned slice. The returned slice is meant
-// to be used for the Buckets field of HistogramOpts.
-//
-// The function panics if 'count' is zero or negative.
-func LinearBuckets(start, width float64, count int) []float64 {
- if count < 1 {
- panic("LinearBuckets needs a positive count")
- }
- buckets := make([]float64, count)
- for i := range buckets {
- buckets[i] = start
- start += width
- }
- return buckets
-}
-
-// ExponentialBuckets creates 'count' regular buckets, where the lowest bucket
-// has an upper bound of 'start' and each following bucket's upper bound is
-// 'factor' times the previous bucket's upper bound. The final +Inf bucket is
-// not counted and not included in the returned slice. The returned slice is
-// meant to be used for the Buckets field of HistogramOpts.
-//
-// The function panics if 'count' is 0 or negative, if 'start' is 0 or negative,
-// or if 'factor' is less than or equal 1.
-func ExponentialBuckets(start, factor float64, count int) []float64 {
- if count < 1 {
- panic("ExponentialBuckets needs a positive count")
- }
- if start <= 0 {
- panic("ExponentialBuckets needs a positive start value")
- }
- if factor <= 1 {
- panic("ExponentialBuckets needs a factor greater than 1")
- }
- buckets := make([]float64, count)
- for i := range buckets {
- buckets[i] = start
- start *= factor
- }
- return buckets
-}
-
-// ExponentialBucketsRange creates 'count' buckets, where the lowest bucket is
-// 'min' and the highest bucket is 'max'. The final +Inf bucket is not counted
-// and not included in the returned slice. The returned slice is meant to be
-// used for the Buckets field of HistogramOpts.
-//
-// The function panics if 'count' is 0 or negative, if 'min' is 0 or negative.
-func ExponentialBucketsRange(min, max float64, count int) []float64 {
- if count < 1 {
- panic("ExponentialBucketsRange count needs a positive count")
- }
- if min <= 0 {
- panic("ExponentialBucketsRange min needs to be greater than 0")
- }
-
- // Formula for exponential buckets.
- // max = min*growthFactor^(bucketCount-1)
-
- // We know max/min and highest bucket. Solve for growthFactor.
- growthFactor := math.Pow(max/min, 1.0/float64(count-1))
-
- // Now that we know growthFactor, solve for each bucket.
- buckets := make([]float64, count)
- for i := 1; i <= count; i++ {
- buckets[i-1] = min * math.Pow(growthFactor, float64(i-1))
- }
- return buckets
-}
-
-// HistogramOpts bundles the options for creating a Histogram metric. It is
-// mandatory to set Name to a non-empty string. All other fields are optional
-// and can safely be left at their zero value, although it is strongly
-// encouraged to set a Help string.
-type HistogramOpts struct {
- // Namespace, Subsystem, and Name are components of the fully-qualified
- // name of the Histogram (created by joining these components with
- // "_"). Only Name is mandatory, the others merely help structuring the
- // name. Note that the fully-qualified name of the Histogram must be a
- // valid Prometheus metric name.
- Namespace string
- Subsystem string
- Name string
-
- // Help provides information about this Histogram.
- //
- // Metrics with the same fully-qualified name must have the same Help
- // string.
- Help string
-
- // ConstLabels are used to attach fixed labels to this metric. Metrics
- // with the same fully-qualified name must have the same label names in
- // their ConstLabels.
- //
- // ConstLabels are only used rarely. In particular, do not use them to
- // attach the same labels to all your metrics. Those use cases are
- // better covered by target labels set by the scraping Prometheus
- // server, or by one specific metric (e.g. a build_info or a
- // machine_role metric). See also
- // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels
- ConstLabels Labels
-
- // Buckets defines the buckets into which observations are counted. Each
- // element in the slice is the upper inclusive bound of a bucket. The
- // values must be sorted in strictly increasing order. There is no need
- // to add a highest bucket with +Inf bound, it will be added
- // implicitly. If Buckets is left as nil or set to a slice of length
- // zero, it is replaced by default buckets. The default buckets are
- // DefBuckets if no buckets for a native histogram (see below) are used,
- // otherwise the default is no buckets. (In other words, if you want to
- // use both regular buckets and buckets for a native histogram, you have
- // to define the regular buckets here explicitly.)
- Buckets []float64
-
- // If NativeHistogramBucketFactor is greater than one, so-called sparse
- // buckets are used (in addition to the regular buckets, if defined
- // above). A Histogram with sparse buckets will be ingested as a Native
- // Histogram by a Prometheus server with that feature enabled (requires
- // Prometheus v2.40+). Sparse buckets are exponential buckets covering
- // the whole float64 range (with the exception of the “zero” bucket, see
- // NativeHistogramZeroThreshold below). From any one bucket to the next,
- // the width of the bucket grows by a constant
- // factor. NativeHistogramBucketFactor provides an upper bound for this
- // factor (exception see below). The smaller
- // NativeHistogramBucketFactor, the more buckets will be used and thus
- // the more costly the histogram will become. A generally good trade-off
- // between cost and accuracy is a value of 1.1 (each bucket is at most
- // 10% wider than the previous one), which will result in each power of
- // two divided into 8 buckets (e.g. there will be 8 buckets between 1
- // and 2, same as between 2 and 4, and 4 and 8, etc.).
- //
- // Details about the actually used factor: The factor is calculated as
- // 2^(2^-n), where n is an integer number between (and including) -4 and
- // 8. n is chosen so that the resulting factor is the largest that is
- // still smaller or equal to NativeHistogramBucketFactor. Note that the
- // smallest possible factor is therefore approx. 1.00271 (i.e. 2^(2^-8)
- // ). If NativeHistogramBucketFactor is greater than 1 but smaller than
- // 2^(2^-8), then the actually used factor is still 2^(2^-8) even though
- // it is larger than the provided NativeHistogramBucketFactor.
- //
- // NOTE: Native Histograms are still an experimental feature. Their
- // behavior might still change without a major version
- // bump. Subsequently, all NativeHistogram... options here might still
- // change their behavior or name (or might completely disappear) without
- // a major version bump.
- NativeHistogramBucketFactor float64
- // All observations with an absolute value of less or equal
- // NativeHistogramZeroThreshold are accumulated into a “zero” bucket.
- // For best results, this should be close to a bucket boundary. This is
- // usually the case if picking a power of two. If
- // NativeHistogramZeroThreshold is left at zero,
- // DefNativeHistogramZeroThreshold is used as the threshold. To
- // configure a zero bucket with an actual threshold of zero (i.e. only
- // observations of precisely zero will go into the zero bucket), set
- // NativeHistogramZeroThreshold to the NativeHistogramZeroThresholdZero
- // constant (or any negative float value).
- NativeHistogramZeroThreshold float64
-
- // The next three fields define a strategy to limit the number of
- // populated sparse buckets. If NativeHistogramMaxBucketNumber is left
- // at zero, the number of buckets is not limited. (Note that this might
- // lead to unbounded memory consumption if the values observed by the
- // Histogram are sufficiently wide-spread. In particular, this could be
- // used as a DoS attack vector. Where the observed values depend on
- // external inputs, it is highly recommended to set a
- // NativeHistogramMaxBucketNumber.) Once the set
- // NativeHistogramMaxBucketNumber is exceeded, the following strategy is
- // enacted:
- // - First, if the last reset (or the creation) of the histogram is at
- // least NativeHistogramMinResetDuration ago, then the whole
- // histogram is reset to its initial state (including regular
- // buckets).
- // - If less time has passed, or if NativeHistogramMinResetDuration is
- // zero, no reset is performed. Instead, the zero threshold is
- // increased sufficiently to reduce the number of buckets to or below
- // NativeHistogramMaxBucketNumber, but not to more than
- // NativeHistogramMaxZeroThreshold. Thus, if
- // NativeHistogramMaxZeroThreshold is already at or below the current
- // zero threshold, nothing happens at this step.
- // - After that, if the number of buckets still exceeds
- // NativeHistogramMaxBucketNumber, the resolution of the histogram is
- // reduced by doubling the width of the sparse buckets (up to a
- // growth factor between one bucket to the next of 2^(2^4) = 65536,
- // see above).
- // - Any increased zero threshold or reduced resolution is reset back
- // to their original values once NativeHistogramMinResetDuration has
- // passed (since the last reset or the creation of the histogram).
- NativeHistogramMaxBucketNumber uint32
- NativeHistogramMinResetDuration time.Duration
- NativeHistogramMaxZeroThreshold float64
-
- // NativeHistogramMaxExemplars limits the number of exemplars
- // that are kept in memory for each native histogram. If you leave it at
- // zero, a default value of 10 is used. If no exemplars should be kept specifically
- // for native histograms, set it to a negative value. (Scrapers can
- // still use the exemplars exposed for classic buckets, which are managed
- // independently.)
- NativeHistogramMaxExemplars int
- // NativeHistogramExemplarTTL is only checked once
- // NativeHistogramMaxExemplars is exceeded. In that case, the
- // oldest exemplar is removed if it is older than NativeHistogramExemplarTTL.
- // Otherwise, the older exemplar in the pair of exemplars that are closest
- // together (on an exponential scale) is removed.
- // If NativeHistogramExemplarTTL is left at its zero value, a default value of
- // 5m is used. To always delete the oldest exemplar, set it to a negative value.
- NativeHistogramExemplarTTL time.Duration
-
- // now is for testing purposes, by default it's time.Now.
- now func() time.Time
-
- // afterFunc is for testing purposes, by default it's time.AfterFunc.
- afterFunc func(time.Duration, func()) *time.Timer
-}
-
-// HistogramVecOpts bundles the options to create a HistogramVec metric.
-// It is mandatory to set HistogramOpts, see there for mandatory fields. VariableLabels
-// is optional and can safely be left to its default value.
-type HistogramVecOpts struct {
- HistogramOpts
-
- // VariableLabels are used to partition the metric vector by the given set
- // of labels. Each label value will be constrained with the optional Constraint
- // function, if provided.
- VariableLabels ConstrainableLabels
-}
-
-// NewHistogram creates a new Histogram based on the provided HistogramOpts. It
-// panics if the buckets in HistogramOpts are not in strictly increasing order.
-//
-// The returned implementation also implements ExemplarObserver. It is safe to
-// perform the corresponding type assertion. Exemplars are tracked separately
-// for each bucket.
-func NewHistogram(opts HistogramOpts) Histogram {
- return newHistogram(
- NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- nil,
- opts.ConstLabels,
- ),
- opts,
- )
-}
-
-func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogram {
- if len(desc.variableLabels.names) != len(labelValues) {
- panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues))
- }
-
- for _, n := range desc.variableLabels.names {
- if n == bucketLabel {
- panic(errBucketLabelNotAllowed)
- }
- }
- for _, lp := range desc.constLabelPairs {
- if lp.GetName() == bucketLabel {
- panic(errBucketLabelNotAllowed)
- }
- }
-
- if opts.now == nil {
- opts.now = time.Now
- }
- if opts.afterFunc == nil {
- opts.afterFunc = time.AfterFunc
- }
-
- h := &histogram{
- desc: desc,
- upperBounds: opts.Buckets,
- labelPairs: MakeLabelPairs(desc, labelValues),
- nativeHistogramMaxBuckets: opts.NativeHistogramMaxBucketNumber,
- nativeHistogramMaxZeroThreshold: opts.NativeHistogramMaxZeroThreshold,
- nativeHistogramMinResetDuration: opts.NativeHistogramMinResetDuration,
- lastResetTime: opts.now(),
- now: opts.now,
- afterFunc: opts.afterFunc,
- }
- if len(h.upperBounds) == 0 && opts.NativeHistogramBucketFactor <= 1 {
- h.upperBounds = DefBuckets
- }
- if opts.NativeHistogramBucketFactor <= 1 {
- h.nativeHistogramSchema = math.MinInt32 // To mark that there are no sparse buckets.
- } else {
- switch {
- case opts.NativeHistogramZeroThreshold > 0:
- h.nativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold
- case opts.NativeHistogramZeroThreshold == 0:
- h.nativeHistogramZeroThreshold = DefNativeHistogramZeroThreshold
- } // Leave h.nativeHistogramZeroThreshold at 0 otherwise.
- h.nativeHistogramSchema = pickSchema(opts.NativeHistogramBucketFactor)
- h.nativeExemplars = makeNativeExemplars(opts.NativeHistogramExemplarTTL, opts.NativeHistogramMaxExemplars)
- }
- for i, upperBound := range h.upperBounds {
- if i < len(h.upperBounds)-1 {
- if upperBound >= h.upperBounds[i+1] {
- panic(fmt.Errorf(
- "histogram buckets must be in increasing order: %f >= %f",
- upperBound, h.upperBounds[i+1],
- ))
- }
- } else {
- if math.IsInf(upperBound, +1) {
- // The +Inf bucket is implicit. Remove it here.
- h.upperBounds = h.upperBounds[:i]
- }
- }
- }
- // Finally we know the final length of h.upperBounds and can make buckets
- // for both counts as well as exemplars:
- h.counts[0] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))}
- atomic.StoreUint64(&h.counts[0].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold))
- atomic.StoreInt32(&h.counts[0].nativeHistogramSchema, h.nativeHistogramSchema)
- h.counts[1] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))}
- atomic.StoreUint64(&h.counts[1].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold))
- atomic.StoreInt32(&h.counts[1].nativeHistogramSchema, h.nativeHistogramSchema)
- h.exemplars = make([]atomic.Value, len(h.upperBounds)+1)
-
- h.init(h) // Init self-collection.
- return h
-}
-
-type histogramCounts struct {
- // Order in this struct matters for the alignment required by atomic
- // operations, see http://golang.org/pkg/sync/atomic/#pkg-note-BUG
-
- // sumBits contains the bits of the float64 representing the sum of all
- // observations.
- sumBits uint64
- count uint64
-
- // nativeHistogramZeroBucket counts all (positive and negative)
- // observations in the zero bucket (with an absolute value less or equal
- // the current threshold, see next field.
- nativeHistogramZeroBucket uint64
- // nativeHistogramZeroThresholdBits is the bit pattern of the current
- // threshold for the zero bucket. It's initially equal to
- // nativeHistogramZeroThreshold but may change according to the bucket
- // count limitation strategy.
- nativeHistogramZeroThresholdBits uint64
- // nativeHistogramSchema may change over time according to the bucket
- // count limitation strategy and therefore has to be saved here.
- nativeHistogramSchema int32
- // Number of (positive and negative) sparse buckets.
- nativeHistogramBucketsNumber uint32
-
- // Regular buckets.
- buckets []uint64
-
- // The sparse buckets for native histograms are implemented with a
- // sync.Map for now. A dedicated data structure will likely be more
- // efficient. There are separate maps for negative and positive
- // observations. The map's value is an *int64, counting observations in
- // that bucket. (Note that we don't use uint64 as an int64 won't
- // overflow in practice, and working with signed numbers from the
- // beginning simplifies the handling of deltas.) The map's key is the
- // index of the bucket according to the used
- // nativeHistogramSchema. Index 0 is for an upper bound of 1.
- nativeHistogramBucketsPositive, nativeHistogramBucketsNegative sync.Map
-}
-
-// observe manages the parts of observe that only affects
-// histogramCounts. doSparse is true if sparse buckets should be done,
-// too.
-func (hc *histogramCounts) observe(v float64, bucket int, doSparse bool) {
- if bucket < len(hc.buckets) {
- atomic.AddUint64(&hc.buckets[bucket], 1)
- }
- atomicAddFloat(&hc.sumBits, v)
- if doSparse && !math.IsNaN(v) {
- var (
- key int
- schema = atomic.LoadInt32(&hc.nativeHistogramSchema)
- zeroThreshold = math.Float64frombits(atomic.LoadUint64(&hc.nativeHistogramZeroThresholdBits))
- bucketCreated, isInf bool
- )
- if math.IsInf(v, 0) {
- // Pretend v is MaxFloat64 but later increment key by one.
- if math.IsInf(v, +1) {
- v = math.MaxFloat64
- } else {
- v = -math.MaxFloat64
- }
- isInf = true
- }
- frac, exp := math.Frexp(math.Abs(v))
- if schema > 0 {
- bounds := nativeHistogramBounds[schema]
- key = sort.SearchFloat64s(bounds, frac) + (exp-1)*len(bounds)
- } else {
- key = exp
- if frac == 0.5 {
- key--
- }
- offset := (1 << -schema) - 1
- key = (key + offset) >> -schema
- }
- if isInf {
- key++
- }
- switch {
- case v > zeroThreshold:
- bucketCreated = addToBucket(&hc.nativeHistogramBucketsPositive, key, 1)
- case v < -zeroThreshold:
- bucketCreated = addToBucket(&hc.nativeHistogramBucketsNegative, key, 1)
- default:
- atomic.AddUint64(&hc.nativeHistogramZeroBucket, 1)
- }
- if bucketCreated {
- atomic.AddUint32(&hc.nativeHistogramBucketsNumber, 1)
- }
- }
- // Increment count last as we take it as a signal that the observation
- // is complete.
- atomic.AddUint64(&hc.count, 1)
-}
-
-type histogram struct {
- // countAndHotIdx enables lock-free writes with use of atomic updates.
- // The most significant bit is the hot index [0 or 1] of the count field
- // below. Observe calls update the hot one. All remaining bits count the
- // number of Observe calls. Observe starts by incrementing this counter,
- // and finish by incrementing the count field in the respective
- // histogramCounts, as a marker for completion.
- //
- // Calls of the Write method (which are non-mutating reads from the
- // perspective of the histogram) swap the hot–cold under the writeMtx
- // lock. A cooldown is awaited (while locked) by comparing the number of
- // observations with the initiation count. Once they match, then the
- // last observation on the now cool one has completed. All cold fields must
- // be merged into the new hot before releasing writeMtx.
- //
- // Fields with atomic access first! See alignment constraint:
- // http://golang.org/pkg/sync/atomic/#pkg-note-BUG
- countAndHotIdx uint64
-
- selfCollector
- desc *Desc
-
- // Only used in the Write method and for sparse bucket management.
- mtx sync.Mutex
-
- // Two counts, one is "hot" for lock-free observations, the other is
- // "cold" for writing out a dto.Metric. It has to be an array of
- // pointers to guarantee 64bit alignment of the histogramCounts, see
- // http://golang.org/pkg/sync/atomic/#pkg-note-BUG.
- counts [2]*histogramCounts
-
- upperBounds []float64
- labelPairs []*dto.LabelPair
- exemplars []atomic.Value // One more than buckets (to include +Inf), each a *dto.Exemplar.
- nativeHistogramSchema int32 // The initial schema. Set to math.MinInt32 if no sparse buckets are used.
- nativeHistogramZeroThreshold float64 // The initial zero threshold.
- nativeHistogramMaxZeroThreshold float64
- nativeHistogramMaxBuckets uint32
- nativeHistogramMinResetDuration time.Duration
- // lastResetTime is protected by mtx. It is also used as created timestamp.
- lastResetTime time.Time
- // resetScheduled is protected by mtx. It is true if a reset is
- // scheduled for a later time (when nativeHistogramMinResetDuration has
- // passed).
- resetScheduled bool
- nativeExemplars nativeExemplars
-
- // now is for testing purposes, by default it's time.Now.
- now func() time.Time
-
- // afterFunc is for testing purposes, by default it's time.AfterFunc.
- afterFunc func(time.Duration, func()) *time.Timer
-}
-
-func (h *histogram) Desc() *Desc {
- return h.desc
-}
-
-func (h *histogram) Observe(v float64) {
- h.observe(v, h.findBucket(v))
-}
-
-// ObserveWithExemplar should not be called in a high-frequency setting
-// for a native histogram with configured exemplars. For this case,
-// the implementation isn't lock-free and might suffer from lock contention.
-func (h *histogram) ObserveWithExemplar(v float64, e Labels) {
- i := h.findBucket(v)
- h.observe(v, i)
- h.updateExemplar(v, i, e)
-}
-
-func (h *histogram) Write(out *dto.Metric) error {
- // For simplicity, we protect this whole method by a mutex. It is not in
- // the hot path, i.e. Observe is called much more often than Write. The
- // complication of making Write lock-free isn't worth it, if possible at
- // all.
- h.mtx.Lock()
- defer h.mtx.Unlock()
-
- // Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0)
- // without touching the count bits. See the struct comments for a full
- // description of the algorithm.
- n := atomic.AddUint64(&h.countAndHotIdx, 1<<63)
- // count is contained unchanged in the lower 63 bits.
- count := n & ((1 << 63) - 1)
- // The most significant bit tells us which counts is hot. The complement
- // is thus the cold one.
- hotCounts := h.counts[n>>63]
- coldCounts := h.counts[(^n)>>63]
-
- waitForCooldown(count, coldCounts)
-
- his := &dto.Histogram{
- Bucket: make([]*dto.Bucket, len(h.upperBounds)),
- SampleCount: proto.Uint64(count),
- SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
- CreatedTimestamp: timestamppb.New(h.lastResetTime),
- }
- out.Histogram = his
- out.Label = h.labelPairs
-
- var cumCount uint64
- for i, upperBound := range h.upperBounds {
- cumCount += atomic.LoadUint64(&coldCounts.buckets[i])
- his.Bucket[i] = &dto.Bucket{
- CumulativeCount: proto.Uint64(cumCount),
- UpperBound: proto.Float64(upperBound),
- }
- if e := h.exemplars[i].Load(); e != nil {
- his.Bucket[i].Exemplar = e.(*dto.Exemplar)
- }
- }
- // If there is an exemplar for the +Inf bucket, we have to add that bucket explicitly.
- if e := h.exemplars[len(h.upperBounds)].Load(); e != nil {
- b := &dto.Bucket{
- CumulativeCount: proto.Uint64(count),
- UpperBound: proto.Float64(math.Inf(1)),
- Exemplar: e.(*dto.Exemplar),
- }
- his.Bucket = append(his.Bucket, b)
- }
- if h.nativeHistogramSchema > math.MinInt32 {
- his.ZeroThreshold = proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.nativeHistogramZeroThresholdBits)))
- his.Schema = proto.Int32(atomic.LoadInt32(&coldCounts.nativeHistogramSchema))
- zeroBucket := atomic.LoadUint64(&coldCounts.nativeHistogramZeroBucket)
-
- defer func() {
- coldCounts.nativeHistogramBucketsPositive.Range(addAndReset(&hotCounts.nativeHistogramBucketsPositive, &hotCounts.nativeHistogramBucketsNumber))
- coldCounts.nativeHistogramBucketsNegative.Range(addAndReset(&hotCounts.nativeHistogramBucketsNegative, &hotCounts.nativeHistogramBucketsNumber))
- }()
-
- his.ZeroCount = proto.Uint64(zeroBucket)
- his.NegativeSpan, his.NegativeDelta = makeBuckets(&coldCounts.nativeHistogramBucketsNegative)
- his.PositiveSpan, his.PositiveDelta = makeBuckets(&coldCounts.nativeHistogramBucketsPositive)
-
- // Add a no-op span to a histogram without observations and with
- // a zero threshold of zero. Otherwise, a native histogram would
- // look like a classic histogram to scrapers.
- if *his.ZeroThreshold == 0 && *his.ZeroCount == 0 && len(his.PositiveSpan) == 0 && len(his.NegativeSpan) == 0 {
- his.PositiveSpan = []*dto.BucketSpan{{
- Offset: proto.Int32(0),
- Length: proto.Uint32(0),
- }}
- }
-
- if h.nativeExemplars.isEnabled() {
- h.nativeExemplars.Lock()
- his.Exemplars = append(his.Exemplars, h.nativeExemplars.exemplars...)
- h.nativeExemplars.Unlock()
- }
-
- }
- addAndResetCounts(hotCounts, coldCounts)
- return nil
-}
-
-// findBucket returns the index of the bucket for the provided value, or
-// len(h.upperBounds) for the +Inf bucket.
-func (h *histogram) findBucket(v float64) int {
- // TODO(beorn7): For small numbers of buckets (<30), a linear search is
- // slightly faster than the binary search. If we really care, we could
- // switch from one search strategy to the other depending on the number
- // of buckets.
- //
- // Microbenchmarks (BenchmarkHistogramNoLabels):
- // 11 buckets: 38.3 ns/op linear - binary 48.7 ns/op
- // 100 buckets: 78.1 ns/op linear - binary 54.9 ns/op
- // 300 buckets: 154 ns/op linear - binary 61.6 ns/op
- return sort.SearchFloat64s(h.upperBounds, v)
-}
-
-// observe is the implementation for Observe without the findBucket part.
-func (h *histogram) observe(v float64, bucket int) {
- // Do not add to sparse buckets for NaN observations.
- doSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v)
- // We increment h.countAndHotIdx so that the counter in the lower
- // 63 bits gets incremented. At the same time, we get the new value
- // back, which we can use to find the currently-hot counts.
- n := atomic.AddUint64(&h.countAndHotIdx, 1)
- hotCounts := h.counts[n>>63]
- hotCounts.observe(v, bucket, doSparse)
- if doSparse {
- h.limitBuckets(hotCounts, v, bucket)
- }
-}
-
-// limitBuckets applies a strategy to limit the number of populated sparse
-// buckets. It's generally best effort, and there are situations where the
-// number can go higher (if even the lowest resolution isn't enough to reduce
-// the number sufficiently, or if the provided counts aren't fully updated yet
-// by a concurrently happening Write call).
-func (h *histogram) limitBuckets(counts *histogramCounts, value float64, bucket int) {
- if h.nativeHistogramMaxBuckets == 0 {
- return // No limit configured.
- }
- if h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&counts.nativeHistogramBucketsNumber) {
- return // Bucket limit not exceeded yet.
- }
-
- h.mtx.Lock()
- defer h.mtx.Unlock()
-
- // The hot counts might have been swapped just before we acquired the
- // lock. Re-fetch the hot counts first...
- n := atomic.LoadUint64(&h.countAndHotIdx)
- hotIdx := n >> 63
- coldIdx := (^n) >> 63
- hotCounts := h.counts[hotIdx]
- coldCounts := h.counts[coldIdx]
- // ...and then check again if we really have to reduce the bucket count.
- if h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&hotCounts.nativeHistogramBucketsNumber) {
- return // Bucket limit not exceeded after all.
- }
- // Try the various strategies in order.
- if h.maybeReset(hotCounts, coldCounts, coldIdx, value, bucket) {
- return
- }
- // One of the other strategies will happen. To undo what they will do as
- // soon as enough time has passed to satisfy
- // h.nativeHistogramMinResetDuration, schedule a reset at the right time
- // if we haven't done so already.
- if h.nativeHistogramMinResetDuration > 0 && !h.resetScheduled {
- h.resetScheduled = true
- h.afterFunc(h.nativeHistogramMinResetDuration-h.now().Sub(h.lastResetTime), h.reset)
- }
-
- if h.maybeWidenZeroBucket(hotCounts, coldCounts) {
- return
- }
- h.doubleBucketWidth(hotCounts, coldCounts)
-}
-
-// maybeReset resets the whole histogram if at least
-// h.nativeHistogramMinResetDuration has been passed. It returns true if the
-// histogram has been reset. The caller must have locked h.mtx.
-func (h *histogram) maybeReset(
- hot, cold *histogramCounts, coldIdx uint64, value float64, bucket int,
-) bool {
- // We are using the possibly mocked h.now() rather than
- // time.Since(h.lastResetTime) to enable testing.
- if h.nativeHistogramMinResetDuration == 0 || // No reset configured.
- h.resetScheduled || // Do not interefere if a reset is already scheduled.
- h.now().Sub(h.lastResetTime) < h.nativeHistogramMinResetDuration {
- return false
- }
- // Completely reset coldCounts.
- h.resetCounts(cold)
- // Repeat the latest observation to not lose it completely.
- cold.observe(value, bucket, true)
- // Make coldCounts the new hot counts while resetting countAndHotIdx.
- n := atomic.SwapUint64(&h.countAndHotIdx, (coldIdx<<63)+1)
- count := n & ((1 << 63) - 1)
- waitForCooldown(count, hot)
- // Finally, reset the formerly hot counts, too.
- h.resetCounts(hot)
- h.lastResetTime = h.now()
- return true
-}
-
-// reset resets the whole histogram. It locks h.mtx itself, i.e. it has to be
-// called without having locked h.mtx.
-func (h *histogram) reset() {
- h.mtx.Lock()
- defer h.mtx.Unlock()
-
- n := atomic.LoadUint64(&h.countAndHotIdx)
- hotIdx := n >> 63
- coldIdx := (^n) >> 63
- hot := h.counts[hotIdx]
- cold := h.counts[coldIdx]
- // Completely reset coldCounts.
- h.resetCounts(cold)
- // Make coldCounts the new hot counts while resetting countAndHotIdx.
- n = atomic.SwapUint64(&h.countAndHotIdx, coldIdx<<63)
- count := n & ((1 << 63) - 1)
- waitForCooldown(count, hot)
- // Finally, reset the formerly hot counts, too.
- h.resetCounts(hot)
- h.lastResetTime = h.now()
- h.resetScheduled = false
-}
-
-// maybeWidenZeroBucket widens the zero bucket until it includes the existing
-// buckets closest to the zero bucket (which could be two, if an equidistant
-// negative and a positive bucket exists, but usually it's only one bucket to be
-// merged into the new wider zero bucket). h.nativeHistogramMaxZeroThreshold
-// limits how far the zero bucket can be extended, and if that's not enough to
-// include an existing bucket, the method returns false. The caller must have
-// locked h.mtx.
-func (h *histogram) maybeWidenZeroBucket(hot, cold *histogramCounts) bool {
- currentZeroThreshold := math.Float64frombits(atomic.LoadUint64(&hot.nativeHistogramZeroThresholdBits))
- if currentZeroThreshold >= h.nativeHistogramMaxZeroThreshold {
- return false
- }
- // Find the key of the bucket closest to zero.
- smallestKey := findSmallestKey(&hot.nativeHistogramBucketsPositive)
- smallestNegativeKey := findSmallestKey(&hot.nativeHistogramBucketsNegative)
- if smallestNegativeKey < smallestKey {
- smallestKey = smallestNegativeKey
- }
- if smallestKey == math.MaxInt32 {
- return false
- }
- newZeroThreshold := getLe(smallestKey, atomic.LoadInt32(&hot.nativeHistogramSchema))
- if newZeroThreshold > h.nativeHistogramMaxZeroThreshold {
- return false // New threshold would exceed the max threshold.
- }
- atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold))
- // Remove applicable buckets.
- if _, loaded := cold.nativeHistogramBucketsNegative.LoadAndDelete(smallestKey); loaded {
- atomicDecUint32(&cold.nativeHistogramBucketsNumber)
- }
- if _, loaded := cold.nativeHistogramBucketsPositive.LoadAndDelete(smallestKey); loaded {
- atomicDecUint32(&cold.nativeHistogramBucketsNumber)
- }
- // Make cold counts the new hot counts.
- n := atomic.AddUint64(&h.countAndHotIdx, 1<<63)
- count := n & ((1 << 63) - 1)
- // Swap the pointer names to represent the new roles and make
- // the rest less confusing.
- hot, cold = cold, hot
- waitForCooldown(count, cold)
- // Add all the now cold counts to the new hot counts...
- addAndResetCounts(hot, cold)
- // ...adjust the new zero threshold in the cold counts, too...
- atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold))
- // ...and then merge the newly deleted buckets into the wider zero
- // bucket.
- mergeAndDeleteOrAddAndReset := func(hotBuckets, coldBuckets *sync.Map) func(k, v interface{}) bool {
- return func(k, v interface{}) bool {
- key := k.(int)
- bucket := v.(*int64)
- if key == smallestKey {
- // Merge into hot zero bucket...
- atomic.AddUint64(&hot.nativeHistogramZeroBucket, uint64(atomic.LoadInt64(bucket)))
- // ...and delete from cold counts.
- coldBuckets.Delete(key)
- atomicDecUint32(&cold.nativeHistogramBucketsNumber)
- } else {
- // Add to corresponding hot bucket...
- if addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) {
- atomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1)
- }
- // ...and reset cold bucket.
- atomic.StoreInt64(bucket, 0)
- }
- return true
- }
- }
-
- cold.nativeHistogramBucketsPositive.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsPositive, &cold.nativeHistogramBucketsPositive))
- cold.nativeHistogramBucketsNegative.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsNegative, &cold.nativeHistogramBucketsNegative))
- return true
-}
-
-// doubleBucketWidth doubles the bucket width (by decrementing the schema
-// number). Note that very sparse buckets could lead to a low reduction of the
-// bucket count (or even no reduction at all). The method does nothing if the
-// schema is already -4.
-func (h *histogram) doubleBucketWidth(hot, cold *histogramCounts) {
- coldSchema := atomic.LoadInt32(&cold.nativeHistogramSchema)
- if coldSchema == -4 {
- return // Already at lowest resolution.
- }
- coldSchema--
- atomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema)
- // Play it simple and just delete all cold buckets.
- atomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0)
- deleteSyncMap(&cold.nativeHistogramBucketsNegative)
- deleteSyncMap(&cold.nativeHistogramBucketsPositive)
- // Make coldCounts the new hot counts.
- n := atomic.AddUint64(&h.countAndHotIdx, 1<<63)
- count := n & ((1 << 63) - 1)
- // Swap the pointer names to represent the new roles and make
- // the rest less confusing.
- hot, cold = cold, hot
- waitForCooldown(count, cold)
- // Add all the now cold counts to the new hot counts...
- addAndResetCounts(hot, cold)
- // ...adjust the schema in the cold counts, too...
- atomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema)
- // ...and then merge the cold buckets into the wider hot buckets.
- merge := func(hotBuckets *sync.Map) func(k, v interface{}) bool {
- return func(k, v interface{}) bool {
- key := k.(int)
- bucket := v.(*int64)
- // Adjust key to match the bucket to merge into.
- if key > 0 {
- key++
- }
- key /= 2
- // Add to corresponding hot bucket.
- if addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) {
- atomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1)
- }
- return true
- }
- }
-
- cold.nativeHistogramBucketsPositive.Range(merge(&hot.nativeHistogramBucketsPositive))
- cold.nativeHistogramBucketsNegative.Range(merge(&hot.nativeHistogramBucketsNegative))
- // Play it simple again and just delete all cold buckets.
- atomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0)
- deleteSyncMap(&cold.nativeHistogramBucketsNegative)
- deleteSyncMap(&cold.nativeHistogramBucketsPositive)
-}
-
-func (h *histogram) resetCounts(counts *histogramCounts) {
- atomic.StoreUint64(&counts.sumBits, 0)
- atomic.StoreUint64(&counts.count, 0)
- atomic.StoreUint64(&counts.nativeHistogramZeroBucket, 0)
- atomic.StoreUint64(&counts.nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold))
- atomic.StoreInt32(&counts.nativeHistogramSchema, h.nativeHistogramSchema)
- atomic.StoreUint32(&counts.nativeHistogramBucketsNumber, 0)
- for i := range h.upperBounds {
- atomic.StoreUint64(&counts.buckets[i], 0)
- }
- deleteSyncMap(&counts.nativeHistogramBucketsNegative)
- deleteSyncMap(&counts.nativeHistogramBucketsPositive)
-}
-
-// updateExemplar replaces the exemplar for the provided classic bucket.
-// With empty labels, it's a no-op. It panics if any of the labels is invalid.
-// If histogram is native, the exemplar will be cached into nativeExemplars,
-// which has a limit, and will remove one exemplar when limit is reached.
-func (h *histogram) updateExemplar(v float64, bucket int, l Labels) {
- if l == nil {
- return
- }
- e, err := newExemplar(v, h.now(), l)
- if err != nil {
- panic(err)
- }
- h.exemplars[bucket].Store(e)
- doSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v)
- if doSparse {
- h.nativeExemplars.addExemplar(e)
- }
-}
-
-// HistogramVec is a Collector that bundles a set of Histograms that all share the
-// same Desc, but have different values for their variable labels. This is used
-// if you want to count the same thing partitioned by various dimensions
-// (e.g. HTTP request latencies, partitioned by status code and method). Create
-// instances with NewHistogramVec.
-type HistogramVec struct {
- *MetricVec
-}
-
-// NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and
-// partitioned by the given label names.
-func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
- return V2.NewHistogramVec(HistogramVecOpts{
- HistogramOpts: opts,
- VariableLabels: UnconstrainedLabels(labelNames),
- })
-}
-
-// NewHistogramVec creates a new HistogramVec based on the provided HistogramVecOpts.
-func (v2) NewHistogramVec(opts HistogramVecOpts) *HistogramVec {
- desc := V2.NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- opts.VariableLabels,
- opts.ConstLabels,
- )
- return &HistogramVec{
- MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
- return newHistogram(desc, opts.HistogramOpts, lvs...)
- }),
- }
-}
-
-// GetMetricWithLabelValues returns the Histogram for the given slice of label
-// values (same order as the variable labels in Desc). If that combination of
-// label values is accessed for the first time, a new Histogram is created.
-//
-// It is possible to call this method without using the returned Histogram to only
-// create the new Histogram but leave it at its starting value, a Histogram without
-// any observations.
-//
-// Keeping the Histogram for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Histogram from the HistogramVec. In that case, the
-// Histogram will still exist, but it will not be exported anymore, even if a
-// Histogram with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of variable labels in Desc (minus any curried labels).
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
-func (v *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
- metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)
- if metric != nil {
- return metric.(Observer), err
- }
- return nil, err
-}
-
-// GetMetricWith returns the Histogram for the given Labels map (the label names
-// must match those of the variable labels in Desc). If that label map is
-// accessed for the first time, a new Histogram is created. Implications of
-// creating a Histogram without using it and keeping the Histogram for later use
-// are the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the variable labels in Desc (minus any curried labels).
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (v *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {
- metric, err := v.MetricVec.GetMetricWith(labels)
- if metric != nil {
- return metric.(Observer), err
- }
- return nil, err
-}
-
-// WithLabelValues works as GetMetricWithLabelValues, but panics where
-// GetMetricWithLabelValues would have returned an error. Not returning an
-// error allows shortcuts like
-//
-// myVec.WithLabelValues("404", "GET").Observe(42.21)
-func (v *HistogramVec) WithLabelValues(lvs ...string) Observer {
- h, err := v.GetMetricWithLabelValues(lvs...)
- if err != nil {
- panic(err)
- }
- return h
-}
-
-// With works as GetMetricWith but panics where GetMetricWithLabels would have
-// returned an error. Not returning an error allows shortcuts like
-//
-// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21)
-func (v *HistogramVec) With(labels Labels) Observer {
- h, err := v.GetMetricWith(labels)
- if err != nil {
- panic(err)
- }
- return h
-}
-
-// CurryWith returns a vector curried with the provided labels, i.e. the
-// returned vector has those labels pre-set for all labeled operations performed
-// on it. The cardinality of the curried vector is reduced accordingly. The
-// order of the remaining labels stays the same (just with the curried labels
-// taken out of the sequence – which is relevant for the
-// (GetMetric)WithLabelValues methods). It is possible to curry a curried
-// vector, but only with labels not yet used for currying before.
-//
-// The metrics contained in the HistogramVec are shared between the curried and
-// uncurried vectors. They are just accessed differently. Curried and uncurried
-// vectors behave identically in terms of collection. Only one must be
-// registered with a given registry (usually the uncurried version). The Reset
-// method deletes all metrics, even if called on a curried vector.
-func (v *HistogramVec) CurryWith(labels Labels) (ObserverVec, error) {
- vec, err := v.MetricVec.CurryWith(labels)
- if vec != nil {
- return &HistogramVec{vec}, err
- }
- return nil, err
-}
-
-// MustCurryWith works as CurryWith but panics where CurryWith would have
-// returned an error.
-func (v *HistogramVec) MustCurryWith(labels Labels) ObserverVec {
- vec, err := v.CurryWith(labels)
- if err != nil {
- panic(err)
- }
- return vec
-}
-
-type constHistogram struct {
- desc *Desc
- count uint64
- sum float64
- buckets map[float64]uint64
- labelPairs []*dto.LabelPair
- createdTs *timestamppb.Timestamp
-}
-
-func (h *constHistogram) Desc() *Desc {
- return h.desc
-}
-
-func (h *constHistogram) Write(out *dto.Metric) error {
- his := &dto.Histogram{
- CreatedTimestamp: h.createdTs,
- }
-
- buckets := make([]*dto.Bucket, 0, len(h.buckets))
-
- his.SampleCount = proto.Uint64(h.count)
- his.SampleSum = proto.Float64(h.sum)
- for upperBound, count := range h.buckets {
- buckets = append(buckets, &dto.Bucket{
- CumulativeCount: proto.Uint64(count),
- UpperBound: proto.Float64(upperBound),
- })
- }
-
- if len(buckets) > 0 {
- sort.Sort(buckSort(buckets))
- }
- his.Bucket = buckets
-
- out.Histogram = his
- out.Label = h.labelPairs
-
- return nil
-}
-
-// NewConstHistogram returns a metric representing a Prometheus histogram with
-// fixed values for the count, sum, and bucket counts. As those parameters
-// cannot be changed, the returned value does not implement the Histogram
-// interface (but only the Metric interface). Users of this package will not
-// have much use for it in regular operations. However, when implementing custom
-// Collectors, it is useful as a throw-away metric that is generated on the fly
-// to send it to Prometheus in the Collect method.
-//
-// buckets is a map of upper bounds to cumulative counts, excluding the +Inf
-// bucket. The +Inf bucket is implicit, and its value is equal to the provided count.
-//
-// NewConstHistogram returns an error if the length of labelValues is not
-// consistent with the variable labels in Desc or if Desc is invalid.
-func NewConstHistogram(
- desc *Desc,
- count uint64,
- sum float64,
- buckets map[float64]uint64,
- labelValues ...string,
-) (Metric, error) {
- if desc.err != nil {
- return nil, desc.err
- }
- if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
- return nil, err
- }
- return &constHistogram{
- desc: desc,
- count: count,
- sum: sum,
- buckets: buckets,
- labelPairs: MakeLabelPairs(desc, labelValues),
- }, nil
-}
-
-// MustNewConstHistogram is a version of NewConstHistogram that panics where
-// NewConstHistogram would have returned an error.
-func MustNewConstHistogram(
- desc *Desc,
- count uint64,
- sum float64,
- buckets map[float64]uint64,
- labelValues ...string,
-) Metric {
- m, err := NewConstHistogram(desc, count, sum, buckets, labelValues...)
- if err != nil {
- panic(err)
- }
- return m
-}
-
-// NewConstHistogramWithCreatedTimestamp does the same thing as NewConstHistogram but sets the created timestamp.
-func NewConstHistogramWithCreatedTimestamp(
- desc *Desc,
- count uint64,
- sum float64,
- buckets map[float64]uint64,
- ct time.Time,
- labelValues ...string,
-) (Metric, error) {
- if desc.err != nil {
- return nil, desc.err
- }
- if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
- return nil, err
- }
- return &constHistogram{
- desc: desc,
- count: count,
- sum: sum,
- buckets: buckets,
- labelPairs: MakeLabelPairs(desc, labelValues),
- createdTs: timestamppb.New(ct),
- }, nil
-}
-
-// MustNewConstHistogramWithCreatedTimestamp is a version of NewConstHistogramWithCreatedTimestamp that panics where
-// NewConstHistogramWithCreatedTimestamp would have returned an error.
-func MustNewConstHistogramWithCreatedTimestamp(
- desc *Desc,
- count uint64,
- sum float64,
- buckets map[float64]uint64,
- ct time.Time,
- labelValues ...string,
-) Metric {
- m, err := NewConstHistogramWithCreatedTimestamp(desc, count, sum, buckets, ct, labelValues...)
- if err != nil {
- panic(err)
- }
- return m
-}
-
-type buckSort []*dto.Bucket
-
-func (s buckSort) Len() int {
- return len(s)
-}
-
-func (s buckSort) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
-}
-
-func (s buckSort) Less(i, j int) bool {
- return s[i].GetUpperBound() < s[j].GetUpperBound()
-}
-
-// pickSchema returns the largest number n between -4 and 8 such that
-// 2^(2^-n) is less or equal the provided bucketFactor.
-//
-// Special cases:
-// - bucketFactor <= 1: panics.
-// - bucketFactor < 2^(2^-8) (but > 1): still returns 8.
-func pickSchema(bucketFactor float64) int32 {
- if bucketFactor <= 1 {
- panic(fmt.Errorf("bucketFactor %f is <=1", bucketFactor))
- }
- floor := math.Floor(math.Log2(math.Log2(bucketFactor)))
- switch {
- case floor <= -8:
- return 8
- case floor >= 4:
- return -4
- default:
- return -int32(floor)
- }
-}
-
-func makeBuckets(buckets *sync.Map) ([]*dto.BucketSpan, []int64) {
- var ii []int
- buckets.Range(func(k, v interface{}) bool {
- ii = append(ii, k.(int))
- return true
- })
- sort.Ints(ii)
-
- if len(ii) == 0 {
- return nil, nil
- }
-
- var (
- spans []*dto.BucketSpan
- deltas []int64
- prevCount int64
- nextI int
- )
-
- appendDelta := func(count int64) {
- *spans[len(spans)-1].Length++
- deltas = append(deltas, count-prevCount)
- prevCount = count
- }
-
- for n, i := range ii {
- v, _ := buckets.Load(i)
- count := atomic.LoadInt64(v.(*int64))
- // Multiple spans with only small gaps in between are probably
- // encoded more efficiently as one larger span with a few empty
- // buckets. Needs some research to find the sweet spot. For now,
- // we assume that gaps of one or two buckets should not create
- // a new span.
- iDelta := int32(i - nextI)
- if n == 0 || iDelta > 2 {
- // We have to create a new span, either because we are
- // at the very beginning, or because we have found a gap
- // of more than two buckets.
- spans = append(spans, &dto.BucketSpan{
- Offset: proto.Int32(iDelta),
- Length: proto.Uint32(0),
- })
- } else {
- // We have found a small gap (or no gap at all).
- // Insert empty buckets as needed.
- for j := int32(0); j < iDelta; j++ {
- appendDelta(0)
- }
- }
- appendDelta(count)
- nextI = i + 1
- }
- return spans, deltas
-}
-
-// addToBucket increments the sparse bucket at key by the provided amount. It
-// returns true if a new sparse bucket had to be created for that.
-func addToBucket(buckets *sync.Map, key int, increment int64) bool {
- if existingBucket, ok := buckets.Load(key); ok {
- // Fast path without allocation.
- atomic.AddInt64(existingBucket.(*int64), increment)
- return false
- }
- // Bucket doesn't exist yet. Slow path allocating new counter.
- newBucket := increment // TODO(beorn7): Check if this is sufficient to not let increment escape.
- if actualBucket, loaded := buckets.LoadOrStore(key, &newBucket); loaded {
- // The bucket was created concurrently in another goroutine.
- // Have to increment after all.
- atomic.AddInt64(actualBucket.(*int64), increment)
- return false
- }
- return true
-}
-
-// addAndReset returns a function to be used with sync.Map.Range of spare
-// buckets in coldCounts. It increments the buckets in the provided hotBuckets
-// according to the buckets ranged through. It then resets all buckets ranged
-// through to 0 (but leaves them in place so that they don't need to get
-// recreated on the next scrape).
-func addAndReset(hotBuckets *sync.Map, bucketNumber *uint32) func(k, v interface{}) bool {
- return func(k, v interface{}) bool {
- bucket := v.(*int64)
- if addToBucket(hotBuckets, k.(int), atomic.LoadInt64(bucket)) {
- atomic.AddUint32(bucketNumber, 1)
- }
- atomic.StoreInt64(bucket, 0)
- return true
- }
-}
-
-func deleteSyncMap(m *sync.Map) {
- m.Range(func(k, v interface{}) bool {
- m.Delete(k)
- return true
- })
-}
-
-func findSmallestKey(m *sync.Map) int {
- result := math.MaxInt32
- m.Range(func(k, v interface{}) bool {
- key := k.(int)
- if key < result {
- result = key
- }
- return true
- })
- return result
-}
-
-func getLe(key int, schema int32) float64 {
- // Here a bit of context about the behavior for the last bucket counting
- // regular numbers (called simply "last bucket" below) and the bucket
- // counting observations of ±Inf (called "inf bucket" below, with a key
- // one higher than that of the "last bucket"):
- //
- // If we apply the usual formula to the last bucket, its upper bound
- // would be calculated as +Inf. The reason is that the max possible
- // regular float64 number (math.MaxFloat64) doesn't coincide with one of
- // the calculated bucket boundaries. So the calculated boundary has to
- // be larger than math.MaxFloat64, and the only float64 larger than
- // math.MaxFloat64 is +Inf. However, we want to count actual
- // observations of ±Inf in the inf bucket. Therefore, we have to treat
- // the upper bound of the last bucket specially and set it to
- // math.MaxFloat64. (The upper bound of the inf bucket, with its key
- // being one higher than that of the last bucket, naturally comes out as
- // +Inf by the usual formula. So that's fine.)
- //
- // math.MaxFloat64 has a frac of 0.9999999999999999 and an exp of
- // 1024. If there were a float64 number following math.MaxFloat64, it
- // would have a frac of 1.0 and an exp of 1024, or equivalently a frac
- // of 0.5 and an exp of 1025. However, since frac must be smaller than
- // 1, and exp must be smaller than 1025, either representation overflows
- // a float64. (Which, in turn, is the reason that math.MaxFloat64 is the
- // largest possible float64. Q.E.D.) However, the formula for
- // calculating the upper bound from the idx and schema of the last
- // bucket results in precisely that. It is either frac=1.0 & exp=1024
- // (for schema < 0) or frac=0.5 & exp=1025 (for schema >=0). (This is,
- // by the way, a power of two where the exponent itself is a power of
- // two, 2¹⁰ in fact, which coinicides with a bucket boundary in all
- // schemas.) So these are the special cases we have to catch below.
- if schema < 0 {
- exp := key << -schema
- if exp == 1024 {
- // This is the last bucket before the overflow bucket
- // (for ±Inf observations). Return math.MaxFloat64 as
- // explained above.
- return math.MaxFloat64
- }
- return math.Ldexp(1, exp)
- }
-
- fracIdx := key & ((1 << schema) - 1)
- frac := nativeHistogramBounds[schema][fracIdx]
- exp := (key >> schema) + 1
- if frac == 0.5 && exp == 1025 {
- // This is the last bucket before the overflow bucket (for ±Inf
- // observations). Return math.MaxFloat64 as explained above.
- return math.MaxFloat64
- }
- return math.Ldexp(frac, exp)
-}
-
-// waitForCooldown returns after the count field in the provided histogramCounts
-// has reached the provided count value.
-func waitForCooldown(count uint64, counts *histogramCounts) {
- for count != atomic.LoadUint64(&counts.count) {
- runtime.Gosched() // Let observations get work done.
- }
-}
-
-// atomicAddFloat adds the provided float atomically to another float
-// represented by the bit pattern the bits pointer is pointing to.
-func atomicAddFloat(bits *uint64, v float64) {
- for {
- loadedBits := atomic.LoadUint64(bits)
- newBits := math.Float64bits(math.Float64frombits(loadedBits) + v)
- if atomic.CompareAndSwapUint64(bits, loadedBits, newBits) {
- break
- }
- }
-}
-
-// atomicDecUint32 atomically decrements the uint32 p points to. See
-// https://pkg.go.dev/sync/atomic#AddUint32 to understand how this is done.
-func atomicDecUint32(p *uint32) {
- atomic.AddUint32(p, ^uint32(0))
-}
-
-// addAndResetCounts adds certain fields (count, sum, conventional buckets, zero
-// bucket) from the cold counts to the corresponding fields in the hot
-// counts. Those fields are then reset to 0 in the cold counts.
-func addAndResetCounts(hot, cold *histogramCounts) {
- atomic.AddUint64(&hot.count, atomic.LoadUint64(&cold.count))
- atomic.StoreUint64(&cold.count, 0)
- coldSum := math.Float64frombits(atomic.LoadUint64(&cold.sumBits))
- atomicAddFloat(&hot.sumBits, coldSum)
- atomic.StoreUint64(&cold.sumBits, 0)
- for i := range hot.buckets {
- atomic.AddUint64(&hot.buckets[i], atomic.LoadUint64(&cold.buckets[i]))
- atomic.StoreUint64(&cold.buckets[i], 0)
- }
- atomic.AddUint64(&hot.nativeHistogramZeroBucket, atomic.LoadUint64(&cold.nativeHistogramZeroBucket))
- atomic.StoreUint64(&cold.nativeHistogramZeroBucket, 0)
-}
-
-type nativeExemplars struct {
- sync.Mutex
-
- // Time-to-live for exemplars, it is set to -1 if exemplars are disabled, that is NativeHistogramMaxExemplars is below 0.
- // The ttl is used on insertion to remove an exemplar that is older than ttl, if present.
- ttl time.Duration
-
- exemplars []*dto.Exemplar
-}
-
-func (n *nativeExemplars) isEnabled() bool {
- return n.ttl != -1
-}
-
-func makeNativeExemplars(ttl time.Duration, maxCount int) nativeExemplars {
- if ttl == 0 {
- ttl = 5 * time.Minute
- }
-
- if maxCount == 0 {
- maxCount = 10
- }
-
- if maxCount < 0 {
- maxCount = 0
- ttl = -1
- }
-
- return nativeExemplars{
- ttl: ttl,
- exemplars: make([]*dto.Exemplar, 0, maxCount),
- }
-}
-
-func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
- if !n.isEnabled() {
- return
- }
-
- n.Lock()
- defer n.Unlock()
-
- // When the number of exemplars has not yet exceeded or
- // is equal to cap(n.exemplars), then
- // insert the new exemplar directly.
- if len(n.exemplars) < cap(n.exemplars) {
- var nIdx int
- for nIdx = 0; nIdx < len(n.exemplars); nIdx++ {
- if *e.Value < *n.exemplars[nIdx].Value {
- break
- }
- }
- n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...)
- return
- }
-
- if len(n.exemplars) == 1 {
- // When the number of exemplars is 1, then
- // replace the existing exemplar with the new exemplar.
- n.exemplars[0] = e
- return
- }
- // From this point on, the number of exemplars is greater than 1.
-
- // When the number of exemplars exceeds the limit, remove one exemplar.
- var (
- ot = time.Time{} // Oldest timestamp seen. Initial value doesn't matter as we replace it due to otIdx == -1 in the loop.
- otIdx = -1 // Index of the exemplar with the oldest timestamp.
-
- md = -1.0 // Logarithm of the delta of the closest pair of exemplars.
-
- // The insertion point of the new exemplar in the exemplars slice after insertion.
- // This is calculated purely based on the order of the exemplars by value.
- // nIdx == len(n.exemplars) means the new exemplar is to be inserted after the end.
- nIdx = -1
-
- // rIdx is ultimately the index for the exemplar that we are replacing with the new exemplar.
- // The aim is to keep a good spread of exemplars by value and not let them bunch up too much.
- // It is calculated in 3 steps:
- // 1. First we set rIdx to the index of the older exemplar within the closest pair by value.
- // That is the following will be true (on log scale):
- // either the exemplar pair on index (rIdx-1, rIdx) or (rIdx, rIdx+1) will have
- // the closest values to each other from all pairs.
- // For example, suppose the values are distributed like this:
- // |-----------x-------------x----------------x----x-----|
- // ^--rIdx as this is older.
- // Or like this:
- // |-----------x-------------x----------------x----x-----|
- // ^--rIdx as this is older.
- // 2. If there is an exemplar that expired, then we simple reset rIdx to that index.
- // 3. We check if by inserting the new exemplar we would create a closer pair at
- // (nIdx-1, nIdx) or (nIdx, nIdx+1) and set rIdx to nIdx-1 or nIdx accordingly to
- // keep the spread of exemplars by value; otherwise we keep rIdx as it is.
- rIdx = -1
- cLog float64 // Logarithm of the current exemplar.
- pLog float64 // Logarithm of the previous exemplar.
- )
-
- for i, exemplar := range n.exemplars {
- // Find the exemplar with the oldest timestamp.
- if otIdx == -1 || exemplar.Timestamp.AsTime().Before(ot) {
- ot = exemplar.Timestamp.AsTime()
- otIdx = i
- }
-
- // Find the index at which to insert new the exemplar.
- if nIdx == -1 && *e.Value <= *exemplar.Value {
- nIdx = i
- }
-
- // Find the two closest exemplars and pick the one the with older timestamp.
- pLog = cLog
- cLog = math.Log(exemplar.GetValue())
- if i == 0 {
- continue
- }
- diff := math.Abs(cLog - pLog)
- if md == -1 || diff < md {
- // The closest exemplar pair is at index: i-1, i.
- // Choose the exemplar with the older timestamp for replacement.
- md = diff
- if n.exemplars[i].Timestamp.AsTime().Before(n.exemplars[i-1].Timestamp.AsTime()) {
- rIdx = i
- } else {
- rIdx = i - 1
- }
- }
-
- }
-
- // If all existing exemplar are smaller than new exemplar,
- // then the exemplar should be inserted at the end.
- if nIdx == -1 {
- nIdx = len(n.exemplars)
- }
- // Here, we have the following relationships:
- // n.exemplars[nIdx-1].Value < e.Value (if nIdx > 0)
- // e.Value <= n.exemplars[nIdx].Value (if nIdx < len(n.exemplars))
-
- if otIdx != -1 && e.Timestamp.AsTime().Sub(ot) > n.ttl {
- // If the oldest exemplar has expired, then replace it with the new exemplar.
- rIdx = otIdx
- } else {
- // In the previous for loop, when calculating the closest pair of exemplars,
- // we did not take into account the newly inserted exemplar.
- // So we need to calculate with the newly inserted exemplar again.
- elog := math.Log(e.GetValue())
- if nIdx > 0 {
- diff := math.Abs(elog - math.Log(n.exemplars[nIdx-1].GetValue()))
- if diff < md {
- // The value we are about to insert is closer to the previous exemplar at the insertion point than what we calculated before in rIdx.
- // v--rIdx
- // |-----------x-n-----------x----------------x----x-----|
- // nIdx-1--^ ^--new exemplar value
- // Do not make the spread worse, replace nIdx-1 and not rIdx.
- md = diff
- rIdx = nIdx - 1
- }
- }
- if nIdx < len(n.exemplars) {
- diff := math.Abs(math.Log(n.exemplars[nIdx].GetValue()) - elog)
- if diff < md {
- // The value we are about to insert is closer to the next exemplar at the insertion point than what we calculated before in rIdx.
- // v--rIdx
- // |-----------x-----------n-x----------------x----x-----|
- // new exemplar value--^ ^--nIdx
- // Do not make the spread worse, replace nIdx-1 and not rIdx.
- rIdx = nIdx
- }
- }
- }
-
- // Adjust the slice according to rIdx and nIdx.
- switch {
- case rIdx == nIdx:
- n.exemplars[nIdx] = e
- case rIdx < nIdx:
- n.exemplars = append(n.exemplars[:rIdx], append(n.exemplars[rIdx+1:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...)...)
- case rIdx > nIdx:
- n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, append(n.exemplars[nIdx:rIdx], n.exemplars[rIdx+1:]...)...)...)
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go
deleted file mode 100644
index 1ed5abe74..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2015 Björn Rabenstein
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-//
-// The code in this package is copy/paste to avoid a dependency. Hence this file
-// carries the copyright of the original repo.
-// https://github.com/beorn7/floats
-package internal
-
-import (
- "math"
-)
-
-// minNormalFloat64 is the smallest positive normal value of type float64.
-var minNormalFloat64 = math.Float64frombits(0x0010000000000000)
-
-// AlmostEqualFloat64 returns true if a and b are equal within a relative error
-// of epsilon. See http://floating-point-gui.de/errors/comparison/ for the
-// details of the applied method.
-func AlmostEqualFloat64(a, b, epsilon float64) bool {
- if a == b {
- return true
- }
- absA := math.Abs(a)
- absB := math.Abs(b)
- diff := math.Abs(a - b)
- if a == 0 || b == 0 || absA+absB < minNormalFloat64 {
- return diff < epsilon*minNormalFloat64
- }
- return diff/math.Min(absA+absB, math.MaxFloat64) < epsilon
-}
-
-// AlmostEqualFloat64s is the slice form of AlmostEqualFloat64.
-func AlmostEqualFloat64s(a, b []float64, epsilon float64) bool {
- if len(a) != len(b) {
- return false
- }
- for i := range a {
- if !AlmostEqualFloat64(a[i], b[i], epsilon) {
- return false
- }
- }
- return true
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go
deleted file mode 100644
index a595a2036..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go
+++ /dev/null
@@ -1,654 +0,0 @@
-// Copyright 2022 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// It provides tools to compare sequences of strings and generate textual diffs.
-//
-// Maintaining `GetUnifiedDiffString` here because original repository
-// (https://github.com/pmezard/go-difflib) is no longer maintained.
-package internal
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "strings"
-)
-
-func min(a, b int) int {
- if a < b {
- return a
- }
- return b
-}
-
-func max(a, b int) int {
- if a > b {
- return a
- }
- return b
-}
-
-func calculateRatio(matches, length int) float64 {
- if length > 0 {
- return 2.0 * float64(matches) / float64(length)
- }
- return 1.0
-}
-
-type Match struct {
- A int
- B int
- Size int
-}
-
-type OpCode struct {
- Tag byte
- I1 int
- I2 int
- J1 int
- J2 int
-}
-
-// SequenceMatcher compares sequence of strings. The basic
-// algorithm predates, and is a little fancier than, an algorithm
-// published in the late 1980's by Ratcliff and Obershelp under the
-// hyperbolic name "gestalt pattern matching". The basic idea is to find
-// the longest contiguous matching subsequence that contains no "junk"
-// elements (R-O doesn't address junk). The same idea is then applied
-// recursively to the pieces of the sequences to the left and to the right
-// of the matching subsequence. This does not yield minimal edit
-// sequences, but does tend to yield matches that "look right" to people.
-//
-// SequenceMatcher tries to compute a "human-friendly diff" between two
-// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the
-// longest *contiguous* & junk-free matching subsequence. That's what
-// catches peoples' eyes. The Windows(tm) windiff has another interesting
-// notion, pairing up elements that appear uniquely in each sequence.
-// That, and the method here, appear to yield more intuitive difference
-// reports than does diff. This method appears to be the least vulnerable
-// to synching up on blocks of "junk lines", though (like blank lines in
-// ordinary text files, or maybe "<P>" lines in HTML files). That may be
-// because this is the only method of the 3 that has a *concept* of
-// "junk" <wink>.
-//
-// Timing: Basic R-O is cubic time worst case and quadratic time expected
-// case. SequenceMatcher is quadratic time for the worst case and has
-// expected-case behavior dependent in a complicated way on how many
-// elements the sequences have in common; best case time is linear.
-type SequenceMatcher struct {
- a []string
- b []string
- b2j map[string][]int
- IsJunk func(string) bool
- autoJunk bool
- bJunk map[string]struct{}
- matchingBlocks []Match
- fullBCount map[string]int
- bPopular map[string]struct{}
- opCodes []OpCode
-}
-
-func NewMatcher(a, b []string) *SequenceMatcher {
- m := SequenceMatcher{autoJunk: true}
- m.SetSeqs(a, b)
- return &m
-}
-
-func NewMatcherWithJunk(a, b []string, autoJunk bool,
- isJunk func(string) bool,
-) *SequenceMatcher {
- m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk}
- m.SetSeqs(a, b)
- return &m
-}
-
-// Set two sequences to be compared.
-func (m *SequenceMatcher) SetSeqs(a, b []string) {
- m.SetSeq1(a)
- m.SetSeq2(b)
-}
-
-// Set the first sequence to be compared. The second sequence to be compared is
-// not changed.
-//
-// SequenceMatcher computes and caches detailed information about the second
-// sequence, so if you want to compare one sequence S against many sequences,
-// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other
-// sequences.
-//
-// See also SetSeqs() and SetSeq2().
-func (m *SequenceMatcher) SetSeq1(a []string) {
- if &a == &m.a {
- return
- }
- m.a = a
- m.matchingBlocks = nil
- m.opCodes = nil
-}
-
-// Set the second sequence to be compared. The first sequence to be compared is
-// not changed.
-func (m *SequenceMatcher) SetSeq2(b []string) {
- if &b == &m.b {
- return
- }
- m.b = b
- m.matchingBlocks = nil
- m.opCodes = nil
- m.fullBCount = nil
- m.chainB()
-}
-
-func (m *SequenceMatcher) chainB() {
- // Populate line -> index mapping
- b2j := map[string][]int{}
- for i, s := range m.b {
- indices := b2j[s]
- indices = append(indices, i)
- b2j[s] = indices
- }
-
- // Purge junk elements
- m.bJunk = map[string]struct{}{}
- if m.IsJunk != nil {
- junk := m.bJunk
- for s := range b2j {
- if m.IsJunk(s) {
- junk[s] = struct{}{}
- }
- }
- for s := range junk {
- delete(b2j, s)
- }
- }
-
- // Purge remaining popular elements
- popular := map[string]struct{}{}
- n := len(m.b)
- if m.autoJunk && n >= 200 {
- ntest := n/100 + 1
- for s, indices := range b2j {
- if len(indices) > ntest {
- popular[s] = struct{}{}
- }
- }
- for s := range popular {
- delete(b2j, s)
- }
- }
- m.bPopular = popular
- m.b2j = b2j
-}
-
-func (m *SequenceMatcher) isBJunk(s string) bool {
- _, ok := m.bJunk[s]
- return ok
-}
-
-// Find longest matching block in a[alo:ahi] and b[blo:bhi].
-//
-// If IsJunk is not defined:
-//
-// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
-//
-// alo <= i <= i+k <= ahi
-// blo <= j <= j+k <= bhi
-//
-// and for all (i',j',k') meeting those conditions,
-//
-// k >= k'
-// i <= i'
-// and if i == i', j <= j'
-//
-// In other words, of all maximal matching blocks, return one that
-// starts earliest in a, and of all those maximal matching blocks that
-// start earliest in a, return the one that starts earliest in b.
-//
-// If IsJunk is defined, first the longest matching block is
-// determined as above, but with the additional restriction that no
-// junk element appears in the block. Then that block is extended as
-// far as possible by matching (only) junk elements on both sides. So
-// the resulting block never matches on junk except as identical junk
-// happens to be adjacent to an "interesting" match.
-//
-// If no blocks match, return (alo, blo, 0).
-func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {
- // CAUTION: stripping common prefix or suffix would be incorrect.
- // E.g.,
- // ab
- // acab
- // Longest matching block is "ab", but if common prefix is
- // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so
- // strip, so ends up claiming that ab is changed to acab by
- // inserting "ca" in the middle. That's minimal but unintuitive:
- // "it's obvious" that someone inserted "ac" at the front.
- // Windiff ends up at the same place as diff, but by pairing up
- // the unique 'b's and then matching the first two 'a's.
- besti, bestj, bestsize := alo, blo, 0
-
- // find longest junk-free match
- // during an iteration of the loop, j2len[j] = length of longest
- // junk-free match ending with a[i-1] and b[j]
- j2len := map[int]int{}
- for i := alo; i != ahi; i++ {
- // look at all instances of a[i] in b; note that because
- // b2j has no junk keys, the loop is skipped if a[i] is junk
- newj2len := map[int]int{}
- for _, j := range m.b2j[m.a[i]] {
- // a[i] matches b[j]
- if j < blo {
- continue
- }
- if j >= bhi {
- break
- }
- k := j2len[j-1] + 1
- newj2len[j] = k
- if k > bestsize {
- besti, bestj, bestsize = i-k+1, j-k+1, k
- }
- }
- j2len = newj2len
- }
-
- // Extend the best by non-junk elements on each end. In particular,
- // "popular" non-junk elements aren't in b2j, which greatly speeds
- // the inner loop above, but also means "the best" match so far
- // doesn't contain any junk *or* popular non-junk elements.
- for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) &&
- m.a[besti-1] == m.b[bestj-1] {
- besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
- }
- for besti+bestsize < ahi && bestj+bestsize < bhi &&
- !m.isBJunk(m.b[bestj+bestsize]) &&
- m.a[besti+bestsize] == m.b[bestj+bestsize] {
- bestsize++
- }
-
- // Now that we have a wholly interesting match (albeit possibly
- // empty!), we may as well suck up the matching junk on each
- // side of it too. Can't think of a good reason not to, and it
- // saves post-processing the (possibly considerable) expense of
- // figuring out what to do with it. In the case of an empty
- // interesting match, this is clearly the right thing to do,
- // because no other kind of match is possible in the regions.
- for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) &&
- m.a[besti-1] == m.b[bestj-1] {
- besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
- }
- for besti+bestsize < ahi && bestj+bestsize < bhi &&
- m.isBJunk(m.b[bestj+bestsize]) &&
- m.a[besti+bestsize] == m.b[bestj+bestsize] {
- bestsize++
- }
-
- return Match{A: besti, B: bestj, Size: bestsize}
-}
-
-// Return list of triples describing matching subsequences.
-//
-// Each triple is of the form (i, j, n), and means that
-// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in
-// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are
-// adjacent triples in the list, and the second is not the last triple in the
-// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe
-// adjacent equal blocks.
-//
-// The last triple is a dummy, (len(a), len(b), 0), and is the only
-// triple with n==0.
-func (m *SequenceMatcher) GetMatchingBlocks() []Match {
- if m.matchingBlocks != nil {
- return m.matchingBlocks
- }
-
- var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match
- matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match {
- match := m.findLongestMatch(alo, ahi, blo, bhi)
- i, j, k := match.A, match.B, match.Size
- if match.Size > 0 {
- if alo < i && blo < j {
- matched = matchBlocks(alo, i, blo, j, matched)
- }
- matched = append(matched, match)
- if i+k < ahi && j+k < bhi {
- matched = matchBlocks(i+k, ahi, j+k, bhi, matched)
- }
- }
- return matched
- }
- matched := matchBlocks(0, len(m.a), 0, len(m.b), nil)
-
- // It's possible that we have adjacent equal blocks in the
- // matching_blocks list now.
- nonAdjacent := []Match{}
- i1, j1, k1 := 0, 0, 0
- for _, b := range matched {
- // Is this block adjacent to i1, j1, k1?
- i2, j2, k2 := b.A, b.B, b.Size
- if i1+k1 == i2 && j1+k1 == j2 {
- // Yes, so collapse them -- this just increases the length of
- // the first block by the length of the second, and the first
- // block so lengthened remains the block to compare against.
- k1 += k2
- } else {
- // Not adjacent. Remember the first block (k1==0 means it's
- // the dummy we started with), and make the second block the
- // new block to compare against.
- if k1 > 0 {
- nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
- }
- i1, j1, k1 = i2, j2, k2
- }
- }
- if k1 > 0 {
- nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
- }
-
- nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0})
- m.matchingBlocks = nonAdjacent
- return m.matchingBlocks
-}
-
-// Return list of 5-tuples describing how to turn a into b.
-//
-// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple
-// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
-// tuple preceding it, and likewise for j1 == the previous j2.
-//
-// The tags are characters, with these meanings:
-//
-// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2]
-//
-// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case.
-//
-// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case.
-//
-// 'e' (equal): a[i1:i2] == b[j1:j2]
-func (m *SequenceMatcher) GetOpCodes() []OpCode {
- if m.opCodes != nil {
- return m.opCodes
- }
- i, j := 0, 0
- matching := m.GetMatchingBlocks()
- opCodes := make([]OpCode, 0, len(matching))
- for _, m := range matching {
- // invariant: we've pumped out correct diffs to change
- // a[:i] into b[:j], and the next matching block is
- // a[ai:ai+size] == b[bj:bj+size]. So we need to pump
- // out a diff to change a[i:ai] into b[j:bj], pump out
- // the matching block, and move (i,j) beyond the match
- ai, bj, size := m.A, m.B, m.Size
- tag := byte(0)
- if i < ai && j < bj {
- tag = 'r'
- } else if i < ai {
- tag = 'd'
- } else if j < bj {
- tag = 'i'
- }
- if tag > 0 {
- opCodes = append(opCodes, OpCode{tag, i, ai, j, bj})
- }
- i, j = ai+size, bj+size
- // the list of matching blocks is terminated by a
- // sentinel with size 0
- if size > 0 {
- opCodes = append(opCodes, OpCode{'e', ai, i, bj, j})
- }
- }
- m.opCodes = opCodes
- return m.opCodes
-}
-
-// Isolate change clusters by eliminating ranges with no changes.
-//
-// Return a generator of groups with up to n lines of context.
-// Each group is in the same format as returned by GetOpCodes().
-func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
- if n < 0 {
- n = 3
- }
- codes := m.GetOpCodes()
- if len(codes) == 0 {
- codes = []OpCode{{'e', 0, 1, 0, 1}}
- }
- // Fixup leading and trailing groups if they show no changes.
- if codes[0].Tag == 'e' {
- c := codes[0]
- i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
- codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2}
- }
- if codes[len(codes)-1].Tag == 'e' {
- c := codes[len(codes)-1]
- i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
- codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)}
- }
- nn := n + n
- groups := [][]OpCode{}
- group := []OpCode{}
- for _, c := range codes {
- i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
- // End the current group and start a new one whenever
- // there is a large range with no changes.
- if c.Tag == 'e' && i2-i1 > nn {
- group = append(group, OpCode{
- c.Tag, i1, min(i2, i1+n),
- j1, min(j2, j1+n),
- })
- groups = append(groups, group)
- group = []OpCode{}
- i1, j1 = max(i1, i2-n), max(j1, j2-n)
- }
- group = append(group, OpCode{c.Tag, i1, i2, j1, j2})
- }
- if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') {
- groups = append(groups, group)
- }
- return groups
-}
-
-// Return a measure of the sequences' similarity (float in [0,1]).
-//
-// Where T is the total number of elements in both sequences, and
-// M is the number of matches, this is 2.0*M / T.
-// Note that this is 1 if the sequences are identical, and 0 if
-// they have nothing in common.
-//
-// .Ratio() is expensive to compute if you haven't already computed
-// .GetMatchingBlocks() or .GetOpCodes(), in which case you may
-// want to try .QuickRatio() or .RealQuickRation() first to get an
-// upper bound.
-func (m *SequenceMatcher) Ratio() float64 {
- matches := 0
- for _, m := range m.GetMatchingBlocks() {
- matches += m.Size
- }
- return calculateRatio(matches, len(m.a)+len(m.b))
-}
-
-// Return an upper bound on ratio() relatively quickly.
-//
-// This isn't defined beyond that it is an upper bound on .Ratio(), and
-// is faster to compute.
-func (m *SequenceMatcher) QuickRatio() float64 {
- // viewing a and b as multisets, set matches to the cardinality
- // of their intersection; this counts the number of matches
- // without regard to order, so is clearly an upper bound
- if m.fullBCount == nil {
- m.fullBCount = map[string]int{}
- for _, s := range m.b {
- m.fullBCount[s]++
- }
- }
-
- // avail[x] is the number of times x appears in 'b' less the
- // number of times we've seen it in 'a' so far ... kinda
- avail := map[string]int{}
- matches := 0
- for _, s := range m.a {
- n, ok := avail[s]
- if !ok {
- n = m.fullBCount[s]
- }
- avail[s] = n - 1
- if n > 0 {
- matches++
- }
- }
- return calculateRatio(matches, len(m.a)+len(m.b))
-}
-
-// Return an upper bound on ratio() very quickly.
-//
-// This isn't defined beyond that it is an upper bound on .Ratio(), and
-// is faster to compute than either .Ratio() or .QuickRatio().
-func (m *SequenceMatcher) RealQuickRatio() float64 {
- la, lb := len(m.a), len(m.b)
- return calculateRatio(min(la, lb), la+lb)
-}
-
-// Convert range to the "ed" format
-func formatRangeUnified(start, stop int) string {
- // Per the diff spec at http://www.unix.org/single_unix_specification/
- beginning := start + 1 // lines start numbering with one
- length := stop - start
- if length == 1 {
- return fmt.Sprintf("%d", beginning)
- }
- if length == 0 {
- beginning-- // empty ranges begin at line just before the range
- }
- return fmt.Sprintf("%d,%d", beginning, length)
-}
-
-// Unified diff parameters
-type UnifiedDiff struct {
- A []string // First sequence lines
- FromFile string // First file name
- FromDate string // First file time
- B []string // Second sequence lines
- ToFile string // Second file name
- ToDate string // Second file time
- Eol string // Headers end of line, defaults to LF
- Context int // Number of context lines
-}
-
-// Compare two sequences of lines; generate the delta as a unified diff.
-//
-// Unified diffs are a compact way of showing line changes and a few
-// lines of context. The number of context lines is set by 'n' which
-// defaults to three.
-//
-// By default, the diff control lines (those with ---, +++, or @@) are
-// created with a trailing newline. This is helpful so that inputs
-// created from file.readlines() result in diffs that are suitable for
-// file.writelines() since both the inputs and outputs have trailing
-// newlines.
-//
-// For inputs that do not have trailing newlines, set the lineterm
-// argument to "" so that the output will be uniformly newline free.
-//
-// The unidiff format normally has a header for filenames and modification
-// times. Any or all of these may be specified using strings for
-// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
-// The modification times are normally expressed in the ISO 8601 format.
-func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error {
- buf := bufio.NewWriter(writer)
- defer buf.Flush()
- wf := func(format string, args ...interface{}) error {
- _, err := buf.WriteString(fmt.Sprintf(format, args...))
- return err
- }
- ws := func(s string) error {
- _, err := buf.WriteString(s)
- return err
- }
-
- if len(diff.Eol) == 0 {
- diff.Eol = "\n"
- }
-
- started := false
- m := NewMatcher(diff.A, diff.B)
- for _, g := range m.GetGroupedOpCodes(diff.Context) {
- if !started {
- started = true
- fromDate := ""
- if len(diff.FromDate) > 0 {
- fromDate = "\t" + diff.FromDate
- }
- toDate := ""
- if len(diff.ToDate) > 0 {
- toDate = "\t" + diff.ToDate
- }
- if diff.FromFile != "" || diff.ToFile != "" {
- err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol)
- if err != nil {
- return err
- }
- err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol)
- if err != nil {
- return err
- }
- }
- }
- first, last := g[0], g[len(g)-1]
- range1 := formatRangeUnified(first.I1, last.I2)
- range2 := formatRangeUnified(first.J1, last.J2)
- if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil {
- return err
- }
- for _, c := range g {
- i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
- if c.Tag == 'e' {
- for _, line := range diff.A[i1:i2] {
- if err := ws(" " + line); err != nil {
- return err
- }
- }
- continue
- }
- if c.Tag == 'r' || c.Tag == 'd' {
- for _, line := range diff.A[i1:i2] {
- if err := ws("-" + line); err != nil {
- return err
- }
- }
- }
- if c.Tag == 'r' || c.Tag == 'i' {
- for _, line := range diff.B[j1:j2] {
- if err := ws("+" + line); err != nil {
- return err
- }
- }
- }
- }
- }
- return nil
-}
-
-// Like WriteUnifiedDiff but returns the diff a string.
-func GetUnifiedDiffString(diff UnifiedDiff) (string, error) {
- w := &bytes.Buffer{}
- err := WriteUnifiedDiff(w, diff)
- return w.String(), err
-}
-
-// Split a string on "\n" while preserving them. The output can be used
-// as input for UnifiedDiff and ContextDiff structures.
-func SplitLines(s string) []string {
- lines := strings.SplitAfter(s, "\n")
- lines[len(lines)-1] += "\n"
- return lines
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go
deleted file mode 100644
index a4fa6eabd..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2021 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package internal
-
-import "regexp"
-
-type GoCollectorRule struct {
- Matcher *regexp.Regexp
- Deny bool
-}
-
-// GoCollectorOptions should not be used be directly by anything, except `collectors` package.
-// Use it via collectors package instead. See issue
-// https://github.com/prometheus/client_golang/issues/1030.
-//
-// This is internal, so external users only can use it via `collector.WithGoCollector*` methods
-type GoCollectorOptions struct {
- DisableMemStatsLikeMetrics bool
- RuntimeMetricSumForHist map[string]string
- RuntimeMetricRules []GoCollectorRule
-}
-
-var GoCollectorDefaultRuntimeMetrics = regexp.MustCompile(`/gc/gogc:percent|/gc/gomemlimit:bytes|/sched/gomaxprocs:threads`)
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go
deleted file mode 100644
index 97d17d6cb..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2021 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build go1.17
-// +build go1.17
-
-package internal
-
-import (
- "math"
- "path"
- "runtime/metrics"
- "strings"
-
- "github.com/prometheus/common/model"
-)
-
-// RuntimeMetricsToProm produces a Prometheus metric name from a runtime/metrics
-// metric description and validates whether the metric is suitable for integration
-// with Prometheus.
-//
-// Returns false if a name could not be produced, or if Prometheus does not understand
-// the runtime/metrics Kind.
-//
-// Note that the main reason a name couldn't be produced is if the runtime/metrics
-// package exports a name with characters outside the valid Prometheus metric name
-// character set. This is theoretically possible, but should never happen in practice.
-// Still, don't rely on it.
-func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) {
- namespace := "go"
-
- comp := strings.SplitN(d.Name, ":", 2)
- key := comp[0]
- unit := comp[1]
-
- // The last path element in the key is the name,
- // the rest is the subsystem.
- subsystem := path.Dir(key[1:] /* remove leading / */)
- name := path.Base(key)
-
- // subsystem is translated by replacing all / and - with _.
- subsystem = strings.ReplaceAll(subsystem, "/", "_")
- subsystem = strings.ReplaceAll(subsystem, "-", "_")
-
- // unit is translated assuming that the unit contains no
- // non-ASCII characters.
- unit = strings.ReplaceAll(unit, "-", "_")
- unit = strings.ReplaceAll(unit, "*", "_")
- unit = strings.ReplaceAll(unit, "/", "_per_")
-
- // name has - replaced with _ and is concatenated with the unit and
- // other data.
- name = strings.ReplaceAll(name, "-", "_")
- name += "_" + unit
- if d.Cumulative && d.Kind != metrics.KindFloat64Histogram {
- name += "_total"
- }
-
- valid := model.IsValidMetricName(model.LabelValue(namespace + "_" + subsystem + "_" + name))
- switch d.Kind {
- case metrics.KindUint64:
- case metrics.KindFloat64:
- case metrics.KindFloat64Histogram:
- default:
- valid = false
- }
- return namespace, subsystem, name, valid
-}
-
-// RuntimeMetricsBucketsForUnit takes a set of buckets obtained for a runtime/metrics histogram
-// type (so, lower-bound inclusive) and a unit from a runtime/metrics name, and produces
-// a reduced set of buckets. This function always removes any -Inf bucket as it's represented
-// as the bottom-most upper-bound inclusive bucket in Prometheus.
-func RuntimeMetricsBucketsForUnit(buckets []float64, unit string) []float64 {
- switch unit {
- case "bytes":
- // Re-bucket as powers of 2.
- return reBucketExp(buckets, 2)
- case "seconds":
- // Re-bucket as powers of 10 and then merge all buckets greater
- // than 1 second into the +Inf bucket.
- b := reBucketExp(buckets, 10)
- for i := range b {
- if b[i] <= 1 {
- continue
- }
- b[i] = math.Inf(1)
- b = b[:i+1]
- break
- }
- return b
- }
- return buckets
-}
-
-// reBucketExp takes a list of bucket boundaries (lower bound inclusive) and
-// downsamples the buckets to those a multiple of base apart. The end result
-// is a roughly exponential (in many cases, perfectly exponential) bucketing
-// scheme.
-func reBucketExp(buckets []float64, base float64) []float64 {
- bucket := buckets[0]
- var newBuckets []float64
- // We may see a -Inf here, in which case, add it and skip it
- // since we risk producing NaNs otherwise.
- //
- // We need to preserve -Inf values to maintain runtime/metrics
- // conventions. We'll strip it out later.
- if bucket == math.Inf(-1) {
- newBuckets = append(newBuckets, bucket)
- buckets = buckets[1:]
- bucket = buckets[0]
- }
- // From now on, bucket should always have a non-Inf value because
- // Infs are only ever at the ends of the bucket lists, so
- // arithmetic operations on it are non-NaN.
- for i := 1; i < len(buckets); i++ {
- if bucket >= 0 && buckets[i] < bucket*base {
- // The next bucket we want to include is at least bucket*base.
- continue
- } else if bucket < 0 && buckets[i] < bucket/base {
- // In this case the bucket we're targeting is negative, and since
- // we're ascending through buckets here, we need to divide to get
- // closer to zero exponentially.
- continue
- }
- // The +Inf bucket will always be the last one, and we'll always
- // end up including it here because bucket
- newBuckets = append(newBuckets, bucket)
- bucket = buckets[i]
- }
- return append(newBuckets, bucket)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go
deleted file mode 100644
index 6515c1148..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package internal
-
-import (
- "sort"
-
- dto "github.com/prometheus/client_model/go"
-)
-
-// LabelPairSorter implements sort.Interface. It is used to sort a slice of
-// dto.LabelPair pointers.
-type LabelPairSorter []*dto.LabelPair
-
-func (s LabelPairSorter) Len() int {
- return len(s)
-}
-
-func (s LabelPairSorter) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
-}
-
-func (s LabelPairSorter) Less(i, j int) bool {
- return s[i].GetName() < s[j].GetName()
-}
-
-// MetricSorter is a sortable slice of *dto.Metric.
-type MetricSorter []*dto.Metric
-
-func (s MetricSorter) Len() int {
- return len(s)
-}
-
-func (s MetricSorter) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
-}
-
-func (s MetricSorter) Less(i, j int) bool {
- if len(s[i].Label) != len(s[j].Label) {
- // This should not happen. The metrics are
- // inconsistent. However, we have to deal with the fact, as
- // people might use custom collectors or metric family injection
- // to create inconsistent metrics. So let's simply compare the
- // number of labels in this case. That will still yield
- // reproducible sorting.
- return len(s[i].Label) < len(s[j].Label)
- }
- for n, lp := range s[i].Label {
- vi := lp.GetValue()
- vj := s[j].Label[n].GetValue()
- if vi != vj {
- return vi < vj
- }
- }
-
- // We should never arrive here. Multiple metrics with the same
- // label set in the same scrape will lead to undefined ingestion
- // behavior. However, as above, we have to provide stable sorting
- // here, even for inconsistent metrics. So sort equal metrics
- // by their timestamp, with missing timestamps (implying "now")
- // coming last.
- if s[i].TimestampMs == nil {
- return false
- }
- if s[j].TimestampMs == nil {
- return true
- }
- return s[i].GetTimestampMs() < s[j].GetTimestampMs()
-}
-
-// NormalizeMetricFamilies returns a MetricFamily slice with empty
-// MetricFamilies pruned and the remaining MetricFamilies sorted by name within
-// the slice, with the contained Metrics sorted within each MetricFamily.
-func NormalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily {
- for _, mf := range metricFamiliesByName {
- sort.Sort(MetricSorter(mf.Metric))
- }
- names := make([]string, 0, len(metricFamiliesByName))
- for name, mf := range metricFamiliesByName {
- if len(mf.Metric) > 0 {
- names = append(names, name)
- }
- }
- sort.Strings(names)
- result := make([]*dto.MetricFamily, 0, len(names))
- for _, name := range names {
- result = append(result, metricFamiliesByName[name])
- }
- return result
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/labels.go b/vendor/github.com/prometheus/client_golang/prometheus/labels.go
deleted file mode 100644
index c21911f29..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/labels.go
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "errors"
- "fmt"
- "strings"
- "unicode/utf8"
-
- "github.com/prometheus/common/model"
-)
-
-// Labels represents a collection of label name -> value mappings. This type is
-// commonly used with the With(Labels) and GetMetricWith(Labels) methods of
-// metric vector Collectors, e.g.:
-//
-// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
-//
-// The other use-case is the specification of constant label pairs in Opts or to
-// create a Desc.
-type Labels map[string]string
-
-// LabelConstraint normalizes label values.
-type LabelConstraint func(string) string
-
-// ConstrainedLabels represents a label name and its constrain function
-// to normalize label values. This type is commonly used when constructing
-// metric vector Collectors.
-type ConstrainedLabel struct {
- Name string
- Constraint LabelConstraint
-}
-
-// ConstrainableLabels is an interface that allows creating of labels that can
-// be optionally constrained.
-//
-// prometheus.V2().NewCounterVec(CounterVecOpts{
-// CounterOpts: {...}, // Usual CounterOpts fields
-// VariableLabels: []ConstrainedLabels{
-// {Name: "A"},
-// {Name: "B", Constraint: func(v string) string { ... }},
-// },
-// })
-type ConstrainableLabels interface {
- compile() *compiledLabels
- labelNames() []string
-}
-
-// ConstrainedLabels represents a collection of label name -> constrain function
-// to normalize label values. This type is commonly used when constructing
-// metric vector Collectors.
-type ConstrainedLabels []ConstrainedLabel
-
-func (cls ConstrainedLabels) compile() *compiledLabels {
- compiled := &compiledLabels{
- names: make([]string, len(cls)),
- labelConstraints: map[string]LabelConstraint{},
- }
-
- for i, label := range cls {
- compiled.names[i] = label.Name
- if label.Constraint != nil {
- compiled.labelConstraints[label.Name] = label.Constraint
- }
- }
-
- return compiled
-}
-
-func (cls ConstrainedLabels) labelNames() []string {
- names := make([]string, len(cls))
- for i, label := range cls {
- names[i] = label.Name
- }
- return names
-}
-
-// UnconstrainedLabels represents collection of label without any constraint on
-// their value. Thus, it is simply a collection of label names.
-//
-// UnconstrainedLabels([]string{ "A", "B" })
-//
-// is equivalent to
-//
-// ConstrainedLabels {
-// { Name: "A" },
-// { Name: "B" },
-// }
-type UnconstrainedLabels []string
-
-func (uls UnconstrainedLabels) compile() *compiledLabels {
- return &compiledLabels{
- names: uls,
- }
-}
-
-func (uls UnconstrainedLabels) labelNames() []string {
- return uls
-}
-
-type compiledLabels struct {
- names []string
- labelConstraints map[string]LabelConstraint
-}
-
-func (cls *compiledLabels) compile() *compiledLabels {
- return cls
-}
-
-func (cls *compiledLabels) labelNames() []string {
- return cls.names
-}
-
-func (cls *compiledLabels) constrain(labelName, value string) string {
- if fn, ok := cls.labelConstraints[labelName]; ok && fn != nil {
- return fn(value)
- }
- return value
-}
-
-// reservedLabelPrefix is a prefix which is not legal in user-supplied
-// label names.
-const reservedLabelPrefix = "__"
-
-var errInconsistentCardinality = errors.New("inconsistent label cardinality")
-
-func makeInconsistentCardinalityError(fqName string, labels, labelValues []string) error {
- return fmt.Errorf(
- "%w: %q has %d variable labels named %q but %d values %q were provided",
- errInconsistentCardinality, fqName,
- len(labels), labels,
- len(labelValues), labelValues,
- )
-}
-
-func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error {
- if len(labels) != expectedNumberOfValues {
- return fmt.Errorf(
- "%w: expected %d label values but got %d in %#v",
- errInconsistentCardinality, expectedNumberOfValues,
- len(labels), labels,
- )
- }
-
- for name, val := range labels {
- if !utf8.ValidString(val) {
- return fmt.Errorf("label %s: value %q is not valid UTF-8", name, val)
- }
- }
-
- return nil
-}
-
-func validateLabelValues(vals []string, expectedNumberOfValues int) error {
- if len(vals) != expectedNumberOfValues {
- // The call below makes vals escape, copy them to avoid that.
- vals := append([]string(nil), vals...)
- return fmt.Errorf(
- "%w: expected %d label values but got %d in %#v",
- errInconsistentCardinality, expectedNumberOfValues,
- len(vals), vals,
- )
- }
-
- for _, val := range vals {
- if !utf8.ValidString(val) {
- return fmt.Errorf("label value %q is not valid UTF-8", val)
- }
- }
-
- return nil
-}
-
-func checkLabelName(l string) bool {
- return model.LabelName(l).IsValid() && !strings.HasPrefix(l, reservedLabelPrefix)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go
deleted file mode 100644
index 9d9b81ab4..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "errors"
- "math"
- "sort"
- "strings"
- "time"
-
- dto "github.com/prometheus/client_model/go"
- "github.com/prometheus/common/model"
- "google.golang.org/protobuf/proto"
-)
-
-var separatorByteSlice = []byte{model.SeparatorByte} // For convenient use with xxhash.
-
-// A Metric models a single sample value with its meta data being exported to
-// Prometheus. Implementations of Metric in this package are Gauge, Counter,
-// Histogram, Summary, and Untyped.
-type Metric interface {
- // Desc returns the descriptor for the Metric. This method idempotently
- // returns the same descriptor throughout the lifetime of the
- // Metric. The returned descriptor is immutable by contract. A Metric
- // unable to describe itself must return an invalid descriptor (created
- // with NewInvalidDesc).
- Desc() *Desc
- // Write encodes the Metric into a "Metric" Protocol Buffer data
- // transmission object.
- //
- // Metric implementations must observe concurrency safety as reads of
- // this metric may occur at any time, and any blocking occurs at the
- // expense of total performance of rendering all registered
- // metrics. Ideally, Metric implementations should support concurrent
- // readers.
- //
- // While populating dto.Metric, it is the responsibility of the
- // implementation to ensure validity of the Metric protobuf (like valid
- // UTF-8 strings or syntactically valid metric and label names). It is
- // recommended to sort labels lexicographically. Callers of Write should
- // still make sure of sorting if they depend on it.
- Write(*dto.Metric) error
- // TODO(beorn7): The original rationale of passing in a pre-allocated
- // dto.Metric protobuf to save allocations has disappeared. The
- // signature of this method should be changed to "Write() (*dto.Metric,
- // error)".
-}
-
-// Opts bundles the options for creating most Metric types. Each metric
-// implementation XXX has its own XXXOpts type, but in most cases, it is just
-// an alias of this type (which might change when the requirement arises.)
-//
-// It is mandatory to set Name to a non-empty string. All other fields are
-// optional and can safely be left at their zero value, although it is strongly
-// encouraged to set a Help string.
-type Opts struct {
- // Namespace, Subsystem, and Name are components of the fully-qualified
- // name of the Metric (created by joining these components with
- // "_"). Only Name is mandatory, the others merely help structuring the
- // name. Note that the fully-qualified name of the metric must be a
- // valid Prometheus metric name.
- Namespace string
- Subsystem string
- Name string
-
- // Help provides information about this metric.
- //
- // Metrics with the same fully-qualified name must have the same Help
- // string.
- Help string
-
- // ConstLabels are used to attach fixed labels to this metric. Metrics
- // with the same fully-qualified name must have the same label names in
- // their ConstLabels.
- //
- // ConstLabels are only used rarely. In particular, do not use them to
- // attach the same labels to all your metrics. Those use cases are
- // better covered by target labels set by the scraping Prometheus
- // server, or by one specific metric (e.g. a build_info or a
- // machine_role metric). See also
- // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels
- ConstLabels Labels
-
- // now is for testing purposes, by default it's time.Now.
- now func() time.Time
-}
-
-// BuildFQName joins the given three name components by "_". Empty name
-// components are ignored. If the name parameter itself is empty, an empty
-// string is returned, no matter what. Metric implementations included in this
-// library use this function internally to generate the fully-qualified metric
-// name from the name component in their Opts. Users of the library will only
-// need this function if they implement their own Metric or instantiate a Desc
-// (with NewDesc) directly.
-func BuildFQName(namespace, subsystem, name string) string {
- if name == "" {
- return ""
- }
- switch {
- case namespace != "" && subsystem != "":
- return strings.Join([]string{namespace, subsystem, name}, "_")
- case namespace != "":
- return strings.Join([]string{namespace, name}, "_")
- case subsystem != "":
- return strings.Join([]string{subsystem, name}, "_")
- }
- return name
-}
-
-type invalidMetric struct {
- desc *Desc
- err error
-}
-
-// NewInvalidMetric returns a metric whose Write method always returns the
-// provided error. It is useful if a Collector finds itself unable to collect
-// a metric and wishes to report an error to the registry.
-func NewInvalidMetric(desc *Desc, err error) Metric {
- return &invalidMetric{desc, err}
-}
-
-func (m *invalidMetric) Desc() *Desc { return m.desc }
-
-func (m *invalidMetric) Write(*dto.Metric) error { return m.err }
-
-type timestampedMetric struct {
- Metric
- t time.Time
-}
-
-func (m timestampedMetric) Write(pb *dto.Metric) error {
- e := m.Metric.Write(pb)
- pb.TimestampMs = proto.Int64(m.t.Unix()*1000 + int64(m.t.Nanosecond()/1000000))
- return e
-}
-
-// NewMetricWithTimestamp returns a new Metric wrapping the provided Metric in a
-// way that it has an explicit timestamp set to the provided Time. This is only
-// useful in rare cases as the timestamp of a Prometheus metric should usually
-// be set by the Prometheus server during scraping. Exceptions include mirroring
-// metrics with given timestamps from other metric
-// sources.
-//
-// NewMetricWithTimestamp works best with MustNewConstMetric,
-// MustNewConstHistogram, and MustNewConstSummary, see example.
-//
-// Currently, the exposition formats used by Prometheus are limited to
-// millisecond resolution. Thus, the provided time will be rounded down to the
-// next full millisecond value.
-func NewMetricWithTimestamp(t time.Time, m Metric) Metric {
- return timestampedMetric{Metric: m, t: t}
-}
-
-type withExemplarsMetric struct {
- Metric
-
- exemplars []*dto.Exemplar
-}
-
-func (m *withExemplarsMetric) Write(pb *dto.Metric) error {
- if err := m.Metric.Write(pb); err != nil {
- return err
- }
-
- switch {
- case pb.Counter != nil:
- pb.Counter.Exemplar = m.exemplars[len(m.exemplars)-1]
- case pb.Histogram != nil:
- for _, e := range m.exemplars {
- // pb.Histogram.Bucket are sorted by UpperBound.
- i := sort.Search(len(pb.Histogram.Bucket), func(i int) bool {
- return pb.Histogram.Bucket[i].GetUpperBound() >= e.GetValue()
- })
- if i < len(pb.Histogram.Bucket) {
- pb.Histogram.Bucket[i].Exemplar = e
- } else {
- // The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365.
- b := &dto.Bucket{
- CumulativeCount: proto.Uint64(pb.Histogram.GetSampleCount()),
- UpperBound: proto.Float64(math.Inf(1)),
- Exemplar: e,
- }
- pb.Histogram.Bucket = append(pb.Histogram.Bucket, b)
- }
- }
- default:
- // TODO(bwplotka): Implement Gauge?
- return errors.New("cannot inject exemplar into Gauge, Summary or Untyped")
- }
-
- return nil
-}
-
-// Exemplar is easier to use, user-facing representation of *dto.Exemplar.
-type Exemplar struct {
- Value float64
- Labels Labels
- // Optional.
- // Default value (time.Time{}) indicates its empty, which should be
- // understood as time.Now() time at the moment of creation of metric.
- Timestamp time.Time
-}
-
-// NewMetricWithExemplars returns a new Metric wrapping the provided Metric with given
-// exemplars. Exemplars are validated.
-//
-// Only last applicable exemplar is injected from the list.
-// For example for Counter it means last exemplar is injected.
-// For Histogram, it means last applicable exemplar for each bucket is injected.
-//
-// NewMetricWithExemplars works best with MustNewConstMetric and
-// MustNewConstHistogram, see example.
-func NewMetricWithExemplars(m Metric, exemplars ...Exemplar) (Metric, error) {
- if len(exemplars) == 0 {
- return nil, errors.New("no exemplar was passed for NewMetricWithExemplars")
- }
-
- var (
- now = time.Now()
- exs = make([]*dto.Exemplar, len(exemplars))
- err error
- )
- for i, e := range exemplars {
- ts := e.Timestamp
- if ts.IsZero() {
- ts = now
- }
- exs[i], err = newExemplar(e.Value, ts, e.Labels)
- if err != nil {
- return nil, err
- }
- }
-
- return &withExemplarsMetric{Metric: m, exemplars: exs}, nil
-}
-
-// MustNewMetricWithExemplars is a version of NewMetricWithExemplars that panics where
-// NewMetricWithExemplars would have returned an error.
-func MustNewMetricWithExemplars(m Metric, exemplars ...Exemplar) Metric {
- ret, err := NewMetricWithExemplars(m, exemplars...)
- if err != nil {
- panic(err)
- }
- return ret
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go b/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go
deleted file mode 100644
index 7c12b2108..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build !js || wasm
-// +build !js wasm
-
-package prometheus
-
-import "runtime"
-
-// getRuntimeNumThreads returns the number of open OS threads.
-func getRuntimeNumThreads() float64 {
- n, _ := runtime.ThreadCreateProfile(nil)
- return float64(n)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go b/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go
deleted file mode 100644
index 7348df01d..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build js && !wasm
-// +build js,!wasm
-
-package prometheus
-
-// getRuntimeNumThreads returns the number of open OS threads.
-func getRuntimeNumThreads() float64 {
- return 1
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/observer.go b/vendor/github.com/prometheus/client_golang/prometheus/observer.go
deleted file mode 100644
index 03773b21f..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/observer.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-// Observer is the interface that wraps the Observe method, which is used by
-// Histogram and Summary to add observations.
-type Observer interface {
- Observe(float64)
-}
-
-// The ObserverFunc type is an adapter to allow the use of ordinary
-// functions as Observers. If f is a function with the appropriate
-// signature, ObserverFunc(f) is an Observer that calls f.
-//
-// This adapter is usually used in connection with the Timer type, and there are
-// two general use cases:
-//
-// The most common one is to use a Gauge as the Observer for a Timer.
-// See the "Gauge" Timer example.
-//
-// The more advanced use case is to create a function that dynamically decides
-// which Observer to use for observing the duration. See the "Complex" Timer
-// example.
-type ObserverFunc func(float64)
-
-// Observe calls f(value). It implements Observer.
-func (f ObserverFunc) Observe(value float64) {
- f(value)
-}
-
-// ObserverVec is an interface implemented by `HistogramVec` and `SummaryVec`.
-type ObserverVec interface {
- GetMetricWith(Labels) (Observer, error)
- GetMetricWithLabelValues(lvs ...string) (Observer, error)
- With(Labels) Observer
- WithLabelValues(...string) Observer
- CurryWith(Labels) (ObserverVec, error)
- MustCurryWith(Labels) ObserverVec
-
- Collector
-}
-
-// ExemplarObserver is implemented by Observers that offer the option of
-// observing a value together with an exemplar. Its ObserveWithExemplar method
-// works like the Observe method of an Observer but also replaces the currently
-// saved exemplar (if any) with a new one, created from the provided value, the
-// current time as timestamp, and the provided Labels. Empty Labels will lead to
-// a valid (label-less) exemplar. But if Labels is nil, the current exemplar is
-// left in place. ObserveWithExemplar panics if any of the provided labels are
-// invalid or if the provided labels contain more than 128 runes in total.
-type ExemplarObserver interface {
- ObserveWithExemplar(value float64, exemplar Labels)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
deleted file mode 100644
index 62a4e7ad9..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "errors"
- "fmt"
- "os"
- "strconv"
- "strings"
-)
-
-type processCollector struct {
- collectFn func(chan<- Metric)
- pidFn func() (int, error)
- reportErrors bool
- cpuTotal *Desc
- openFDs, maxFDs *Desc
- vsize, maxVsize *Desc
- rss *Desc
- startTime *Desc
- inBytes, outBytes *Desc
-}
-
-// ProcessCollectorOpts defines the behavior of a process metrics collector
-// created with NewProcessCollector.
-type ProcessCollectorOpts struct {
- // PidFn returns the PID of the process the collector collects metrics
- // for. It is called upon each collection. By default, the PID of the
- // current process is used, as determined on construction time by
- // calling os.Getpid().
- PidFn func() (int, error)
- // If non-empty, each of the collected metrics is prefixed by the
- // provided string and an underscore ("_").
- Namespace string
- // If true, any error encountered during collection is reported as an
- // invalid metric (see NewInvalidMetric). Otherwise, errors are ignored
- // and the collected metrics will be incomplete. (Possibly, no metrics
- // will be collected at all.) While that's usually not desired, it is
- // appropriate for the common "mix-in" of process metrics, where process
- // metrics are nice to have, but failing to collect them should not
- // disrupt the collection of the remaining metrics.
- ReportErrors bool
-}
-
-// NewProcessCollector is the obsolete version of collectors.NewProcessCollector.
-// See there for documentation.
-//
-// Deprecated: Use collectors.NewProcessCollector instead.
-func NewProcessCollector(opts ProcessCollectorOpts) Collector {
- ns := ""
- if len(opts.Namespace) > 0 {
- ns = opts.Namespace + "_"
- }
-
- c := &processCollector{
- reportErrors: opts.ReportErrors,
- cpuTotal: NewDesc(
- ns+"process_cpu_seconds_total",
- "Total user and system CPU time spent in seconds.",
- nil, nil,
- ),
- openFDs: NewDesc(
- ns+"process_open_fds",
- "Number of open file descriptors.",
- nil, nil,
- ),
- maxFDs: NewDesc(
- ns+"process_max_fds",
- "Maximum number of open file descriptors.",
- nil, nil,
- ),
- vsize: NewDesc(
- ns+"process_virtual_memory_bytes",
- "Virtual memory size in bytes.",
- nil, nil,
- ),
- maxVsize: NewDesc(
- ns+"process_virtual_memory_max_bytes",
- "Maximum amount of virtual memory available in bytes.",
- nil, nil,
- ),
- rss: NewDesc(
- ns+"process_resident_memory_bytes",
- "Resident memory size in bytes.",
- nil, nil,
- ),
- startTime: NewDesc(
- ns+"process_start_time_seconds",
- "Start time of the process since unix epoch in seconds.",
- nil, nil,
- ),
- inBytes: NewDesc(
- ns+"process_network_receive_bytes_total",
- "Number of bytes received by the process over the network.",
- nil, nil,
- ),
- outBytes: NewDesc(
- ns+"process_network_transmit_bytes_total",
- "Number of bytes sent by the process over the network.",
- nil, nil,
- ),
- }
-
- if opts.PidFn == nil {
- c.pidFn = getPIDFn()
- } else {
- c.pidFn = opts.PidFn
- }
-
- // Set up process metric collection if supported by the runtime.
- if canCollectProcess() {
- c.collectFn = c.processCollect
- } else {
- c.collectFn = func(ch chan<- Metric) {
- c.reportError(ch, nil, errors.New("process metrics not supported on this platform"))
- }
- }
-
- return c
-}
-
-// Describe returns all descriptions of the collector.
-func (c *processCollector) Describe(ch chan<- *Desc) {
- ch <- c.cpuTotal
- ch <- c.openFDs
- ch <- c.maxFDs
- ch <- c.vsize
- ch <- c.maxVsize
- ch <- c.rss
- ch <- c.startTime
- ch <- c.inBytes
- ch <- c.outBytes
-}
-
-// Collect returns the current state of all metrics of the collector.
-func (c *processCollector) Collect(ch chan<- Metric) {
- c.collectFn(ch)
-}
-
-func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {
- if !c.reportErrors {
- return
- }
- if desc == nil {
- desc = NewInvalidDesc(err)
- }
- ch <- NewInvalidMetric(desc, err)
-}
-
-// NewPidFileFn returns a function that retrieves a pid from the specified file.
-// It is meant to be used for the PidFn field in ProcessCollectorOpts.
-func NewPidFileFn(pidFilePath string) func() (int, error) {
- return func() (int, error) {
- content, err := os.ReadFile(pidFilePath)
- if err != nil {
- return 0, fmt.Errorf("can't read pid file %q: %w", pidFilePath, err)
- }
- pid, err := strconv.Atoi(strings.TrimSpace(string(content)))
- if err != nil {
- return 0, fmt.Errorf("can't parse pid file %q: %w", pidFilePath, err)
- }
-
- return pid, nil
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go
deleted file mode 100644
index b1e363d6c..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build js
-// +build js
-
-package prometheus
-
-func canCollectProcess() bool {
- return false
-}
-
-func (c *processCollector) processCollect(ch chan<- Metric) {
- // noop on this platform
- return
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
deleted file mode 100644
index 14d56d2d0..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2019 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build !windows && !js && !wasip1
-// +build !windows,!js,!wasip1
-
-package prometheus
-
-import (
- "github.com/prometheus/procfs"
-)
-
-func canCollectProcess() bool {
- _, err := procfs.NewDefaultFS()
- return err == nil
-}
-
-func (c *processCollector) processCollect(ch chan<- Metric) {
- pid, err := c.pidFn()
- if err != nil {
- c.reportError(ch, nil, err)
- return
- }
-
- p, err := procfs.NewProc(pid)
- if err != nil {
- c.reportError(ch, nil, err)
- return
- }
-
- if stat, err := p.Stat(); err == nil {
- ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
- ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
- ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
- if startTime, err := stat.StartTime(); err == nil {
- ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
- } else {
- c.reportError(ch, c.startTime, err)
- }
- } else {
- c.reportError(ch, nil, err)
- }
-
- if fds, err := p.FileDescriptorsLen(); err == nil {
- ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
- } else {
- c.reportError(ch, c.openFDs, err)
- }
-
- if limits, err := p.Limits(); err == nil {
- ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
- ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(limits.AddressSpace))
- } else {
- c.reportError(ch, nil, err)
- }
-
- if netstat, err := p.Netstat(); err == nil {
- var inOctets, outOctets float64
- if netstat.IpExt.InOctets != nil {
- inOctets = *netstat.IpExt.InOctets
- }
- if netstat.IpExt.OutOctets != nil {
- outOctets = *netstat.IpExt.OutOctets
- }
- ch <- MustNewConstMetric(c.inBytes, CounterValue, inOctets)
- ch <- MustNewConstMetric(c.outBytes, CounterValue, outOctets)
- } else {
- c.reportError(ch, nil, err)
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go
deleted file mode 100644
index d8d9a6d7a..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2023 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build wasip1
-// +build wasip1
-
-package prometheus
-
-func canCollectProcess() bool {
- return false
-}
-
-func (*processCollector) processCollect(chan<- Metric) {
- // noop on this platform
- return
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
deleted file mode 100644
index f973398df..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2019 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "syscall"
- "unsafe"
-
- "golang.org/x/sys/windows"
-)
-
-func canCollectProcess() bool {
- return true
-}
-
-var (
- modpsapi = syscall.NewLazyDLL("psapi.dll")
- modkernel32 = syscall.NewLazyDLL("kernel32.dll")
-
- procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
- procGetProcessHandleCount = modkernel32.NewProc("GetProcessHandleCount")
-)
-
-type processMemoryCounters struct {
- // System interface description
- // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-process_memory_counters_ex
-
- // Refer to the Golang internal implementation
- // https://golang.org/src/internal/syscall/windows/psapi_windows.go
- _ uint32
- PageFaultCount uint32
- PeakWorkingSetSize uintptr
- WorkingSetSize uintptr
- QuotaPeakPagedPoolUsage uintptr
- QuotaPagedPoolUsage uintptr
- QuotaPeakNonPagedPoolUsage uintptr
- QuotaNonPagedPoolUsage uintptr
- PagefileUsage uintptr
- PeakPagefileUsage uintptr
- PrivateUsage uintptr
-}
-
-func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) {
- mem := processMemoryCounters{}
- r1, _, err := procGetProcessMemoryInfo.Call(
- uintptr(handle),
- uintptr(unsafe.Pointer(&mem)),
- uintptr(unsafe.Sizeof(mem)),
- )
- if r1 != 1 {
- return mem, err
- } else {
- return mem, nil
- }
-}
-
-func getProcessHandleCount(handle windows.Handle) (uint32, error) {
- var count uint32
- r1, _, err := procGetProcessHandleCount.Call(
- uintptr(handle),
- uintptr(unsafe.Pointer(&count)),
- )
- if r1 != 1 {
- return 0, err
- } else {
- return count, nil
- }
-}
-
-func (c *processCollector) processCollect(ch chan<- Metric) {
- h, err := windows.GetCurrentProcess()
- if err != nil {
- c.reportError(ch, nil, err)
- return
- }
-
- var startTime, exitTime, kernelTime, userTime windows.Filetime
- err = windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime)
- if err != nil {
- c.reportError(ch, nil, err)
- return
- }
- ch <- MustNewConstMetric(c.startTime, GaugeValue, float64(startTime.Nanoseconds()/1e9))
- ch <- MustNewConstMetric(c.cpuTotal, CounterValue, fileTimeToSeconds(kernelTime)+fileTimeToSeconds(userTime))
-
- mem, err := getProcessMemoryInfo(h)
- if err != nil {
- c.reportError(ch, nil, err)
- return
- }
- ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.PrivateUsage))
- ch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.WorkingSetSize))
-
- handles, err := getProcessHandleCount(h)
- if err != nil {
- c.reportError(ch, nil, err)
- return
- }
- ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(handles))
- ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process.
-}
-
-func fileTimeToSeconds(ft windows.Filetime) float64 {
- return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
deleted file mode 100644
index 315eab5f1..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
- "bufio"
- "io"
- "net"
- "net/http"
-)
-
-const (
- closeNotifier = 1 << iota
- flusher
- hijacker
- readerFrom
- pusher
-)
-
-type delegator interface {
- http.ResponseWriter
-
- Status() int
- Written() int64
-}
-
-type responseWriterDelegator struct {
- http.ResponseWriter
-
- status int
- written int64
- wroteHeader bool
- observeWriteHeader func(int)
-}
-
-func (r *responseWriterDelegator) Status() int {
- return r.status
-}
-
-func (r *responseWriterDelegator) Written() int64 {
- return r.written
-}
-
-func (r *responseWriterDelegator) WriteHeader(code int) {
- if r.observeWriteHeader != nil && !r.wroteHeader {
- // Only call observeWriteHeader for the 1st time. It's a bug if
- // WriteHeader is called more than once, but we want to protect
- // against it here. Note that we still delegate the WriteHeader
- // to the original ResponseWriter to not mask the bug from it.
- r.observeWriteHeader(code)
- }
- r.status = code
- r.wroteHeader = true
- r.ResponseWriter.WriteHeader(code)
-}
-
-func (r *responseWriterDelegator) Write(b []byte) (int, error) {
- // If applicable, call WriteHeader here so that observeWriteHeader is
- // handled appropriately.
- if !r.wroteHeader {
- r.WriteHeader(http.StatusOK)
- }
- n, err := r.ResponseWriter.Write(b)
- r.written += int64(n)
- return n, err
-}
-
-// Unwrap lets http.ResponseController get the underlying http.ResponseWriter,
-// by implementing the [rwUnwrapper](https://cs.opensource.google/go/go/+/refs/tags/go1.21.4:src/net/http/responsecontroller.go;l=42-44) interface.
-func (r *responseWriterDelegator) Unwrap() http.ResponseWriter {
- return r.ResponseWriter
-}
-
-type (
- closeNotifierDelegator struct{ *responseWriterDelegator }
- flusherDelegator struct{ *responseWriterDelegator }
- hijackerDelegator struct{ *responseWriterDelegator }
- readerFromDelegator struct{ *responseWriterDelegator }
- pusherDelegator struct{ *responseWriterDelegator }
-)
-
-func (d closeNotifierDelegator) CloseNotify() <-chan bool {
- //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users.
- return d.ResponseWriter.(http.CloseNotifier).CloseNotify()
-}
-
-func (d flusherDelegator) Flush() {
- // If applicable, call WriteHeader here so that observeWriteHeader is
- // handled appropriately.
- if !d.wroteHeader {
- d.WriteHeader(http.StatusOK)
- }
- d.ResponseWriter.(http.Flusher).Flush()
-}
-
-func (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- return d.ResponseWriter.(http.Hijacker).Hijack()
-}
-
-func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {
- // If applicable, call WriteHeader here so that observeWriteHeader is
- // handled appropriately.
- if !d.wroteHeader {
- d.WriteHeader(http.StatusOK)
- }
- n, err := d.ResponseWriter.(io.ReaderFrom).ReadFrom(re)
- d.written += n
- return n, err
-}
-
-func (d pusherDelegator) Push(target string, opts *http.PushOptions) error {
- return d.ResponseWriter.(http.Pusher).Push(target, opts)
-}
-
-var pickDelegator = make([]func(*responseWriterDelegator) delegator, 32)
-
-func init() {
- // TODO(beorn7): Code generation would help here.
- pickDelegator[0] = func(d *responseWriterDelegator) delegator { // 0
- return d
- }
- pickDelegator[closeNotifier] = func(d *responseWriterDelegator) delegator { // 1
- return closeNotifierDelegator{d}
- }
- pickDelegator[flusher] = func(d *responseWriterDelegator) delegator { // 2
- return flusherDelegator{d}
- }
- pickDelegator[flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 3
- return struct {
- *responseWriterDelegator
- http.Flusher
- http.CloseNotifier
- }{d, flusherDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[hijacker] = func(d *responseWriterDelegator) delegator { // 4
- return hijackerDelegator{d}
- }
- pickDelegator[hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 5
- return struct {
- *responseWriterDelegator
- http.Hijacker
- http.CloseNotifier
- }{d, hijackerDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 6
- return struct {
- *responseWriterDelegator
- http.Hijacker
- http.Flusher
- }{d, hijackerDelegator{d}, flusherDelegator{d}}
- }
- pickDelegator[hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 7
- return struct {
- *responseWriterDelegator
- http.Hijacker
- http.Flusher
- http.CloseNotifier
- }{d, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[readerFrom] = func(d *responseWriterDelegator) delegator { // 8
- return readerFromDelegator{d}
- }
- pickDelegator[readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 9
- return struct {
- *responseWriterDelegator
- io.ReaderFrom
- http.CloseNotifier
- }{d, readerFromDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 10
- return struct {
- *responseWriterDelegator
- io.ReaderFrom
- http.Flusher
- }{d, readerFromDelegator{d}, flusherDelegator{d}}
- }
- pickDelegator[readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 11
- return struct {
- *responseWriterDelegator
- io.ReaderFrom
- http.Flusher
- http.CloseNotifier
- }{d, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 12
- return struct {
- *responseWriterDelegator
- io.ReaderFrom
- http.Hijacker
- }{d, readerFromDelegator{d}, hijackerDelegator{d}}
- }
- pickDelegator[readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 13
- return struct {
- *responseWriterDelegator
- io.ReaderFrom
- http.Hijacker
- http.CloseNotifier
- }{d, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 14
- return struct {
- *responseWriterDelegator
- io.ReaderFrom
- http.Hijacker
- http.Flusher
- }{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
- }
- pickDelegator[readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 15
- return struct {
- *responseWriterDelegator
- io.ReaderFrom
- http.Hijacker
- http.Flusher
- http.CloseNotifier
- }{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16
- return pusherDelegator{d}
- }
- pickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17
- return struct {
- *responseWriterDelegator
- http.Pusher
- http.CloseNotifier
- }{d, pusherDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[pusher+flusher] = func(d *responseWriterDelegator) delegator { // 18
- return struct {
- *responseWriterDelegator
- http.Pusher
- http.Flusher
- }{d, pusherDelegator{d}, flusherDelegator{d}}
- }
- pickDelegator[pusher+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 19
- return struct {
- *responseWriterDelegator
- http.Pusher
- http.Flusher
- http.CloseNotifier
- }{d, pusherDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[pusher+hijacker] = func(d *responseWriterDelegator) delegator { // 20
- return struct {
- *responseWriterDelegator
- http.Pusher
- http.Hijacker
- }{d, pusherDelegator{d}, hijackerDelegator{d}}
- }
- pickDelegator[pusher+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 21
- return struct {
- *responseWriterDelegator
- http.Pusher
- http.Hijacker
- http.CloseNotifier
- }{d, pusherDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[pusher+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 22
- return struct {
- *responseWriterDelegator
- http.Pusher
- http.Hijacker
- http.Flusher
- }{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
- }
- pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 23
- return struct {
- *responseWriterDelegator
- http.Pusher
- http.Hijacker
- http.Flusher
- http.CloseNotifier
- }{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[pusher+readerFrom] = func(d *responseWriterDelegator) delegator { // 24
- return struct {
- *responseWriterDelegator
- http.Pusher
- io.ReaderFrom
- }{d, pusherDelegator{d}, readerFromDelegator{d}}
- }
- pickDelegator[pusher+readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 25
- return struct {
- *responseWriterDelegator
- http.Pusher
- io.ReaderFrom
- http.CloseNotifier
- }{d, pusherDelegator{d}, readerFromDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[pusher+readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 26
- return struct {
- *responseWriterDelegator
- http.Pusher
- io.ReaderFrom
- http.Flusher
- }{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}}
- }
- pickDelegator[pusher+readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 27
- return struct {
- *responseWriterDelegator
- http.Pusher
- io.ReaderFrom
- http.Flusher
- http.CloseNotifier
- }{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[pusher+readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 28
- return struct {
- *responseWriterDelegator
- http.Pusher
- io.ReaderFrom
- http.Hijacker
- }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}}
- }
- pickDelegator[pusher+readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 29
- return struct {
- *responseWriterDelegator
- http.Pusher
- io.ReaderFrom
- http.Hijacker
- http.CloseNotifier
- }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
- }
- pickDelegator[pusher+readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 30
- return struct {
- *responseWriterDelegator
- http.Pusher
- io.ReaderFrom
- http.Hijacker
- http.Flusher
- }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
- }
- pickDelegator[pusher+readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 31
- return struct {
- *responseWriterDelegator
- http.Pusher
- io.ReaderFrom
- http.Hijacker
- http.Flusher
- http.CloseNotifier
- }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
- }
-}
-
-func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
- d := &responseWriterDelegator{
- ResponseWriter: w,
- observeWriteHeader: observeWriteHeaderFunc,
- }
-
- id := 0
- //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users.
- if _, ok := w.(http.CloseNotifier); ok {
- id += closeNotifier
- }
- if _, ok := w.(http.Flusher); ok {
- id += flusher
- }
- if _, ok := w.(http.Hijacker); ok {
- id += hijacker
- }
- if _, ok := w.(io.ReaderFrom); ok {
- id += readerFrom
- }
- if _, ok := w.(http.Pusher); ok {
- id += pusher
- }
-
- return pickDelegator[id](d)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
deleted file mode 100644
index e598e66e6..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
+++ /dev/null
@@ -1,467 +0,0 @@
-// Copyright 2016 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package promhttp provides tooling around HTTP servers and clients.
-//
-// First, the package allows the creation of http.Handler instances to expose
-// Prometheus metrics via HTTP. promhttp.Handler acts on the
-// prometheus.DefaultGatherer. With HandlerFor, you can create a handler for a
-// custom registry or anything that implements the Gatherer interface. It also
-// allows the creation of handlers that act differently on errors or allow to
-// log errors.
-//
-// Second, the package provides tooling to instrument instances of http.Handler
-// via middleware. Middleware wrappers follow the naming scheme
-// InstrumentHandlerX, where X describes the intended use of the middleware.
-// See each function's doc comment for specific details.
-//
-// Finally, the package allows for an http.RoundTripper to be instrumented via
-// middleware. Middleware wrappers follow the naming scheme
-// InstrumentRoundTripperX, where X describes the intended use of the
-// middleware. See each function's doc comment for specific details.
-package promhttp
-
-import (
- "compress/gzip"
- "errors"
- "fmt"
- "io"
- "net/http"
- "strconv"
- "sync"
- "time"
-
- "github.com/klauspost/compress/zstd"
- "github.com/prometheus/common/expfmt"
-
- "github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil"
- "github.com/prometheus/client_golang/prometheus"
-)
-
-const (
- contentTypeHeader = "Content-Type"
- contentEncodingHeader = "Content-Encoding"
- acceptEncodingHeader = "Accept-Encoding"
- processStartTimeHeader = "Process-Start-Time-Unix"
-)
-
-// Compression represents the content encodings handlers support for the HTTP
-// responses.
-type Compression string
-
-const (
- Identity Compression = "identity"
- Gzip Compression = "gzip"
- Zstd Compression = "zstd"
-)
-
-var defaultCompressionFormats = []Compression{Identity, Gzip, Zstd}
-
-var gzipPool = sync.Pool{
- New: func() interface{} {
- return gzip.NewWriter(nil)
- },
-}
-
-// Handler returns an http.Handler for the prometheus.DefaultGatherer, using
-// default HandlerOpts, i.e. it reports the first error as an HTTP error, it has
-// no error logging, and it applies compression if requested by the client.
-//
-// The returned http.Handler is already instrumented using the
-// InstrumentMetricHandler function and the prometheus.DefaultRegisterer. If you
-// create multiple http.Handlers by separate calls of the Handler function, the
-// metrics used for instrumentation will be shared between them, providing
-// global scrape counts.
-//
-// This function is meant to cover the bulk of basic use cases. If you are doing
-// anything that requires more customization (including using a non-default
-// Gatherer, different instrumentation, and non-default HandlerOpts), use the
-// HandlerFor function. See there for details.
-func Handler() http.Handler {
- return InstrumentMetricHandler(
- prometheus.DefaultRegisterer, HandlerFor(prometheus.DefaultGatherer, HandlerOpts{}),
- )
-}
-
-// HandlerFor returns an uninstrumented http.Handler for the provided
-// Gatherer. The behavior of the Handler is defined by the provided
-// HandlerOpts. Thus, HandlerFor is useful to create http.Handlers for custom
-// Gatherers, with non-default HandlerOpts, and/or with custom (or no)
-// instrumentation. Use the InstrumentMetricHandler function to apply the same
-// kind of instrumentation as it is used by the Handler function.
-func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
- return HandlerForTransactional(prometheus.ToTransactionalGatherer(reg), opts)
-}
-
-// HandlerForTransactional is like HandlerFor, but it uses transactional gather, which
-// can safely change in-place returned *dto.MetricFamily before call to `Gather` and after
-// call to `done` of that `Gather`.
-func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerOpts) http.Handler {
- var (
- inFlightSem chan struct{}
- errCnt = prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Name: "promhttp_metric_handler_errors_total",
- Help: "Total number of internal errors encountered by the promhttp metric handler.",
- },
- []string{"cause"},
- )
- )
-
- if opts.MaxRequestsInFlight > 0 {
- inFlightSem = make(chan struct{}, opts.MaxRequestsInFlight)
- }
- if opts.Registry != nil {
- // Initialize all possibilities that can occur below.
- errCnt.WithLabelValues("gathering")
- errCnt.WithLabelValues("encoding")
- if err := opts.Registry.Register(errCnt); err != nil {
- are := &prometheus.AlreadyRegisteredError{}
- if errors.As(err, are) {
- errCnt = are.ExistingCollector.(*prometheus.CounterVec)
- } else {
- panic(err)
- }
- }
- }
-
- // Select compression formats to offer based on default or user choice.
- var compressions []string
- if !opts.DisableCompression {
- offers := defaultCompressionFormats
- if len(opts.OfferedCompressions) > 0 {
- offers = opts.OfferedCompressions
- }
- for _, comp := range offers {
- compressions = append(compressions, string(comp))
- }
- }
-
- h := http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
- if !opts.ProcessStartTime.IsZero() {
- rsp.Header().Set(processStartTimeHeader, strconv.FormatInt(opts.ProcessStartTime.Unix(), 10))
- }
- if inFlightSem != nil {
- select {
- case inFlightSem <- struct{}{}: // All good, carry on.
- defer func() { <-inFlightSem }()
- default:
- http.Error(rsp, fmt.Sprintf(
- "Limit of concurrent requests reached (%d), try again later.", opts.MaxRequestsInFlight,
- ), http.StatusServiceUnavailable)
- return
- }
- }
- mfs, done, err := reg.Gather()
- defer done()
- if err != nil {
- if opts.ErrorLog != nil {
- opts.ErrorLog.Println("error gathering metrics:", err)
- }
- errCnt.WithLabelValues("gathering").Inc()
- switch opts.ErrorHandling {
- case PanicOnError:
- panic(err)
- case ContinueOnError:
- if len(mfs) == 0 {
- // Still report the error if no metrics have been gathered.
- httpError(rsp, err)
- return
- }
- case HTTPErrorOnError:
- httpError(rsp, err)
- return
- }
- }
-
- var contentType expfmt.Format
- if opts.EnableOpenMetrics {
- contentType = expfmt.NegotiateIncludingOpenMetrics(req.Header)
- } else {
- contentType = expfmt.Negotiate(req.Header)
- }
- rsp.Header().Set(contentTypeHeader, string(contentType))
-
- w, encodingHeader, closeWriter, err := negotiateEncodingWriter(req, rsp, compressions)
- if err != nil {
- if opts.ErrorLog != nil {
- opts.ErrorLog.Println("error getting writer", err)
- }
- w = io.Writer(rsp)
- encodingHeader = string(Identity)
- }
-
- defer closeWriter()
-
- // Set Content-Encoding only when data is compressed
- if encodingHeader != string(Identity) {
- rsp.Header().Set(contentEncodingHeader, encodingHeader)
- }
- enc := expfmt.NewEncoder(w, contentType)
-
- // handleError handles the error according to opts.ErrorHandling
- // and returns true if we have to abort after the handling.
- handleError := func(err error) bool {
- if err == nil {
- return false
- }
- if opts.ErrorLog != nil {
- opts.ErrorLog.Println("error encoding and sending metric family:", err)
- }
- errCnt.WithLabelValues("encoding").Inc()
- switch opts.ErrorHandling {
- case PanicOnError:
- panic(err)
- case HTTPErrorOnError:
- // We cannot really send an HTTP error at this
- // point because we most likely have written
- // something to rsp already. But at least we can
- // stop sending.
- return true
- }
- // Do nothing in all other cases, including ContinueOnError.
- return false
- }
-
- for _, mf := range mfs {
- if handleError(enc.Encode(mf)) {
- return
- }
- }
- if closer, ok := enc.(expfmt.Closer); ok {
- // This in particular takes care of the final "# EOF\n" line for OpenMetrics.
- if handleError(closer.Close()) {
- return
- }
- }
- })
-
- if opts.Timeout <= 0 {
- return h
- }
- return http.TimeoutHandler(h, opts.Timeout, fmt.Sprintf(
- "Exceeded configured timeout of %v.\n",
- opts.Timeout,
- ))
-}
-
-// InstrumentMetricHandler is usually used with an http.Handler returned by the
-// HandlerFor function. It instruments the provided http.Handler with two
-// metrics: A counter vector "promhttp_metric_handler_requests_total" to count
-// scrapes partitioned by HTTP status code, and a gauge
-// "promhttp_metric_handler_requests_in_flight" to track the number of
-// simultaneous scrapes. This function idempotently registers collectors for
-// both metrics with the provided Registerer. It panics if the registration
-// fails. The provided metrics are useful to see how many scrapes hit the
-// monitored target (which could be from different Prometheus servers or other
-// scrapers), and how often they overlap (which would result in more than one
-// scrape in flight at the same time). Note that the scrapes-in-flight gauge
-// will contain the scrape by which it is exposed, while the scrape counter will
-// only get incremented after the scrape is complete (as only then the status
-// code is known). For tracking scrape durations, use the
-// "scrape_duration_seconds" gauge created by the Prometheus server upon each
-// scrape.
-func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) http.Handler {
- cnt := prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Name: "promhttp_metric_handler_requests_total",
- Help: "Total number of scrapes by HTTP status code.",
- },
- []string{"code"},
- )
- // Initialize the most likely HTTP status codes.
- cnt.WithLabelValues("200")
- cnt.WithLabelValues("500")
- cnt.WithLabelValues("503")
- if err := reg.Register(cnt); err != nil {
- are := &prometheus.AlreadyRegisteredError{}
- if errors.As(err, are) {
- cnt = are.ExistingCollector.(*prometheus.CounterVec)
- } else {
- panic(err)
- }
- }
-
- gge := prometheus.NewGauge(prometheus.GaugeOpts{
- Name: "promhttp_metric_handler_requests_in_flight",
- Help: "Current number of scrapes being served.",
- })
- if err := reg.Register(gge); err != nil {
- are := &prometheus.AlreadyRegisteredError{}
- if errors.As(err, are) {
- gge = are.ExistingCollector.(prometheus.Gauge)
- } else {
- panic(err)
- }
- }
-
- return InstrumentHandlerCounter(cnt, InstrumentHandlerInFlight(gge, handler))
-}
-
-// HandlerErrorHandling defines how a Handler serving metrics will handle
-// errors.
-type HandlerErrorHandling int
-
-// These constants cause handlers serving metrics to behave as described if
-// errors are encountered.
-const (
- // Serve an HTTP status code 500 upon the first error
- // encountered. Report the error message in the body. Note that HTTP
- // errors cannot be served anymore once the beginning of a regular
- // payload has been sent. Thus, in the (unlikely) case that encoding the
- // payload into the negotiated wire format fails, serving the response
- // will simply be aborted. Set an ErrorLog in HandlerOpts to detect
- // those errors.
- HTTPErrorOnError HandlerErrorHandling = iota
- // Ignore errors and try to serve as many metrics as possible. However,
- // if no metrics can be served, serve an HTTP status code 500 and the
- // last error message in the body. Only use this in deliberate "best
- // effort" metrics collection scenarios. In this case, it is highly
- // recommended to provide other means of detecting errors: By setting an
- // ErrorLog in HandlerOpts, the errors are logged. By providing a
- // Registry in HandlerOpts, the exposed metrics include an error counter
- // "promhttp_metric_handler_errors_total", which can be used for
- // alerts.
- ContinueOnError
- // Panic upon the first error encountered (useful for "crash only" apps).
- PanicOnError
-)
-
-// Logger is the minimal interface HandlerOpts needs for logging. Note that
-// log.Logger from the standard library implements this interface, and it is
-// easy to implement by custom loggers, if they don't do so already anyway.
-type Logger interface {
- Println(v ...interface{})
-}
-
-// HandlerOpts specifies options how to serve metrics via an http.Handler. The
-// zero value of HandlerOpts is a reasonable default.
-type HandlerOpts struct {
- // ErrorLog specifies an optional Logger for errors collecting and
- // serving metrics. If nil, errors are not logged at all. Note that the
- // type of a reported error is often prometheus.MultiError, which
- // formats into a multi-line error string. If you want to avoid the
- // latter, create a Logger implementation that detects a
- // prometheus.MultiError and formats the contained errors into one line.
- ErrorLog Logger
- // ErrorHandling defines how errors are handled. Note that errors are
- // logged regardless of the configured ErrorHandling provided ErrorLog
- // is not nil.
- ErrorHandling HandlerErrorHandling
- // If Registry is not nil, it is used to register a metric
- // "promhttp_metric_handler_errors_total", partitioned by "cause". A
- // failed registration causes a panic. Note that this error counter is
- // different from the instrumentation you get from the various
- // InstrumentHandler... helpers. It counts errors that don't necessarily
- // result in a non-2xx HTTP status code. There are two typical cases:
- // (1) Encoding errors that only happen after streaming of the HTTP body
- // has already started (and the status code 200 has been sent). This
- // should only happen with custom collectors. (2) Collection errors with
- // no effect on the HTTP status code because ErrorHandling is set to
- // ContinueOnError.
- Registry prometheus.Registerer
- // DisableCompression disables the response encoding (compression) and
- // encoding negotiation. If true, the handler will
- // never compress the response, even if requested
- // by the client and the OfferedCompressions field is set.
- DisableCompression bool
- // OfferedCompressions is a set of encodings (compressions) handler will
- // try to offer when negotiating with the client. This defaults to identity, gzip
- // and zstd.
- // NOTE: If handler can't agree with the client on the encodings or
- // unsupported or empty encodings are set in OfferedCompressions,
- // handler always fallbacks to no compression (identity), for
- // compatibility reasons. In such cases ErrorLog will be used if set.
- OfferedCompressions []Compression
- // The number of concurrent HTTP requests is limited to
- // MaxRequestsInFlight. Additional requests are responded to with 503
- // Service Unavailable and a suitable message in the body. If
- // MaxRequestsInFlight is 0 or negative, no limit is applied.
- MaxRequestsInFlight int
- // If handling a request takes longer than Timeout, it is responded to
- // with 503 ServiceUnavailable and a suitable Message. No timeout is
- // applied if Timeout is 0 or negative. Note that with the current
- // implementation, reaching the timeout simply ends the HTTP requests as
- // described above (and even that only if sending of the body hasn't
- // started yet), while the bulk work of gathering all the metrics keeps
- // running in the background (with the eventual result to be thrown
- // away). Until the implementation is improved, it is recommended to
- // implement a separate timeout in potentially slow Collectors.
- Timeout time.Duration
- // If true, the experimental OpenMetrics encoding is added to the
- // possible options during content negotiation. Note that Prometheus
- // 2.5.0+ will negotiate OpenMetrics as first priority. OpenMetrics is
- // the only way to transmit exemplars. However, the move to OpenMetrics
- // is not completely transparent. Most notably, the values of "quantile"
- // labels of Summaries and "le" labels of Histograms are formatted with
- // a trailing ".0" if they would otherwise look like integer numbers
- // (which changes the identity of the resulting series on the Prometheus
- // server).
- EnableOpenMetrics bool
- // ProcessStartTime allows setting process start timevalue that will be exposed
- // with "Process-Start-Time-Unix" response header along with the metrics
- // payload. This allow callers to have efficient transformations to cumulative
- // counters (e.g. OpenTelemetry) or generally _created timestamp estimation per
- // scrape target.
- // NOTE: This feature is experimental and not covered by OpenMetrics or Prometheus
- // exposition format.
- ProcessStartTime time.Time
-}
-
-// httpError removes any content-encoding header and then calls http.Error with
-// the provided error and http.StatusInternalServerError. Error contents is
-// supposed to be uncompressed plain text. Same as with a plain http.Error, this
-// must not be called if the header or any payload has already been sent.
-func httpError(rsp http.ResponseWriter, err error) {
- rsp.Header().Del(contentEncodingHeader)
- http.Error(
- rsp,
- "An error has occurred while serving metrics:\n\n"+err.Error(),
- http.StatusInternalServerError,
- )
-}
-
-// negotiateEncodingWriter reads the Accept-Encoding header from a request and
-// selects the right compression based on an allow-list of supported
-// compressions. It returns a writer implementing the compression and an the
-// correct value that the caller can set in the response header.
-func negotiateEncodingWriter(r *http.Request, rw io.Writer, compressions []string) (_ io.Writer, encodingHeaderValue string, closeWriter func(), _ error) {
- if len(compressions) == 0 {
- return rw, string(Identity), func() {}, nil
- }
-
- // TODO(mrueg): Replace internal/github.com/gddo once https://github.com/golang/go/issues/19307 is implemented.
- selected := httputil.NegotiateContentEncoding(r, compressions)
-
- switch selected {
- case "zstd":
- // TODO(mrueg): Replace klauspost/compress with stdlib implementation once https://github.com/golang/go/issues/62513 is implemented.
- z, err := zstd.NewWriter(rw, zstd.WithEncoderLevel(zstd.SpeedFastest))
- if err != nil {
- return nil, "", func() {}, err
- }
-
- z.Reset(rw)
- return z, selected, func() { _ = z.Close() }, nil
- case "gzip":
- gz := gzipPool.Get().(*gzip.Writer)
- gz.Reset(rw)
- return gz, selected, func() { _ = gz.Close(); gzipPool.Put(gz) }, nil
- case "identity":
- // This means the content is not compressed.
- return rw, selected, func() {}, nil
- default:
- // The content encoding was not implemented yet.
- return nil, "", func() {}, fmt.Errorf("content compression format not recognized: %s. Valid formats are: %s", selected, defaultCompressionFormats)
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
deleted file mode 100644
index d3482c40c..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
- "crypto/tls"
- "net/http"
- "net/http/httptrace"
- "time"
-
- "github.com/prometheus/client_golang/prometheus"
-)
-
-// The RoundTripperFunc type is an adapter to allow the use of ordinary
-// functions as RoundTrippers. If f is a function with the appropriate
-// signature, RountTripperFunc(f) is a RoundTripper that calls f.
-type RoundTripperFunc func(req *http.Request) (*http.Response, error)
-
-// RoundTrip implements the RoundTripper interface.
-func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
- return rt(r)
-}
-
-// InstrumentRoundTripperInFlight is a middleware that wraps the provided
-// http.RoundTripper. It sets the provided prometheus.Gauge to the number of
-// requests currently handled by the wrapped http.RoundTripper.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc {
- return func(r *http.Request) (*http.Response, error) {
- gauge.Inc()
- defer gauge.Dec()
- return next.RoundTrip(r)
- }
-}
-
-// InstrumentRoundTripperCounter is a middleware that wraps the provided
-// http.RoundTripper to observe the request result with the provided CounterVec.
-// The CounterVec must have zero, one, or two non-const non-curried labels. For
-// those, the only allowed label names are "code" and "method". The function
-// panics otherwise. For the "method" label a predefined default label value set
-// is used to filter given values. Values besides predefined values will count
-// as `unknown` method.`WithExtraMethods` can be used to add more
-// methods to the set. Partitioning of the CounterVec happens by HTTP status code
-// and/or HTTP method if the respective instance label names are present in the
-// CounterVec. For unpartitioned counting, use a CounterVec with zero labels.
-//
-// If the wrapped RoundTripper panics or returns a non-nil error, the Counter
-// is not incremented.
-//
-// Use with WithExemplarFromContext to instrument the exemplars on the counter of requests.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
- rtOpts := defaultOptions()
- for _, o := range opts {
- o.apply(rtOpts)
- }
-
- // Curry the counter with dynamic labels before checking the remaining labels.
- code, method := checkLabels(counter.MustCurryWith(rtOpts.emptyDynamicLabels()))
-
- return func(r *http.Request) (*http.Response, error) {
- resp, err := next.RoundTrip(r)
- if err == nil {
- l := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)
- for label, resolve := range rtOpts.extraLabelsFromCtx {
- l[label] = resolve(resp.Request.Context())
- }
- addWithExemplar(counter.With(l), 1, rtOpts.getExemplarFn(r.Context()))
- }
- return resp, err
- }
-}
-
-// InstrumentRoundTripperDuration is a middleware that wraps the provided
-// http.RoundTripper to observe the request duration with the provided
-// ObserverVec. The ObserverVec must have zero, one, or two non-const
-// non-curried labels. For those, the only allowed label names are "code" and
-// "method". The function panics otherwise. For the "method" label a predefined
-// default label value set is used to filter given values. Values besides
-// predefined values will count as `unknown` method. `WithExtraMethods`
-// can be used to add more methods to the set. The Observe method of the Observer
-// in the ObserverVec is called with the request duration in
-// seconds. Partitioning happens by HTTP status code and/or HTTP method if the
-// respective instance label names are present in the ObserverVec. For
-// unpartitioned observations, use an ObserverVec with zero labels. Note that
-// partitioning of Histograms is expensive and should be used judiciously.
-//
-// If the wrapped RoundTripper panics or returns a non-nil error, no values are
-// reported.
-//
-// Use with WithExemplarFromContext to instrument the exemplars on the duration histograms.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
- rtOpts := defaultOptions()
- for _, o := range opts {
- o.apply(rtOpts)
- }
-
- // Curry the observer with dynamic labels before checking the remaining labels.
- code, method := checkLabels(obs.MustCurryWith(rtOpts.emptyDynamicLabels()))
-
- return func(r *http.Request) (*http.Response, error) {
- start := time.Now()
- resp, err := next.RoundTrip(r)
- if err == nil {
- l := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)
- for label, resolve := range rtOpts.extraLabelsFromCtx {
- l[label] = resolve(resp.Request.Context())
- }
- observeWithExemplar(obs.With(l), time.Since(start).Seconds(), rtOpts.getExemplarFn(r.Context()))
- }
- return resp, err
- }
-}
-
-// InstrumentTrace is used to offer flexibility in instrumenting the available
-// httptrace.ClientTrace hook functions. Each function is passed a float64
-// representing the time in seconds since the start of the http request. A user
-// may choose to use separately buckets Histograms, or implement custom
-// instance labels on a per function basis.
-type InstrumentTrace struct {
- GotConn func(float64)
- PutIdleConn func(float64)
- GotFirstResponseByte func(float64)
- Got100Continue func(float64)
- DNSStart func(float64)
- DNSDone func(float64)
- ConnectStart func(float64)
- ConnectDone func(float64)
- TLSHandshakeStart func(float64)
- TLSHandshakeDone func(float64)
- WroteHeaders func(float64)
- Wait100Continue func(float64)
- WroteRequest func(float64)
-}
-
-// InstrumentRoundTripperTrace is a middleware that wraps the provided
-// RoundTripper and reports times to hook functions provided in the
-// InstrumentTrace struct. Hook functions that are not present in the provided
-// InstrumentTrace struct are ignored. Times reported to the hook functions are
-// time since the start of the request. Only with Go1.9+, those times are
-// guaranteed to never be negative. (Earlier Go versions are not using a
-// monotonic clock.) Note that partitioning of Histograms is expensive and
-// should be used judiciously.
-//
-// For hook functions that receive an error as an argument, no observations are
-// made in the event of a non-nil error value.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc {
- return func(r *http.Request) (*http.Response, error) {
- start := time.Now()
-
- trace := &httptrace.ClientTrace{
- GotConn: func(_ httptrace.GotConnInfo) {
- if it.GotConn != nil {
- it.GotConn(time.Since(start).Seconds())
- }
- },
- PutIdleConn: func(err error) {
- if err != nil {
- return
- }
- if it.PutIdleConn != nil {
- it.PutIdleConn(time.Since(start).Seconds())
- }
- },
- DNSStart: func(_ httptrace.DNSStartInfo) {
- if it.DNSStart != nil {
- it.DNSStart(time.Since(start).Seconds())
- }
- },
- DNSDone: func(_ httptrace.DNSDoneInfo) {
- if it.DNSDone != nil {
- it.DNSDone(time.Since(start).Seconds())
- }
- },
- ConnectStart: func(_, _ string) {
- if it.ConnectStart != nil {
- it.ConnectStart(time.Since(start).Seconds())
- }
- },
- ConnectDone: func(_, _ string, err error) {
- if err != nil {
- return
- }
- if it.ConnectDone != nil {
- it.ConnectDone(time.Since(start).Seconds())
- }
- },
- GotFirstResponseByte: func() {
- if it.GotFirstResponseByte != nil {
- it.GotFirstResponseByte(time.Since(start).Seconds())
- }
- },
- Got100Continue: func() {
- if it.Got100Continue != nil {
- it.Got100Continue(time.Since(start).Seconds())
- }
- },
- TLSHandshakeStart: func() {
- if it.TLSHandshakeStart != nil {
- it.TLSHandshakeStart(time.Since(start).Seconds())
- }
- },
- TLSHandshakeDone: func(_ tls.ConnectionState, err error) {
- if err != nil {
- return
- }
- if it.TLSHandshakeDone != nil {
- it.TLSHandshakeDone(time.Since(start).Seconds())
- }
- },
- WroteHeaders: func() {
- if it.WroteHeaders != nil {
- it.WroteHeaders(time.Since(start).Seconds())
- }
- },
- Wait100Continue: func() {
- if it.Wait100Continue != nil {
- it.Wait100Continue(time.Since(start).Seconds())
- }
- },
- WroteRequest: func(_ httptrace.WroteRequestInfo) {
- if it.WroteRequest != nil {
- it.WroteRequest(time.Since(start).Seconds())
- }
- },
- }
- r = r.WithContext(httptrace.WithClientTrace(r.Context(), trace))
-
- return next.RoundTrip(r)
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
deleted file mode 100644
index 356edb786..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
+++ /dev/null
@@ -1,576 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
- "errors"
- "net/http"
- "strconv"
- "strings"
- "time"
-
- dto "github.com/prometheus/client_model/go"
-
- "github.com/prometheus/client_golang/prometheus"
-)
-
-// magicString is used for the hacky label test in checkLabels. Remove once fixed.
-const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa"
-
-// observeWithExemplar is a wrapper for [prometheus.ExemplarAdder.ExemplarObserver],
-// which falls back to [prometheus.Observer.Observe] if no labels are provided.
-func observeWithExemplar(obs prometheus.Observer, val float64, labels map[string]string) {
- if labels == nil {
- obs.Observe(val)
- return
- }
- obs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels)
-}
-
-// addWithExemplar is a wrapper for [prometheus.ExemplarAdder.AddWithExemplar],
-// which falls back to [prometheus.Counter.Add] if no labels are provided.
-func addWithExemplar(obs prometheus.Counter, val float64, labels map[string]string) {
- if labels == nil {
- obs.Add(val)
- return
- }
- obs.(prometheus.ExemplarAdder).AddWithExemplar(val, labels)
-}
-
-// InstrumentHandlerInFlight is a middleware that wraps the provided
-// http.Handler. It sets the provided prometheus.Gauge to the number of
-// requests currently handled by the wrapped http.Handler.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- g.Inc()
- defer g.Dec()
- next.ServeHTTP(w, r)
- })
-}
-
-// InstrumentHandlerDuration is a middleware that wraps the provided
-// http.Handler to observe the request duration with the provided ObserverVec.
-// The ObserverVec must have valid metric and label names and must have zero,
-// one, or two non-const non-curried labels. For those, the only allowed label
-// names are "code" and "method". The function panics otherwise. For the "method"
-// label a predefined default label value set is used to filter given values.
-// Values besides predefined values will count as `unknown` method.
-// `WithExtraMethods` can be used to add more methods to the set. The Observe
-// method of the Observer in the ObserverVec is called with the request duration
-// in seconds. Partitioning happens by HTTP status code and/or HTTP method if
-// the respective instance label names are present in the ObserverVec. For
-// unpartitioned observations, use an ObserverVec with zero labels. Note that
-// partitioning of Histograms is expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
- hOpts := defaultOptions()
- for _, o := range opts {
- o.apply(hOpts)
- }
-
- // Curry the observer with dynamic labels before checking the remaining labels.
- code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels()))
-
- if code {
- return func(w http.ResponseWriter, r *http.Request) {
- now := time.Now()
- d := newDelegator(w, nil)
- next.ServeHTTP(d, r)
-
- l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)
- for label, resolve := range hOpts.extraLabelsFromCtx {
- l[label] = resolve(r.Context())
- }
- observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context()))
- }
- }
-
- return func(w http.ResponseWriter, r *http.Request) {
- now := time.Now()
- next.ServeHTTP(w, r)
- l := labels(code, method, r.Method, 0, hOpts.extraMethods...)
- for label, resolve := range hOpts.extraLabelsFromCtx {
- l[label] = resolve(r.Context())
- }
- observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context()))
- }
-}
-
-// InstrumentHandlerCounter is a middleware that wraps the provided http.Handler
-// to observe the request result with the provided CounterVec. The CounterVec
-// must have valid metric and label names and must have zero, one, or two
-// non-const non-curried labels. For those, the only allowed label names are
-// "code" and "method". The function panics otherwise. For the "method"
-// label a predefined default label value set is used to filter given values.
-// Values besides predefined values will count as `unknown` method.
-// `WithExtraMethods` can be used to add more methods to the set. Partitioning of the
-// CounterVec happens by HTTP status code and/or HTTP method if the respective
-// instance label names are present in the CounterVec. For unpartitioned
-// counting, use a CounterVec with zero labels.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, the Counter is not incremented.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, opts ...Option) http.HandlerFunc {
- hOpts := defaultOptions()
- for _, o := range opts {
- o.apply(hOpts)
- }
-
- // Curry the counter with dynamic labels before checking the remaining labels.
- code, method := checkLabels(counter.MustCurryWith(hOpts.emptyDynamicLabels()))
-
- if code {
- return func(w http.ResponseWriter, r *http.Request) {
- d := newDelegator(w, nil)
- next.ServeHTTP(d, r)
-
- l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)
- for label, resolve := range hOpts.extraLabelsFromCtx {
- l[label] = resolve(r.Context())
- }
- addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context()))
- }
- }
-
- return func(w http.ResponseWriter, r *http.Request) {
- next.ServeHTTP(w, r)
-
- l := labels(code, method, r.Method, 0, hOpts.extraMethods...)
- for label, resolve := range hOpts.extraLabelsFromCtx {
- l[label] = resolve(r.Context())
- }
- addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context()))
- }
-}
-
-// InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided
-// http.Handler to observe with the provided ObserverVec the request duration
-// until the response headers are written. The ObserverVec must have valid
-// metric and label names and must have zero, one, or two non-const non-curried
-// labels. For those, the only allowed label names are "code" and "method". The
-// function panics otherwise. For the "method" label a predefined default label
-// value set is used to filter given values. Values besides predefined values
-// will count as `unknown` method.`WithExtraMethods` can be used to add more
-// methods to the set. The Observe method of the Observer in the
-// ObserverVec is called with the request duration in seconds. Partitioning
-// happens by HTTP status code and/or HTTP method if the respective instance
-// label names are present in the ObserverVec. For unpartitioned observations,
-// use an ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped Handler panics before calling WriteHeader, no value is
-// reported.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
- hOpts := defaultOptions()
- for _, o := range opts {
- o.apply(hOpts)
- }
-
- // Curry the observer with dynamic labels before checking the remaining labels.
- code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels()))
-
- return func(w http.ResponseWriter, r *http.Request) {
- now := time.Now()
- d := newDelegator(w, func(status int) {
- l := labels(code, method, r.Method, status, hOpts.extraMethods...)
- for label, resolve := range hOpts.extraLabelsFromCtx {
- l[label] = resolve(r.Context())
- }
- observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context()))
- })
- next.ServeHTTP(d, r)
- }
-}
-
-// InstrumentHandlerRequestSize is a middleware that wraps the provided
-// http.Handler to observe the request size with the provided ObserverVec. The
-// ObserverVec must have valid metric and label names and must have zero, one,
-// or two non-const non-curried labels. For those, the only allowed label names
-// are "code" and "method". The function panics otherwise. For the "method"
-// label a predefined default label value set is used to filter given values.
-// Values besides predefined values will count as `unknown` method.
-// `WithExtraMethods` can be used to add more methods to the set. The Observe
-// method of the Observer in the ObserverVec is called with the request size in
-// bytes. Partitioning happens by HTTP status code and/or HTTP method if the
-// respective instance label names are present in the ObserverVec. For
-// unpartitioned observations, use an ObserverVec with zero labels. Note that
-// partitioning of Histograms is expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
- hOpts := defaultOptions()
- for _, o := range opts {
- o.apply(hOpts)
- }
-
- // Curry the observer with dynamic labels before checking the remaining labels.
- code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels()))
-
- if code {
- return func(w http.ResponseWriter, r *http.Request) {
- d := newDelegator(w, nil)
- next.ServeHTTP(d, r)
- size := computeApproximateRequestSize(r)
-
- l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)
- for label, resolve := range hOpts.extraLabelsFromCtx {
- l[label] = resolve(r.Context())
- }
- observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context()))
- }
- }
-
- return func(w http.ResponseWriter, r *http.Request) {
- next.ServeHTTP(w, r)
- size := computeApproximateRequestSize(r)
-
- l := labels(code, method, r.Method, 0, hOpts.extraMethods...)
- for label, resolve := range hOpts.extraLabelsFromCtx {
- l[label] = resolve(r.Context())
- }
- observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context()))
- }
-}
-
-// InstrumentHandlerResponseSize is a middleware that wraps the provided
-// http.Handler to observe the response size with the provided ObserverVec. The
-// ObserverVec must have valid metric and label names and must have zero, one,
-// or two non-const non-curried labels. For those, the only allowed label names
-// are "code" and "method". The function panics otherwise. For the "method"
-// label a predefined default label value set is used to filter given values.
-// Values besides predefined values will count as `unknown` method.
-// `WithExtraMethods` can be used to add more methods to the set. The Observe
-// method of the Observer in the ObserverVec is called with the response size in
-// bytes. Partitioning happens by HTTP status code and/or HTTP method if the
-// respective instance label names are present in the ObserverVec. For
-// unpartitioned observations, use an ObserverVec with zero labels. Note that
-// partitioning of Histograms is expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.Handler {
- hOpts := defaultOptions()
- for _, o := range opts {
- o.apply(hOpts)
- }
-
- // Curry the observer with dynamic labels before checking the remaining labels.
- code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels()))
-
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- d := newDelegator(w, nil)
- next.ServeHTTP(d, r)
-
- l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)
- for label, resolve := range hOpts.extraLabelsFromCtx {
- l[label] = resolve(r.Context())
- }
- observeWithExemplar(obs.With(l), float64(d.Written()), hOpts.getExemplarFn(r.Context()))
- })
-}
-
-// checkLabels returns whether the provided Collector has a non-const,
-// non-curried label named "code" and/or "method". It panics if the provided
-// Collector does not have a Desc or has more than one Desc or its Desc is
-// invalid. It also panics if the Collector has any non-const, non-curried
-// labels that are not named "code" or "method".
-func checkLabels(c prometheus.Collector) (code, method bool) {
- // TODO(beorn7): Remove this hacky way to check for instance labels
- // once Descriptors can have their dimensionality queried.
- var (
- desc *prometheus.Desc
- m prometheus.Metric
- pm dto.Metric
- lvs []string
- )
-
- // Get the Desc from the Collector.
- descc := make(chan *prometheus.Desc, 1)
- c.Describe(descc)
-
- select {
- case desc = <-descc:
- default:
- panic("no description provided by collector")
- }
- select {
- case <-descc:
- panic("more than one description provided by collector")
- default:
- }
-
- close(descc)
-
- // Make sure the Collector has a valid Desc by registering it with a
- // temporary registry.
- prometheus.NewRegistry().MustRegister(c)
-
- // Create a ConstMetric with the Desc. Since we don't know how many
- // variable labels there are, try for as long as it needs.
- for err := errors.New("dummy"); err != nil; lvs = append(lvs, magicString) {
- m, err = prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, lvs...)
- }
-
- // Write out the metric into a proto message and look at the labels.
- // If the value is not the magicString, it is a constLabel, which doesn't interest us.
- // If the label is curried, it doesn't interest us.
- // In all other cases, only "code" or "method" is allowed.
- if err := m.Write(&pm); err != nil {
- panic("error checking metric for labels")
- }
- for _, label := range pm.Label {
- name, value := label.GetName(), label.GetValue()
- if value != magicString || isLabelCurried(c, name) {
- continue
- }
- switch name {
- case "code":
- code = true
- case "method":
- method = true
- default:
- panic("metric partitioned with non-supported labels")
- }
- }
- return
-}
-
-func isLabelCurried(c prometheus.Collector, label string) bool {
- // This is even hackier than the label test above.
- // We essentially try to curry again and see if it works.
- // But for that, we need to type-convert to the two
- // types we use here, ObserverVec or *CounterVec.
- switch v := c.(type) {
- case *prometheus.CounterVec:
- if _, err := v.CurryWith(prometheus.Labels{label: "dummy"}); err == nil {
- return false
- }
- case prometheus.ObserverVec:
- if _, err := v.CurryWith(prometheus.Labels{label: "dummy"}); err == nil {
- return false
- }
- default:
- panic("unsupported metric vec type")
- }
- return true
-}
-
-func labels(code, method bool, reqMethod string, status int, extraMethods ...string) prometheus.Labels {
- labels := prometheus.Labels{}
-
- if !(code || method) {
- return labels
- }
-
- if code {
- labels["code"] = sanitizeCode(status)
- }
- if method {
- labels["method"] = sanitizeMethod(reqMethod, extraMethods...)
- }
-
- return labels
-}
-
-func computeApproximateRequestSize(r *http.Request) int {
- s := 0
- if r.URL != nil {
- s += len(r.URL.String())
- }
-
- s += len(r.Method)
- s += len(r.Proto)
- for name, values := range r.Header {
- s += len(name)
- for _, value := range values {
- s += len(value)
- }
- }
- s += len(r.Host)
-
- // N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
-
- if r.ContentLength != -1 {
- s += int(r.ContentLength)
- }
- return s
-}
-
-// If the wrapped http.Handler has a known method, it will be sanitized and returned.
-// Otherwise, "unknown" will be returned. The known method list can be extended
-// as needed by using extraMethods parameter.
-func sanitizeMethod(m string, extraMethods ...string) string {
- // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for
- // the methods chosen as default.
- switch m {
- case "GET", "get":
- return "get"
- case "PUT", "put":
- return "put"
- case "HEAD", "head":
- return "head"
- case "POST", "post":
- return "post"
- case "DELETE", "delete":
- return "delete"
- case "CONNECT", "connect":
- return "connect"
- case "OPTIONS", "options":
- return "options"
- case "NOTIFY", "notify":
- return "notify"
- case "TRACE", "trace":
- return "trace"
- case "PATCH", "patch":
- return "patch"
- default:
- for _, method := range extraMethods {
- if strings.EqualFold(m, method) {
- return strings.ToLower(m)
- }
- }
- return "unknown"
- }
-}
-
-// If the wrapped http.Handler has not set a status code, i.e. the value is
-// currently 0, sanitizeCode will return 200, for consistency with behavior in
-// the stdlib.
-func sanitizeCode(s int) string {
- // See for accepted codes https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
- switch s {
- case 100:
- return "100"
- case 101:
- return "101"
-
- case 200, 0:
- return "200"
- case 201:
- return "201"
- case 202:
- return "202"
- case 203:
- return "203"
- case 204:
- return "204"
- case 205:
- return "205"
- case 206:
- return "206"
-
- case 300:
- return "300"
- case 301:
- return "301"
- case 302:
- return "302"
- case 304:
- return "304"
- case 305:
- return "305"
- case 307:
- return "307"
-
- case 400:
- return "400"
- case 401:
- return "401"
- case 402:
- return "402"
- case 403:
- return "403"
- case 404:
- return "404"
- case 405:
- return "405"
- case 406:
- return "406"
- case 407:
- return "407"
- case 408:
- return "408"
- case 409:
- return "409"
- case 410:
- return "410"
- case 411:
- return "411"
- case 412:
- return "412"
- case 413:
- return "413"
- case 414:
- return "414"
- case 415:
- return "415"
- case 416:
- return "416"
- case 417:
- return "417"
- case 418:
- return "418"
-
- case 500:
- return "500"
- case 501:
- return "501"
- case 502:
- return "502"
- case 503:
- return "503"
- case 504:
- return "504"
- case 505:
- return "505"
-
- case 428:
- return "428"
- case 429:
- return "429"
- case 431:
- return "431"
- case 511:
- return "511"
-
- default:
- if s >= 100 && s <= 599 {
- return strconv.Itoa(s)
- }
- return "unknown"
- }
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
deleted file mode 100644
index 5d4383aa1..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2022 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
- "context"
-
- "github.com/prometheus/client_golang/prometheus"
-)
-
-// Option are used to configure both handler (middleware) or round tripper.
-type Option interface {
- apply(*options)
-}
-
-// LabelValueFromCtx are used to compute the label value from request context.
-// Context can be filled with values from request through middleware.
-type LabelValueFromCtx func(ctx context.Context) string
-
-// options store options for both a handler or round tripper.
-type options struct {
- extraMethods []string
- getExemplarFn func(requestCtx context.Context) prometheus.Labels
- extraLabelsFromCtx map[string]LabelValueFromCtx
-}
-
-func defaultOptions() *options {
- return &options{
- getExemplarFn: func(ctx context.Context) prometheus.Labels { return nil },
- extraLabelsFromCtx: map[string]LabelValueFromCtx{},
- }
-}
-
-func (o *options) emptyDynamicLabels() prometheus.Labels {
- labels := prometheus.Labels{}
-
- for label := range o.extraLabelsFromCtx {
- labels[label] = ""
- }
-
- return labels
-}
-
-type optionApplyFunc func(*options)
-
-func (o optionApplyFunc) apply(opt *options) { o(opt) }
-
-// WithExtraMethods adds additional HTTP methods to the list of allowed methods.
-// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for the default list.
-//
-// See the example for ExampleInstrumentHandlerWithExtraMethods for example usage.
-func WithExtraMethods(methods ...string) Option {
- return optionApplyFunc(func(o *options) {
- o.extraMethods = methods
- })
-}
-
-// WithExemplarFromContext allows to inject function that will get exemplar from context that will be put to counter and histogram metrics.
-// If the function returns nil labels or the metric does not support exemplars, no exemplar will be added (noop), but
-// metric will continue to observe/increment.
-func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option {
- return optionApplyFunc(func(o *options) {
- o.getExemplarFn = getExemplarFn
- })
-}
-
-// WithLabelFromCtx registers a label for dynamic resolution with access to context.
-// See the example for ExampleInstrumentHandlerWithLabelResolver for example usage
-func WithLabelFromCtx(name string, valueFn LabelValueFromCtx) Option {
- return optionApplyFunc(func(o *options) {
- o.extraLabelsFromCtx[name] = valueFn
- })
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go
deleted file mode 100644
index c6fd2f58b..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go
+++ /dev/null
@@ -1,1076 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "bytes"
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "unicode/utf8"
-
- "github.com/prometheus/client_golang/prometheus/internal"
-
- "github.com/cespare/xxhash/v2"
- dto "github.com/prometheus/client_model/go"
- "github.com/prometheus/common/expfmt"
- "google.golang.org/protobuf/proto"
-)
-
-const (
- // Capacity for the channel to collect metrics and descriptors.
- capMetricChan = 1000
- capDescChan = 10
-)
-
-// DefaultRegisterer and DefaultGatherer are the implementations of the
-// Registerer and Gatherer interface a number of convenience functions in this
-// package act on. Initially, both variables point to the same Registry, which
-// has a process collector (currently on Linux only, see NewProcessCollector)
-// and a Go collector (see NewGoCollector, in particular the note about
-// stop-the-world implication with Go versions older than 1.9) already
-// registered. This approach to keep default instances as global state mirrors
-// the approach of other packages in the Go standard library. Note that there
-// are caveats. Change the variables with caution and only if you understand the
-// consequences. Users who want to avoid global state altogether should not use
-// the convenience functions and act on custom instances instead.
-var (
- defaultRegistry = NewRegistry()
- DefaultRegisterer Registerer = defaultRegistry
- DefaultGatherer Gatherer = defaultRegistry
-)
-
-func init() {
- MustRegister(NewProcessCollector(ProcessCollectorOpts{}))
- MustRegister(NewGoCollector())
-}
-
-// NewRegistry creates a new vanilla Registry without any Collectors
-// pre-registered.
-func NewRegistry() *Registry {
- return &Registry{
- collectorsByID: map[uint64]Collector{},
- descIDs: map[uint64]struct{}{},
- dimHashesByName: map[string]uint64{},
- }
-}
-
-// NewPedanticRegistry returns a registry that checks during collection if each
-// collected Metric is consistent with its reported Desc, and if the Desc has
-// actually been registered with the registry. Unchecked Collectors (those whose
-// Describe method does not yield any descriptors) are excluded from the check.
-//
-// Usually, a Registry will be happy as long as the union of all collected
-// Metrics is consistent and valid even if some metrics are not consistent with
-// their own Desc or a Desc provided by their registered Collector. Well-behaved
-// Collectors and Metrics will only provide consistent Descs. This Registry is
-// useful to test the implementation of Collectors and Metrics.
-func NewPedanticRegistry() *Registry {
- r := NewRegistry()
- r.pedanticChecksEnabled = true
- return r
-}
-
-// Registerer is the interface for the part of a registry in charge of
-// registering and unregistering. Users of custom registries should use
-// Registerer as type for registration purposes (rather than the Registry type
-// directly). In that way, they are free to use custom Registerer implementation
-// (e.g. for testing purposes).
-type Registerer interface {
- // Register registers a new Collector to be included in metrics
- // collection. It returns an error if the descriptors provided by the
- // Collector are invalid or if they — in combination with descriptors of
- // already registered Collectors — do not fulfill the consistency and
- // uniqueness criteria described in the documentation of metric.Desc.
- //
- // If the provided Collector is equal to a Collector already registered
- // (which includes the case of re-registering the same Collector), the
- // returned error is an instance of AlreadyRegisteredError, which
- // contains the previously registered Collector.
- //
- // A Collector whose Describe method does not yield any Desc is treated
- // as unchecked. Registration will always succeed. No check for
- // re-registering (see previous paragraph) is performed. Thus, the
- // caller is responsible for not double-registering the same unchecked
- // Collector, and for providing a Collector that will not cause
- // inconsistent metrics on collection. (This would lead to scrape
- // errors.)
- Register(Collector) error
- // MustRegister works like Register but registers any number of
- // Collectors and panics upon the first registration that causes an
- // error.
- MustRegister(...Collector)
- // Unregister unregisters the Collector that equals the Collector passed
- // in as an argument. (Two Collectors are considered equal if their
- // Describe method yields the same set of descriptors.) The function
- // returns whether a Collector was unregistered. Note that an unchecked
- // Collector cannot be unregistered (as its Describe method does not
- // yield any descriptor).
- //
- // Note that even after unregistering, it will not be possible to
- // register a new Collector that is inconsistent with the unregistered
- // Collector, e.g. a Collector collecting metrics with the same name but
- // a different help string. The rationale here is that the same registry
- // instance must only collect consistent metrics throughout its
- // lifetime.
- Unregister(Collector) bool
-}
-
-// Gatherer is the interface for the part of a registry in charge of gathering
-// the collected metrics into a number of MetricFamilies. The Gatherer interface
-// comes with the same general implication as described for the Registerer
-// interface.
-type Gatherer interface {
- // Gather calls the Collect method of the registered Collectors and then
- // gathers the collected metrics into a lexicographically sorted slice
- // of uniquely named MetricFamily protobufs. Gather ensures that the
- // returned slice is valid and self-consistent so that it can be used
- // for valid exposition. As an exception to the strict consistency
- // requirements described for metric.Desc, Gather will tolerate
- // different sets of label names for metrics of the same metric family.
- //
- // Even if an error occurs, Gather attempts to gather as many metrics as
- // possible. Hence, if a non-nil error is returned, the returned
- // MetricFamily slice could be nil (in case of a fatal error that
- // prevented any meaningful metric collection) or contain a number of
- // MetricFamily protobufs, some of which might be incomplete, and some
- // might be missing altogether. The returned error (which might be a
- // MultiError) explains the details. Note that this is mostly useful for
- // debugging purposes. If the gathered protobufs are to be used for
- // exposition in actual monitoring, it is almost always better to not
- // expose an incomplete result and instead disregard the returned
- // MetricFamily protobufs in case the returned error is non-nil.
- Gather() ([]*dto.MetricFamily, error)
-}
-
-// Register registers the provided Collector with the DefaultRegisterer.
-//
-// Register is a shortcut for DefaultRegisterer.Register(c). See there for more
-// details.
-func Register(c Collector) error {
- return DefaultRegisterer.Register(c)
-}
-
-// MustRegister registers the provided Collectors with the DefaultRegisterer and
-// panics if any error occurs.
-//
-// MustRegister is a shortcut for DefaultRegisterer.MustRegister(cs...). See
-// there for more details.
-func MustRegister(cs ...Collector) {
- DefaultRegisterer.MustRegister(cs...)
-}
-
-// Unregister removes the registration of the provided Collector from the
-// DefaultRegisterer.
-//
-// Unregister is a shortcut for DefaultRegisterer.Unregister(c). See there for
-// more details.
-func Unregister(c Collector) bool {
- return DefaultRegisterer.Unregister(c)
-}
-
-// GathererFunc turns a function into a Gatherer.
-type GathererFunc func() ([]*dto.MetricFamily, error)
-
-// Gather implements Gatherer.
-func (gf GathererFunc) Gather() ([]*dto.MetricFamily, error) {
- return gf()
-}
-
-// AlreadyRegisteredError is returned by the Register method if the Collector to
-// be registered has already been registered before, or a different Collector
-// that collects the same metrics has been registered before. Registration fails
-// in that case, but you can detect from the kind of error what has
-// happened. The error contains fields for the existing Collector and the
-// (rejected) new Collector that equals the existing one. This can be used to
-// find out if an equal Collector has been registered before and switch over to
-// using the old one, as demonstrated in the example.
-type AlreadyRegisteredError struct {
- ExistingCollector, NewCollector Collector
-}
-
-func (err AlreadyRegisteredError) Error() string {
- return "duplicate metrics collector registration attempted"
-}
-
-// MultiError is a slice of errors implementing the error interface. It is used
-// by a Gatherer to report multiple errors during MetricFamily gathering.
-type MultiError []error
-
-// Error formats the contained errors as a bullet point list, preceded by the
-// total number of errors. Note that this results in a multi-line string.
-func (errs MultiError) Error() string {
- if len(errs) == 0 {
- return ""
- }
- buf := &bytes.Buffer{}
- fmt.Fprintf(buf, "%d error(s) occurred:", len(errs))
- for _, err := range errs {
- fmt.Fprintf(buf, "\n* %s", err)
- }
- return buf.String()
-}
-
-// Append appends the provided error if it is not nil.
-func (errs *MultiError) Append(err error) {
- if err != nil {
- *errs = append(*errs, err)
- }
-}
-
-// MaybeUnwrap returns nil if len(errs) is 0. It returns the first and only
-// contained error as error if len(errs is 1). In all other cases, it returns
-// the MultiError directly. This is helpful for returning a MultiError in a way
-// that only uses the MultiError if needed.
-func (errs MultiError) MaybeUnwrap() error {
- switch len(errs) {
- case 0:
- return nil
- case 1:
- return errs[0]
- default:
- return errs
- }
-}
-
-// Registry registers Prometheus collectors, collects their metrics, and gathers
-// them into MetricFamilies for exposition. It implements Registerer, Gatherer,
-// and Collector. The zero value is not usable. Create instances with
-// NewRegistry or NewPedanticRegistry.
-//
-// Registry implements Collector to allow it to be used for creating groups of
-// metrics. See the Grouping example for how this can be done.
-type Registry struct {
- mtx sync.RWMutex
- collectorsByID map[uint64]Collector // ID is a hash of the descIDs.
- descIDs map[uint64]struct{}
- dimHashesByName map[string]uint64
- uncheckedCollectors []Collector
- pedanticChecksEnabled bool
-}
-
-// Register implements Registerer.
-func (r *Registry) Register(c Collector) error {
- var (
- descChan = make(chan *Desc, capDescChan)
- newDescIDs = map[uint64]struct{}{}
- newDimHashesByName = map[string]uint64{}
- collectorID uint64 // All desc IDs XOR'd together.
- duplicateDescErr error
- )
- go func() {
- c.Describe(descChan)
- close(descChan)
- }()
- r.mtx.Lock()
- defer func() {
- // Drain channel in case of premature return to not leak a goroutine.
- for range descChan {
- }
- r.mtx.Unlock()
- }()
- // Conduct various tests...
- for desc := range descChan {
-
- // Is the descriptor valid at all?
- if desc.err != nil {
- return fmt.Errorf("descriptor %s is invalid: %w", desc, desc.err)
- }
-
- // Is the descID unique?
- // (In other words: Is the fqName + constLabel combination unique?)
- if _, exists := r.descIDs[desc.id]; exists {
- duplicateDescErr = fmt.Errorf("descriptor %s already exists with the same fully-qualified name and const label values", desc)
- }
- // If it is not a duplicate desc in this collector, XOR it to
- // the collectorID. (We allow duplicate descs within the same
- // collector, but their existence must be a no-op.)
- if _, exists := newDescIDs[desc.id]; !exists {
- newDescIDs[desc.id] = struct{}{}
- collectorID ^= desc.id
- }
-
- // Are all the label names and the help string consistent with
- // previous descriptors of the same name?
- // First check existing descriptors...
- if dimHash, exists := r.dimHashesByName[desc.fqName]; exists {
- if dimHash != desc.dimHash {
- return fmt.Errorf("a previously registered descriptor with the same fully-qualified name as %s has different label names or a different help string", desc)
- }
- continue
- }
-
- // ...then check the new descriptors already seen.
- if dimHash, exists := newDimHashesByName[desc.fqName]; exists {
- if dimHash != desc.dimHash {
- return fmt.Errorf("descriptors reported by collector have inconsistent label names or help strings for the same fully-qualified name, offender is %s", desc)
- }
- continue
- }
- newDimHashesByName[desc.fqName] = desc.dimHash
- }
- // A Collector yielding no Desc at all is considered unchecked.
- if len(newDescIDs) == 0 {
- r.uncheckedCollectors = append(r.uncheckedCollectors, c)
- return nil
- }
- if existing, exists := r.collectorsByID[collectorID]; exists {
- switch e := existing.(type) {
- case *wrappingCollector:
- return AlreadyRegisteredError{
- ExistingCollector: e.unwrapRecursively(),
- NewCollector: c,
- }
- default:
- return AlreadyRegisteredError{
- ExistingCollector: e,
- NewCollector: c,
- }
- }
- }
- // If the collectorID is new, but at least one of the descs existed
- // before, we are in trouble.
- if duplicateDescErr != nil {
- return duplicateDescErr
- }
-
- // Only after all tests have passed, actually register.
- r.collectorsByID[collectorID] = c
- for hash := range newDescIDs {
- r.descIDs[hash] = struct{}{}
- }
- for name, dimHash := range newDimHashesByName {
- r.dimHashesByName[name] = dimHash
- }
- return nil
-}
-
-// Unregister implements Registerer.
-func (r *Registry) Unregister(c Collector) bool {
- var (
- descChan = make(chan *Desc, capDescChan)
- descIDs = map[uint64]struct{}{}
- collectorID uint64 // All desc IDs XOR'd together.
- )
- go func() {
- c.Describe(descChan)
- close(descChan)
- }()
- for desc := range descChan {
- if _, exists := descIDs[desc.id]; !exists {
- collectorID ^= desc.id
- descIDs[desc.id] = struct{}{}
- }
- }
-
- r.mtx.RLock()
- if _, exists := r.collectorsByID[collectorID]; !exists {
- r.mtx.RUnlock()
- return false
- }
- r.mtx.RUnlock()
-
- r.mtx.Lock()
- defer r.mtx.Unlock()
-
- delete(r.collectorsByID, collectorID)
- for id := range descIDs {
- delete(r.descIDs, id)
- }
- // dimHashesByName is left untouched as those must be consistent
- // throughout the lifetime of a program.
- return true
-}
-
-// MustRegister implements Registerer.
-func (r *Registry) MustRegister(cs ...Collector) {
- for _, c := range cs {
- if err := r.Register(c); err != nil {
- panic(err)
- }
- }
-}
-
-// Gather implements Gatherer.
-func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
- r.mtx.RLock()
-
- if len(r.collectorsByID) == 0 && len(r.uncheckedCollectors) == 0 {
- // Fast path.
- r.mtx.RUnlock()
- return nil, nil
- }
-
- var (
- checkedMetricChan = make(chan Metric, capMetricChan)
- uncheckedMetricChan = make(chan Metric, capMetricChan)
- metricHashes = map[uint64]struct{}{}
- wg sync.WaitGroup
- errs MultiError // The collected errors to return in the end.
- registeredDescIDs map[uint64]struct{} // Only used for pedantic checks
- )
-
- goroutineBudget := len(r.collectorsByID) + len(r.uncheckedCollectors)
- metricFamiliesByName := make(map[string]*dto.MetricFamily, len(r.dimHashesByName))
- checkedCollectors := make(chan Collector, len(r.collectorsByID))
- uncheckedCollectors := make(chan Collector, len(r.uncheckedCollectors))
- for _, collector := range r.collectorsByID {
- checkedCollectors <- collector
- }
- for _, collector := range r.uncheckedCollectors {
- uncheckedCollectors <- collector
- }
- // In case pedantic checks are enabled, we have to copy the map before
- // giving up the RLock.
- if r.pedanticChecksEnabled {
- registeredDescIDs = make(map[uint64]struct{}, len(r.descIDs))
- for id := range r.descIDs {
- registeredDescIDs[id] = struct{}{}
- }
- }
- r.mtx.RUnlock()
-
- wg.Add(goroutineBudget)
-
- collectWorker := func() {
- for {
- select {
- case collector := <-checkedCollectors:
- collector.Collect(checkedMetricChan)
- case collector := <-uncheckedCollectors:
- collector.Collect(uncheckedMetricChan)
- default:
- return
- }
- wg.Done()
- }
- }
-
- // Start the first worker now to make sure at least one is running.
- go collectWorker()
- goroutineBudget--
-
- // Close checkedMetricChan and uncheckedMetricChan once all collectors
- // are collected.
- go func() {
- wg.Wait()
- close(checkedMetricChan)
- close(uncheckedMetricChan)
- }()
-
- // Drain checkedMetricChan and uncheckedMetricChan in case of premature return.
- defer func() {
- if checkedMetricChan != nil {
- for range checkedMetricChan {
- }
- }
- if uncheckedMetricChan != nil {
- for range uncheckedMetricChan {
- }
- }
- }()
-
- // Copy the channel references so we can nil them out later to remove
- // them from the select statements below.
- cmc := checkedMetricChan
- umc := uncheckedMetricChan
-
- for {
- select {
- case metric, ok := <-cmc:
- if !ok {
- cmc = nil
- break
- }
- errs.Append(processMetric(
- metric, metricFamiliesByName,
- metricHashes,
- registeredDescIDs,
- ))
- case metric, ok := <-umc:
- if !ok {
- umc = nil
- break
- }
- errs.Append(processMetric(
- metric, metricFamiliesByName,
- metricHashes,
- nil,
- ))
- default:
- if goroutineBudget <= 0 || len(checkedCollectors)+len(uncheckedCollectors) == 0 {
- // All collectors are already being worked on or
- // we have already as many goroutines started as
- // there are collectors. Do the same as above,
- // just without the default.
- select {
- case metric, ok := <-cmc:
- if !ok {
- cmc = nil
- break
- }
- errs.Append(processMetric(
- metric, metricFamiliesByName,
- metricHashes,
- registeredDescIDs,
- ))
- case metric, ok := <-umc:
- if !ok {
- umc = nil
- break
- }
- errs.Append(processMetric(
- metric, metricFamiliesByName,
- metricHashes,
- nil,
- ))
- }
- break
- }
- // Start more workers.
- go collectWorker()
- goroutineBudget--
- runtime.Gosched()
- }
- // Once both checkedMetricChan and uncheckedMetricChan are closed
- // and drained, the contraption above will nil out cmc and umc,
- // and then we can leave the collect loop here.
- if cmc == nil && umc == nil {
- break
- }
- }
- return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap()
-}
-
-// Describe implements Collector.
-func (r *Registry) Describe(ch chan<- *Desc) {
- r.mtx.RLock()
- defer r.mtx.RUnlock()
-
- // Only report the checked Collectors; unchecked collectors don't report any
- // Desc.
- for _, c := range r.collectorsByID {
- c.Describe(ch)
- }
-}
-
-// Collect implements Collector.
-func (r *Registry) Collect(ch chan<- Metric) {
- r.mtx.RLock()
- defer r.mtx.RUnlock()
-
- for _, c := range r.collectorsByID {
- c.Collect(ch)
- }
- for _, c := range r.uncheckedCollectors {
- c.Collect(ch)
- }
-}
-
-// WriteToTextfile calls Gather on the provided Gatherer, encodes the result in the
-// Prometheus text format, and writes it to a temporary file. Upon success, the
-// temporary file is renamed to the provided filename.
-//
-// This is intended for use with the textfile collector of the node exporter.
-// Note that the node exporter expects the filename to be suffixed with ".prom".
-func WriteToTextfile(filename string, g Gatherer) error {
- tmp, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename))
- if err != nil {
- return err
- }
- defer os.Remove(tmp.Name())
-
- mfs, err := g.Gather()
- if err != nil {
- return err
- }
- for _, mf := range mfs {
- if _, err := expfmt.MetricFamilyToText(tmp, mf); err != nil {
- return err
- }
- }
- if err := tmp.Close(); err != nil {
- return err
- }
-
- if err := os.Chmod(tmp.Name(), 0o644); err != nil {
- return err
- }
- return os.Rename(tmp.Name(), filename)
-}
-
-// processMetric is an internal helper method only used by the Gather method.
-func processMetric(
- metric Metric,
- metricFamiliesByName map[string]*dto.MetricFamily,
- metricHashes map[uint64]struct{},
- registeredDescIDs map[uint64]struct{},
-) error {
- desc := metric.Desc()
- // Wrapped metrics collected by an unchecked Collector can have an
- // invalid Desc.
- if desc.err != nil {
- return desc.err
- }
- dtoMetric := &dto.Metric{}
- if err := metric.Write(dtoMetric); err != nil {
- return fmt.Errorf("error collecting metric %v: %w", desc, err)
- }
- metricFamily, ok := metricFamiliesByName[desc.fqName]
- if ok { // Existing name.
- if metricFamily.GetHelp() != desc.help {
- return fmt.Errorf(
- "collected metric %s %s has help %q but should have %q",
- desc.fqName, dtoMetric, desc.help, metricFamily.GetHelp(),
- )
- }
- // TODO(beorn7): Simplify switch once Desc has type.
- switch metricFamily.GetType() {
- case dto.MetricType_COUNTER:
- if dtoMetric.Counter == nil {
- return fmt.Errorf(
- "collected metric %s %s should be a Counter",
- desc.fqName, dtoMetric,
- )
- }
- case dto.MetricType_GAUGE:
- if dtoMetric.Gauge == nil {
- return fmt.Errorf(
- "collected metric %s %s should be a Gauge",
- desc.fqName, dtoMetric,
- )
- }
- case dto.MetricType_SUMMARY:
- if dtoMetric.Summary == nil {
- return fmt.Errorf(
- "collected metric %s %s should be a Summary",
- desc.fqName, dtoMetric,
- )
- }
- case dto.MetricType_UNTYPED:
- if dtoMetric.Untyped == nil {
- return fmt.Errorf(
- "collected metric %s %s should be Untyped",
- desc.fqName, dtoMetric,
- )
- }
- case dto.MetricType_HISTOGRAM:
- if dtoMetric.Histogram == nil {
- return fmt.Errorf(
- "collected metric %s %s should be a Histogram",
- desc.fqName, dtoMetric,
- )
- }
- default:
- panic("encountered MetricFamily with invalid type")
- }
- } else { // New name.
- metricFamily = &dto.MetricFamily{}
- metricFamily.Name = proto.String(desc.fqName)
- metricFamily.Help = proto.String(desc.help)
- // TODO(beorn7): Simplify switch once Desc has type.
- switch {
- case dtoMetric.Gauge != nil:
- metricFamily.Type = dto.MetricType_GAUGE.Enum()
- case dtoMetric.Counter != nil:
- metricFamily.Type = dto.MetricType_COUNTER.Enum()
- case dtoMetric.Summary != nil:
- metricFamily.Type = dto.MetricType_SUMMARY.Enum()
- case dtoMetric.Untyped != nil:
- metricFamily.Type = dto.MetricType_UNTYPED.Enum()
- case dtoMetric.Histogram != nil:
- metricFamily.Type = dto.MetricType_HISTOGRAM.Enum()
- default:
- return fmt.Errorf("empty metric collected: %s", dtoMetric)
- }
- if err := checkSuffixCollisions(metricFamily, metricFamiliesByName); err != nil {
- return err
- }
- metricFamiliesByName[desc.fqName] = metricFamily
- }
- if err := checkMetricConsistency(metricFamily, dtoMetric, metricHashes); err != nil {
- return err
- }
- if registeredDescIDs != nil {
- // Is the desc registered at all?
- if _, exist := registeredDescIDs[desc.id]; !exist {
- return fmt.Errorf(
- "collected metric %s %s with unregistered descriptor %s",
- metricFamily.GetName(), dtoMetric, desc,
- )
- }
- if err := checkDescConsistency(metricFamily, dtoMetric, desc); err != nil {
- return err
- }
- }
- metricFamily.Metric = append(metricFamily.Metric, dtoMetric)
- return nil
-}
-
-// Gatherers is a slice of Gatherer instances that implements the Gatherer
-// interface itself. Its Gather method calls Gather on all Gatherers in the
-// slice in order and returns the merged results. Errors returned from the
-// Gather calls are all returned in a flattened MultiError. Duplicate and
-// inconsistent Metrics are skipped (first occurrence in slice order wins) and
-// reported in the returned error.
-//
-// Gatherers can be used to merge the Gather results from multiple
-// Registries. It also provides a way to directly inject existing MetricFamily
-// protobufs into the gathering by creating a custom Gatherer with a Gather
-// method that simply returns the existing MetricFamily protobufs. Note that no
-// registration is involved (in contrast to Collector registration), so
-// obviously registration-time checks cannot happen. Any inconsistencies between
-// the gathered MetricFamilies are reported as errors by the Gather method, and
-// inconsistent Metrics are dropped. Invalid parts of the MetricFamilies
-// (e.g. syntactically invalid metric or label names) will go undetected.
-type Gatherers []Gatherer
-
-// Gather implements Gatherer.
-func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) {
- var (
- metricFamiliesByName = map[string]*dto.MetricFamily{}
- metricHashes = map[uint64]struct{}{}
- errs MultiError // The collected errors to return in the end.
- )
-
- for i, g := range gs {
- mfs, err := g.Gather()
- if err != nil {
- multiErr := MultiError{}
- if errors.As(err, &multiErr) {
- for _, err := range multiErr {
- errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err))
- }
- } else {
- errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err))
- }
- }
- for _, mf := range mfs {
- existingMF, exists := metricFamiliesByName[mf.GetName()]
- if exists {
- if existingMF.GetHelp() != mf.GetHelp() {
- errs = append(errs, fmt.Errorf(
- "gathered metric family %s has help %q but should have %q",
- mf.GetName(), mf.GetHelp(), existingMF.GetHelp(),
- ))
- continue
- }
- if existingMF.GetType() != mf.GetType() {
- errs = append(errs, fmt.Errorf(
- "gathered metric family %s has type %s but should have %s",
- mf.GetName(), mf.GetType(), existingMF.GetType(),
- ))
- continue
- }
- } else {
- existingMF = &dto.MetricFamily{}
- existingMF.Name = mf.Name
- existingMF.Help = mf.Help
- existingMF.Type = mf.Type
- if err := checkSuffixCollisions(existingMF, metricFamiliesByName); err != nil {
- errs = append(errs, err)
- continue
- }
- metricFamiliesByName[mf.GetName()] = existingMF
- }
- for _, m := range mf.Metric {
- if err := checkMetricConsistency(existingMF, m, metricHashes); err != nil {
- errs = append(errs, err)
- continue
- }
- existingMF.Metric = append(existingMF.Metric, m)
- }
- }
- }
- return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap()
-}
-
-// checkSuffixCollisions checks for collisions with the “magic” suffixes the
-// Prometheus text format and the internal metric representation of the
-// Prometheus server add while flattening Summaries and Histograms.
-func checkSuffixCollisions(mf *dto.MetricFamily, mfs map[string]*dto.MetricFamily) error {
- var (
- newName = mf.GetName()
- newType = mf.GetType()
- newNameWithoutSuffix = ""
- )
- switch {
- case strings.HasSuffix(newName, "_count"):
- newNameWithoutSuffix = newName[:len(newName)-6]
- case strings.HasSuffix(newName, "_sum"):
- newNameWithoutSuffix = newName[:len(newName)-4]
- case strings.HasSuffix(newName, "_bucket"):
- newNameWithoutSuffix = newName[:len(newName)-7]
- }
- if newNameWithoutSuffix != "" {
- if existingMF, ok := mfs[newNameWithoutSuffix]; ok {
- switch existingMF.GetType() {
- case dto.MetricType_SUMMARY:
- if !strings.HasSuffix(newName, "_bucket") {
- return fmt.Errorf(
- "collected metric named %q collides with previously collected summary named %q",
- newName, newNameWithoutSuffix,
- )
- }
- case dto.MetricType_HISTOGRAM:
- return fmt.Errorf(
- "collected metric named %q collides with previously collected histogram named %q",
- newName, newNameWithoutSuffix,
- )
- }
- }
- }
- if newType == dto.MetricType_SUMMARY || newType == dto.MetricType_HISTOGRAM {
- if _, ok := mfs[newName+"_count"]; ok {
- return fmt.Errorf(
- "collected histogram or summary named %q collides with previously collected metric named %q",
- newName, newName+"_count",
- )
- }
- if _, ok := mfs[newName+"_sum"]; ok {
- return fmt.Errorf(
- "collected histogram or summary named %q collides with previously collected metric named %q",
- newName, newName+"_sum",
- )
- }
- }
- if newType == dto.MetricType_HISTOGRAM {
- if _, ok := mfs[newName+"_bucket"]; ok {
- return fmt.Errorf(
- "collected histogram named %q collides with previously collected metric named %q",
- newName, newName+"_bucket",
- )
- }
- }
- return nil
-}
-
-// checkMetricConsistency checks if the provided Metric is consistent with the
-// provided MetricFamily. It also hashes the Metric labels and the MetricFamily
-// name. If the resulting hash is already in the provided metricHashes, an error
-// is returned. If not, it is added to metricHashes.
-func checkMetricConsistency(
- metricFamily *dto.MetricFamily,
- dtoMetric *dto.Metric,
- metricHashes map[uint64]struct{},
-) error {
- name := metricFamily.GetName()
-
- // Type consistency with metric family.
- if metricFamily.GetType() == dto.MetricType_GAUGE && dtoMetric.Gauge == nil ||
- metricFamily.GetType() == dto.MetricType_COUNTER && dtoMetric.Counter == nil ||
- metricFamily.GetType() == dto.MetricType_SUMMARY && dtoMetric.Summary == nil ||
- metricFamily.GetType() == dto.MetricType_HISTOGRAM && dtoMetric.Histogram == nil ||
- metricFamily.GetType() == dto.MetricType_UNTYPED && dtoMetric.Untyped == nil {
- return fmt.Errorf(
- "collected metric %q { %s} is not a %s",
- name, dtoMetric, metricFamily.GetType(),
- )
- }
-
- previousLabelName := ""
- for _, labelPair := range dtoMetric.GetLabel() {
- labelName := labelPair.GetName()
- if labelName == previousLabelName {
- return fmt.Errorf(
- "collected metric %q { %s} has two or more labels with the same name: %s",
- name, dtoMetric, labelName,
- )
- }
- if !checkLabelName(labelName) {
- return fmt.Errorf(
- "collected metric %q { %s} has a label with an invalid name: %s",
- name, dtoMetric, labelName,
- )
- }
- if dtoMetric.Summary != nil && labelName == quantileLabel {
- return fmt.Errorf(
- "collected metric %q { %s} must not have an explicit %q label",
- name, dtoMetric, quantileLabel,
- )
- }
- if !utf8.ValidString(labelPair.GetValue()) {
- return fmt.Errorf(
- "collected metric %q { %s} has a label named %q whose value is not utf8: %#v",
- name, dtoMetric, labelName, labelPair.GetValue())
- }
- previousLabelName = labelName
- }
-
- // Is the metric unique (i.e. no other metric with the same name and the same labels)?
- h := xxhash.New()
- h.WriteString(name)
- h.Write(separatorByteSlice)
- // Make sure label pairs are sorted. We depend on it for the consistency
- // check.
- if !sort.IsSorted(internal.LabelPairSorter(dtoMetric.Label)) {
- // We cannot sort dtoMetric.Label in place as it is immutable by contract.
- copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label))
- copy(copiedLabels, dtoMetric.Label)
- sort.Sort(internal.LabelPairSorter(copiedLabels))
- dtoMetric.Label = copiedLabels
- }
- for _, lp := range dtoMetric.Label {
- h.WriteString(lp.GetName())
- h.Write(separatorByteSlice)
- h.WriteString(lp.GetValue())
- h.Write(separatorByteSlice)
- }
- if dtoMetric.TimestampMs != nil {
- h.WriteString(strconv.FormatInt(*(dtoMetric.TimestampMs), 10))
- h.Write(separatorByteSlice)
- }
- hSum := h.Sum64()
- if _, exists := metricHashes[hSum]; exists {
- return fmt.Errorf(
- "collected metric %q { %s} was collected before with the same name and label values",
- name, dtoMetric,
- )
- }
- metricHashes[hSum] = struct{}{}
- return nil
-}
-
-func checkDescConsistency(
- metricFamily *dto.MetricFamily,
- dtoMetric *dto.Metric,
- desc *Desc,
-) error {
- // Desc help consistency with metric family help.
- if metricFamily.GetHelp() != desc.help {
- return fmt.Errorf(
- "collected metric %s %s has help %q but should have %q",
- metricFamily.GetName(), dtoMetric, metricFamily.GetHelp(), desc.help,
- )
- }
-
- // Is the desc consistent with the content of the metric?
- lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label))
- copy(lpsFromDesc, desc.constLabelPairs)
- for _, l := range desc.variableLabels.names {
- lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{
- Name: proto.String(l),
- })
- }
- if len(lpsFromDesc) != len(dtoMetric.Label) {
- return fmt.Errorf(
- "labels in collected metric %s %s are inconsistent with descriptor %s",
- metricFamily.GetName(), dtoMetric, desc,
- )
- }
- sort.Sort(internal.LabelPairSorter(lpsFromDesc))
- for i, lpFromDesc := range lpsFromDesc {
- lpFromMetric := dtoMetric.Label[i]
- if lpFromDesc.GetName() != lpFromMetric.GetName() ||
- lpFromDesc.Value != nil && lpFromDesc.GetValue() != lpFromMetric.GetValue() {
- return fmt.Errorf(
- "labels in collected metric %s %s are inconsistent with descriptor %s",
- metricFamily.GetName(), dtoMetric, desc,
- )
- }
- }
- return nil
-}
-
-var _ TransactionalGatherer = &MultiTRegistry{}
-
-// MultiTRegistry is a TransactionalGatherer that joins gathered metrics from multiple
-// transactional gatherers.
-//
-// It is caller responsibility to ensure two registries have mutually exclusive metric families,
-// no deduplication will happen.
-type MultiTRegistry struct {
- tGatherers []TransactionalGatherer
-}
-
-// NewMultiTRegistry creates MultiTRegistry.
-func NewMultiTRegistry(tGatherers ...TransactionalGatherer) *MultiTRegistry {
- return &MultiTRegistry{
- tGatherers: tGatherers,
- }
-}
-
-// Gather implements TransactionalGatherer interface.
-func (r *MultiTRegistry) Gather() (mfs []*dto.MetricFamily, done func(), err error) {
- errs := MultiError{}
-
- dFns := make([]func(), 0, len(r.tGatherers))
- // TODO(bwplotka): Implement concurrency for those?
- for _, g := range r.tGatherers {
- // TODO(bwplotka): Check for duplicates?
- m, d, err := g.Gather()
- errs.Append(err)
-
- mfs = append(mfs, m...)
- dFns = append(dFns, d)
- }
-
- // TODO(bwplotka): Consider sort in place, given metric family in gather is sorted already.
- sort.Slice(mfs, func(i, j int) bool {
- return *mfs[i].Name < *mfs[j].Name
- })
- return mfs, func() {
- for _, d := range dFns {
- d()
- }
- }, errs.MaybeUnwrap()
-}
-
-// TransactionalGatherer represents transactional gatherer that can be triggered to notify gatherer that memory
-// used by metric family is no longer used by a caller. This allows implementations with cache.
-type TransactionalGatherer interface {
- // Gather returns metrics in a lexicographically sorted slice
- // of uniquely named MetricFamily protobufs. Gather ensures that the
- // returned slice is valid and self-consistent so that it can be used
- // for valid exposition. As an exception to the strict consistency
- // requirements described for metric.Desc, Gather will tolerate
- // different sets of label names for metrics of the same metric family.
- //
- // Even if an error occurs, Gather attempts to gather as many metrics as
- // possible. Hence, if a non-nil error is returned, the returned
- // MetricFamily slice could be nil (in case of a fatal error that
- // prevented any meaningful metric collection) or contain a number of
- // MetricFamily protobufs, some of which might be incomplete, and some
- // might be missing altogether. The returned error (which might be a
- // MultiError) explains the details. Note that this is mostly useful for
- // debugging purposes. If the gathered protobufs are to be used for
- // exposition in actual monitoring, it is almost always better to not
- // expose an incomplete result and instead disregard the returned
- // MetricFamily protobufs in case the returned error is non-nil.
- //
- // Important: done is expected to be triggered (even if the error occurs!)
- // once caller does not need returned slice of dto.MetricFamily.
- Gather() (_ []*dto.MetricFamily, done func(), err error)
-}
-
-// ToTransactionalGatherer transforms Gatherer to transactional one with noop as done function.
-func ToTransactionalGatherer(g Gatherer) TransactionalGatherer {
- return &noTransactionGatherer{g: g}
-}
-
-type noTransactionGatherer struct {
- g Gatherer
-}
-
-// Gather implements TransactionalGatherer interface.
-func (g *noTransactionGatherer) Gather() (_ []*dto.MetricFamily, done func(), err error) {
- mfs, err := g.g.Gather()
- return mfs, func() {}, err
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/vendor/github.com/prometheus/client_golang/prometheus/summary.go
deleted file mode 100644
index 1ab0e4796..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/summary.go
+++ /dev/null
@@ -1,827 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "fmt"
- "math"
- "runtime"
- "sort"
- "sync"
- "sync/atomic"
- "time"
-
- dto "github.com/prometheus/client_model/go"
-
- "github.com/beorn7/perks/quantile"
- "google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/types/known/timestamppb"
-)
-
-// quantileLabel is used for the label that defines the quantile in a
-// summary.
-const quantileLabel = "quantile"
-
-// A Summary captures individual observations from an event or sample stream and
-// summarizes them in a manner similar to traditional summary statistics: 1. sum
-// of observations, 2. observation count, 3. rank estimations.
-//
-// A typical use-case is the observation of request latencies. By default, a
-// Summary provides the median, the 90th and the 99th percentile of the latency
-// as rank estimations. However, the default behavior will change in the
-// upcoming v1.0.0 of the library. There will be no rank estimations at all by
-// default. For a sane transition, it is recommended to set the desired rank
-// estimations explicitly.
-//
-// Note that the rank estimations cannot be aggregated in a meaningful way with
-// the Prometheus query language (i.e. you cannot average or add them). If you
-// need aggregatable quantiles (e.g. you want the 99th percentile latency of all
-// queries served across all instances of a service), consider the Histogram
-// metric type. See the Prometheus documentation for more details.
-//
-// To create Summary instances, use NewSummary.
-type Summary interface {
- Metric
- Collector
-
- // Observe adds a single observation to the summary. Observations are
- // usually positive or zero. Negative observations are accepted but
- // prevent current versions of Prometheus from properly detecting
- // counter resets in the sum of observations. See
- // https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations
- // for details.
- Observe(float64)
-}
-
-var errQuantileLabelNotAllowed = fmt.Errorf(
- "%q is not allowed as label name in summaries", quantileLabel,
-)
-
-// Default values for SummaryOpts.
-const (
- // DefMaxAge is the default duration for which observations stay
- // relevant.
- DefMaxAge time.Duration = 10 * time.Minute
- // DefAgeBuckets is the default number of buckets used to calculate the
- // age of observations.
- DefAgeBuckets = 5
- // DefBufCap is the standard buffer size for collecting Summary observations.
- DefBufCap = 500
-)
-
-// SummaryOpts bundles the options for creating a Summary metric. It is
-// mandatory to set Name to a non-empty string. While all other fields are
-// optional and can safely be left at their zero value, it is recommended to set
-// a help string and to explicitly set the Objectives field to the desired value
-// as the default value will change in the upcoming v1.0.0 of the library.
-type SummaryOpts struct {
- // Namespace, Subsystem, and Name are components of the fully-qualified
- // name of the Summary (created by joining these components with
- // "_"). Only Name is mandatory, the others merely help structuring the
- // name. Note that the fully-qualified name of the Summary must be a
- // valid Prometheus metric name.
- Namespace string
- Subsystem string
- Name string
-
- // Help provides information about this Summary.
- //
- // Metrics with the same fully-qualified name must have the same Help
- // string.
- Help string
-
- // ConstLabels are used to attach fixed labels to this metric. Metrics
- // with the same fully-qualified name must have the same label names in
- // their ConstLabels.
- //
- // Due to the way a Summary is represented in the Prometheus text format
- // and how it is handled by the Prometheus server internally, “quantile”
- // is an illegal label name. Construction of a Summary or SummaryVec
- // will panic if this label name is used in ConstLabels.
- //
- // ConstLabels are only used rarely. In particular, do not use them to
- // attach the same labels to all your metrics. Those use cases are
- // better covered by target labels set by the scraping Prometheus
- // server, or by one specific metric (e.g. a build_info or a
- // machine_role metric). See also
- // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels
- ConstLabels Labels
-
- // Objectives defines the quantile rank estimates with their respective
- // absolute error. If Objectives[q] = e, then the value reported for q
- // will be the φ-quantile value for some φ between q-e and q+e. The
- // default value is an empty map, resulting in a summary without
- // quantiles.
- Objectives map[float64]float64
-
- // MaxAge defines the duration for which an observation stays relevant
- // for the summary. Only applies to pre-calculated quantiles, does not
- // apply to _sum and _count. Must be positive. The default value is
- // DefMaxAge.
- MaxAge time.Duration
-
- // AgeBuckets is the number of buckets used to exclude observations that
- // are older than MaxAge from the summary. A higher number has a
- // resource penalty, so only increase it if the higher resolution is
- // really required. For very high observation rates, you might want to
- // reduce the number of age buckets. With only one age bucket, you will
- // effectively see a complete reset of the summary each time MaxAge has
- // passed. The default value is DefAgeBuckets.
- AgeBuckets uint32
-
- // BufCap defines the default sample stream buffer size. The default
- // value of DefBufCap should suffice for most uses. If there is a need
- // to increase the value, a multiple of 500 is recommended (because that
- // is the internal buffer size of the underlying package
- // "github.com/bmizerany/perks/quantile").
- BufCap uint32
-
- // now is for testing purposes, by default it's time.Now.
- now func() time.Time
-}
-
-// SummaryVecOpts bundles the options to create a SummaryVec metric.
-// It is mandatory to set SummaryOpts, see there for mandatory fields. VariableLabels
-// is optional and can safely be left to its default value.
-type SummaryVecOpts struct {
- SummaryOpts
-
- // VariableLabels are used to partition the metric vector by the given set
- // of labels. Each label value will be constrained with the optional Constraint
- // function, if provided.
- VariableLabels ConstrainableLabels
-}
-
-// Problem with the sliding-window decay algorithm... The Merge method of
-// perk/quantile is actually not working as advertised - and it might be
-// unfixable, as the underlying algorithm is apparently not capable of merging
-// summaries in the first place. To avoid using Merge, we are currently adding
-// observations to _each_ age bucket, i.e. the effort to add a sample is
-// essentially multiplied by the number of age buckets. When rotating age
-// buckets, we empty the previous head stream. On scrape time, we simply take
-// the quantiles from the head stream (no merging required). Result: More effort
-// on observation time, less effort on scrape time, which is exactly the
-// opposite of what we try to accomplish, but at least the results are correct.
-//
-// The quite elegant previous contraption to merge the age buckets efficiently
-// on scrape time (see code up commit 6b9530d72ea715f0ba612c0120e6e09fbf1d49d0)
-// can't be used anymore.
-
-// NewSummary creates a new Summary based on the provided SummaryOpts.
-func NewSummary(opts SummaryOpts) Summary {
- return newSummary(
- NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- nil,
- opts.ConstLabels,
- ),
- opts,
- )
-}
-
-func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
- if len(desc.variableLabels.names) != len(labelValues) {
- panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues))
- }
-
- for _, n := range desc.variableLabels.names {
- if n == quantileLabel {
- panic(errQuantileLabelNotAllowed)
- }
- }
- for _, lp := range desc.constLabelPairs {
- if lp.GetName() == quantileLabel {
- panic(errQuantileLabelNotAllowed)
- }
- }
-
- if opts.Objectives == nil {
- opts.Objectives = map[float64]float64{}
- }
-
- if opts.MaxAge < 0 {
- panic(fmt.Errorf("illegal max age MaxAge=%v", opts.MaxAge))
- }
- if opts.MaxAge == 0 {
- opts.MaxAge = DefMaxAge
- }
-
- if opts.AgeBuckets == 0 {
- opts.AgeBuckets = DefAgeBuckets
- }
-
- if opts.BufCap == 0 {
- opts.BufCap = DefBufCap
- }
-
- if opts.now == nil {
- opts.now = time.Now
- }
- if len(opts.Objectives) == 0 {
- // Use the lock-free implementation of a Summary without objectives.
- s := &noObjectivesSummary{
- desc: desc,
- labelPairs: MakeLabelPairs(desc, labelValues),
- counts: [2]*summaryCounts{{}, {}},
- }
- s.init(s) // Init self-collection.
- s.createdTs = timestamppb.New(opts.now())
- return s
- }
-
- s := &summary{
- desc: desc,
-
- objectives: opts.Objectives,
- sortedObjectives: make([]float64, 0, len(opts.Objectives)),
-
- labelPairs: MakeLabelPairs(desc, labelValues),
-
- hotBuf: make([]float64, 0, opts.BufCap),
- coldBuf: make([]float64, 0, opts.BufCap),
- streamDuration: opts.MaxAge / time.Duration(opts.AgeBuckets),
- }
- s.headStreamExpTime = opts.now().Add(s.streamDuration)
- s.hotBufExpTime = s.headStreamExpTime
-
- for i := uint32(0); i < opts.AgeBuckets; i++ {
- s.streams = append(s.streams, s.newStream())
- }
- s.headStream = s.streams[0]
-
- for qu := range s.objectives {
- s.sortedObjectives = append(s.sortedObjectives, qu)
- }
- sort.Float64s(s.sortedObjectives)
-
- s.init(s) // Init self-collection.
- s.createdTs = timestamppb.New(opts.now())
- return s
-}
-
-type summary struct {
- selfCollector
-
- bufMtx sync.Mutex // Protects hotBuf and hotBufExpTime.
- mtx sync.Mutex // Protects every other moving part.
- // Lock bufMtx before mtx if both are needed.
-
- desc *Desc
-
- objectives map[float64]float64
- sortedObjectives []float64
-
- labelPairs []*dto.LabelPair
-
- sum float64
- cnt uint64
-
- hotBuf, coldBuf []float64
-
- streams []*quantile.Stream
- streamDuration time.Duration
- headStream *quantile.Stream
- headStreamIdx int
- headStreamExpTime, hotBufExpTime time.Time
-
- createdTs *timestamppb.Timestamp
-}
-
-func (s *summary) Desc() *Desc {
- return s.desc
-}
-
-func (s *summary) Observe(v float64) {
- s.bufMtx.Lock()
- defer s.bufMtx.Unlock()
-
- now := time.Now()
- if now.After(s.hotBufExpTime) {
- s.asyncFlush(now)
- }
- s.hotBuf = append(s.hotBuf, v)
- if len(s.hotBuf) == cap(s.hotBuf) {
- s.asyncFlush(now)
- }
-}
-
-func (s *summary) Write(out *dto.Metric) error {
- sum := &dto.Summary{
- CreatedTimestamp: s.createdTs,
- }
- qs := make([]*dto.Quantile, 0, len(s.objectives))
-
- s.bufMtx.Lock()
- s.mtx.Lock()
- // Swap bufs even if hotBuf is empty to set new hotBufExpTime.
- s.swapBufs(time.Now())
- s.bufMtx.Unlock()
-
- s.flushColdBuf()
- sum.SampleCount = proto.Uint64(s.cnt)
- sum.SampleSum = proto.Float64(s.sum)
-
- for _, rank := range s.sortedObjectives {
- var q float64
- if s.headStream.Count() == 0 {
- q = math.NaN()
- } else {
- q = s.headStream.Query(rank)
- }
- qs = append(qs, &dto.Quantile{
- Quantile: proto.Float64(rank),
- Value: proto.Float64(q),
- })
- }
-
- s.mtx.Unlock()
-
- if len(qs) > 0 {
- sort.Sort(quantSort(qs))
- }
- sum.Quantile = qs
-
- out.Summary = sum
- out.Label = s.labelPairs
- return nil
-}
-
-func (s *summary) newStream() *quantile.Stream {
- return quantile.NewTargeted(s.objectives)
-}
-
-// asyncFlush needs bufMtx locked.
-func (s *summary) asyncFlush(now time.Time) {
- s.mtx.Lock()
- s.swapBufs(now)
-
- // Unblock the original goroutine that was responsible for the mutation
- // that triggered the compaction. But hold onto the global non-buffer
- // state mutex until the operation finishes.
- go func() {
- s.flushColdBuf()
- s.mtx.Unlock()
- }()
-}
-
-// rotateStreams needs mtx AND bufMtx locked.
-func (s *summary) maybeRotateStreams() {
- for !s.hotBufExpTime.Equal(s.headStreamExpTime) {
- s.headStream.Reset()
- s.headStreamIdx++
- if s.headStreamIdx >= len(s.streams) {
- s.headStreamIdx = 0
- }
- s.headStream = s.streams[s.headStreamIdx]
- s.headStreamExpTime = s.headStreamExpTime.Add(s.streamDuration)
- }
-}
-
-// flushColdBuf needs mtx locked.
-func (s *summary) flushColdBuf() {
- for _, v := range s.coldBuf {
- for _, stream := range s.streams {
- stream.Insert(v)
- }
- s.cnt++
- s.sum += v
- }
- s.coldBuf = s.coldBuf[0:0]
- s.maybeRotateStreams()
-}
-
-// swapBufs needs mtx AND bufMtx locked, coldBuf must be empty.
-func (s *summary) swapBufs(now time.Time) {
- if len(s.coldBuf) != 0 {
- panic("coldBuf is not empty")
- }
- s.hotBuf, s.coldBuf = s.coldBuf, s.hotBuf
- // hotBuf is now empty and gets new expiration set.
- for now.After(s.hotBufExpTime) {
- s.hotBufExpTime = s.hotBufExpTime.Add(s.streamDuration)
- }
-}
-
-type summaryCounts struct {
- // sumBits contains the bits of the float64 representing the sum of all
- // observations. sumBits and count have to go first in the struct to
- // guarantee alignment for atomic operations.
- // http://golang.org/pkg/sync/atomic/#pkg-note-BUG
- sumBits uint64
- count uint64
-}
-
-type noObjectivesSummary struct {
- // countAndHotIdx enables lock-free writes with use of atomic updates.
- // The most significant bit is the hot index [0 or 1] of the count field
- // below. Observe calls update the hot one. All remaining bits count the
- // number of Observe calls. Observe starts by incrementing this counter,
- // and finish by incrementing the count field in the respective
- // summaryCounts, as a marker for completion.
- //
- // Calls of the Write method (which are non-mutating reads from the
- // perspective of the summary) swap the hot–cold under the writeMtx
- // lock. A cooldown is awaited (while locked) by comparing the number of
- // observations with the initiation count. Once they match, then the
- // last observation on the now cool one has completed. All cool fields must
- // be merged into the new hot before releasing writeMtx.
-
- // Fields with atomic access first! See alignment constraint:
- // http://golang.org/pkg/sync/atomic/#pkg-note-BUG
- countAndHotIdx uint64
-
- selfCollector
- desc *Desc
- writeMtx sync.Mutex // Only used in the Write method.
-
- // Two counts, one is "hot" for lock-free observations, the other is
- // "cold" for writing out a dto.Metric. It has to be an array of
- // pointers to guarantee 64bit alignment of the histogramCounts, see
- // http://golang.org/pkg/sync/atomic/#pkg-note-BUG.
- counts [2]*summaryCounts
-
- labelPairs []*dto.LabelPair
-
- createdTs *timestamppb.Timestamp
-}
-
-func (s *noObjectivesSummary) Desc() *Desc {
- return s.desc
-}
-
-func (s *noObjectivesSummary) Observe(v float64) {
- // We increment h.countAndHotIdx so that the counter in the lower
- // 63 bits gets incremented. At the same time, we get the new value
- // back, which we can use to find the currently-hot counts.
- n := atomic.AddUint64(&s.countAndHotIdx, 1)
- hotCounts := s.counts[n>>63]
-
- for {
- oldBits := atomic.LoadUint64(&hotCounts.sumBits)
- newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
- if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
- break
- }
- }
- // Increment count last as we take it as a signal that the observation
- // is complete.
- atomic.AddUint64(&hotCounts.count, 1)
-}
-
-func (s *noObjectivesSummary) Write(out *dto.Metric) error {
- // For simplicity, we protect this whole method by a mutex. It is not in
- // the hot path, i.e. Observe is called much more often than Write. The
- // complication of making Write lock-free isn't worth it, if possible at
- // all.
- s.writeMtx.Lock()
- defer s.writeMtx.Unlock()
-
- // Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0)
- // without touching the count bits. See the struct comments for a full
- // description of the algorithm.
- n := atomic.AddUint64(&s.countAndHotIdx, 1<<63)
- // count is contained unchanged in the lower 63 bits.
- count := n & ((1 << 63) - 1)
- // The most significant bit tells us which counts is hot. The complement
- // is thus the cold one.
- hotCounts := s.counts[n>>63]
- coldCounts := s.counts[(^n)>>63]
-
- // Await cooldown.
- for count != atomic.LoadUint64(&coldCounts.count) {
- runtime.Gosched() // Let observations get work done.
- }
-
- sum := &dto.Summary{
- SampleCount: proto.Uint64(count),
- SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
- CreatedTimestamp: s.createdTs,
- }
-
- out.Summary = sum
- out.Label = s.labelPairs
-
- // Finally add all the cold counts to the new hot counts and reset the cold counts.
- atomic.AddUint64(&hotCounts.count, count)
- atomic.StoreUint64(&coldCounts.count, 0)
- for {
- oldBits := atomic.LoadUint64(&hotCounts.sumBits)
- newBits := math.Float64bits(math.Float64frombits(oldBits) + sum.GetSampleSum())
- if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
- atomic.StoreUint64(&coldCounts.sumBits, 0)
- break
- }
- }
- return nil
-}
-
-type quantSort []*dto.Quantile
-
-func (s quantSort) Len() int {
- return len(s)
-}
-
-func (s quantSort) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
-}
-
-func (s quantSort) Less(i, j int) bool {
- return s[i].GetQuantile() < s[j].GetQuantile()
-}
-
-// SummaryVec is a Collector that bundles a set of Summaries that all share the
-// same Desc, but have different values for their variable labels. This is used
-// if you want to count the same thing partitioned by various dimensions
-// (e.g. HTTP request latencies, partitioned by status code and method). Create
-// instances with NewSummaryVec.
-type SummaryVec struct {
- *MetricVec
-}
-
-// NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and
-// partitioned by the given label names.
-//
-// Due to the way a Summary is represented in the Prometheus text format and how
-// it is handled by the Prometheus server internally, “quantile” is an illegal
-// label name. NewSummaryVec will panic if this label name is used.
-func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
- return V2.NewSummaryVec(SummaryVecOpts{
- SummaryOpts: opts,
- VariableLabels: UnconstrainedLabels(labelNames),
- })
-}
-
-// NewSummaryVec creates a new SummaryVec based on the provided SummaryVecOpts.
-func (v2) NewSummaryVec(opts SummaryVecOpts) *SummaryVec {
- for _, ln := range opts.VariableLabels.labelNames() {
- if ln == quantileLabel {
- panic(errQuantileLabelNotAllowed)
- }
- }
- desc := V2.NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- opts.VariableLabels,
- opts.ConstLabels,
- )
- return &SummaryVec{
- MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
- return newSummary(desc, opts.SummaryOpts, lvs...)
- }),
- }
-}
-
-// GetMetricWithLabelValues returns the Summary for the given slice of label
-// values (same order as the variable labels in Desc). If that combination of
-// label values is accessed for the first time, a new Summary is created.
-//
-// It is possible to call this method without using the returned Summary to only
-// create the new Summary but leave it at its starting value, a Summary without
-// any observations.
-//
-// Keeping the Summary for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Summary from the SummaryVec. In that case,
-// the Summary will still exist, but it will not be exported anymore, even if a
-// Summary with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of variable labels in Desc (minus any curried labels).
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
-func (v *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
- metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)
- if metric != nil {
- return metric.(Observer), err
- }
- return nil, err
-}
-
-// GetMetricWith returns the Summary for the given Labels map (the label names
-// must match those of the variable labels in Desc). If that label map is
-// accessed for the first time, a new Summary is created. Implications of
-// creating a Summary without using it and keeping the Summary for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the variable labels in Desc (minus any curried labels).
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (v *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {
- metric, err := v.MetricVec.GetMetricWith(labels)
- if metric != nil {
- return metric.(Observer), err
- }
- return nil, err
-}
-
-// WithLabelValues works as GetMetricWithLabelValues, but panics where
-// GetMetricWithLabelValues would have returned an error. Not returning an
-// error allows shortcuts like
-//
-// myVec.WithLabelValues("404", "GET").Observe(42.21)
-func (v *SummaryVec) WithLabelValues(lvs ...string) Observer {
- s, err := v.GetMetricWithLabelValues(lvs...)
- if err != nil {
- panic(err)
- }
- return s
-}
-
-// With works as GetMetricWith, but panics where GetMetricWithLabels would have
-// returned an error. Not returning an error allows shortcuts like
-//
-// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21)
-func (v *SummaryVec) With(labels Labels) Observer {
- s, err := v.GetMetricWith(labels)
- if err != nil {
- panic(err)
- }
- return s
-}
-
-// CurryWith returns a vector curried with the provided labels, i.e. the
-// returned vector has those labels pre-set for all labeled operations performed
-// on it. The cardinality of the curried vector is reduced accordingly. The
-// order of the remaining labels stays the same (just with the curried labels
-// taken out of the sequence – which is relevant for the
-// (GetMetric)WithLabelValues methods). It is possible to curry a curried
-// vector, but only with labels not yet used for currying before.
-//
-// The metrics contained in the SummaryVec are shared between the curried and
-// uncurried vectors. They are just accessed differently. Curried and uncurried
-// vectors behave identically in terms of collection. Only one must be
-// registered with a given registry (usually the uncurried version). The Reset
-// method deletes all metrics, even if called on a curried vector.
-func (v *SummaryVec) CurryWith(labels Labels) (ObserverVec, error) {
- vec, err := v.MetricVec.CurryWith(labels)
- if vec != nil {
- return &SummaryVec{vec}, err
- }
- return nil, err
-}
-
-// MustCurryWith works as CurryWith but panics where CurryWith would have
-// returned an error.
-func (v *SummaryVec) MustCurryWith(labels Labels) ObserverVec {
- vec, err := v.CurryWith(labels)
- if err != nil {
- panic(err)
- }
- return vec
-}
-
-type constSummary struct {
- desc *Desc
- count uint64
- sum float64
- quantiles map[float64]float64
- labelPairs []*dto.LabelPair
- createdTs *timestamppb.Timestamp
-}
-
-func (s *constSummary) Desc() *Desc {
- return s.desc
-}
-
-func (s *constSummary) Write(out *dto.Metric) error {
- sum := &dto.Summary{
- CreatedTimestamp: s.createdTs,
- }
- qs := make([]*dto.Quantile, 0, len(s.quantiles))
-
- sum.SampleCount = proto.Uint64(s.count)
- sum.SampleSum = proto.Float64(s.sum)
-
- for rank, q := range s.quantiles {
- qs = append(qs, &dto.Quantile{
- Quantile: proto.Float64(rank),
- Value: proto.Float64(q),
- })
- }
-
- if len(qs) > 0 {
- sort.Sort(quantSort(qs))
- }
- sum.Quantile = qs
-
- out.Summary = sum
- out.Label = s.labelPairs
-
- return nil
-}
-
-// NewConstSummary returns a metric representing a Prometheus summary with fixed
-// values for the count, sum, and quantiles. As those parameters cannot be
-// changed, the returned value does not implement the Summary interface (but
-// only the Metric interface). Users of this package will not have much use for
-// it in regular operations. However, when implementing custom Collectors, it is
-// useful as a throw-away metric that is generated on the fly to send it to
-// Prometheus in the Collect method.
-//
-// quantiles maps ranks to quantile values. For example, a median latency of
-// 0.23s and a 99th percentile latency of 0.56s would be expressed as:
-//
-// map[float64]float64{0.5: 0.23, 0.99: 0.56}
-//
-// NewConstSummary returns an error if the length of labelValues is not
-// consistent with the variable labels in Desc or if Desc is invalid.
-func NewConstSummary(
- desc *Desc,
- count uint64,
- sum float64,
- quantiles map[float64]float64,
- labelValues ...string,
-) (Metric, error) {
- if desc.err != nil {
- return nil, desc.err
- }
- if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
- return nil, err
- }
- return &constSummary{
- desc: desc,
- count: count,
- sum: sum,
- quantiles: quantiles,
- labelPairs: MakeLabelPairs(desc, labelValues),
- }, nil
-}
-
-// MustNewConstSummary is a version of NewConstSummary that panics where
-// NewConstMetric would have returned an error.
-func MustNewConstSummary(
- desc *Desc,
- count uint64,
- sum float64,
- quantiles map[float64]float64,
- labelValues ...string,
-) Metric {
- m, err := NewConstSummary(desc, count, sum, quantiles, labelValues...)
- if err != nil {
- panic(err)
- }
- return m
-}
-
-// NewConstSummaryWithCreatedTimestamp does the same thing as NewConstSummary but sets the created timestamp.
-func NewConstSummaryWithCreatedTimestamp(
- desc *Desc,
- count uint64,
- sum float64,
- quantiles map[float64]float64,
- ct time.Time,
- labelValues ...string,
-) (Metric, error) {
- if desc.err != nil {
- return nil, desc.err
- }
- if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
- return nil, err
- }
- return &constSummary{
- desc: desc,
- count: count,
- sum: sum,
- quantiles: quantiles,
- labelPairs: MakeLabelPairs(desc, labelValues),
- createdTs: timestamppb.New(ct),
- }, nil
-}
-
-// MustNewConstSummaryWithCreatedTimestamp is a version of NewConstSummaryWithCreatedTimestamp that panics where
-// NewConstSummaryWithCreatedTimestamp would have returned an error.
-func MustNewConstSummaryWithCreatedTimestamp(
- desc *Desc,
- count uint64,
- sum float64,
- quantiles map[float64]float64,
- ct time.Time,
- labelValues ...string,
-) Metric {
- m, err := NewConstSummaryWithCreatedTimestamp(desc, count, sum, quantiles, ct, labelValues...)
- if err != nil {
- panic(err)
- }
- return m
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/timer.go b/vendor/github.com/prometheus/client_golang/prometheus/timer.go
deleted file mode 100644
index 52344fef5..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/timer.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2016 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import "time"
-
-// Timer is a helper type to time functions. Use NewTimer to create new
-// instances.
-type Timer struct {
- begin time.Time
- observer Observer
-}
-
-// NewTimer creates a new Timer. The provided Observer is used to observe a
-// duration in seconds. If the Observer implements ExemplarObserver, passing exemplar
-// later on will be also supported.
-// Timer is usually used to time a function call in the
-// following way:
-//
-// func TimeMe() {
-// timer := NewTimer(myHistogram)
-// defer timer.ObserveDuration()
-// // Do actual work.
-// }
-//
-// or
-//
-// func TimeMeWithExemplar() {
-// timer := NewTimer(myHistogram)
-// defer timer.ObserveDurationWithExemplar(exemplar)
-// // Do actual work.
-// }
-func NewTimer(o Observer) *Timer {
- return &Timer{
- begin: time.Now(),
- observer: o,
- }
-}
-
-// ObserveDuration records the duration passed since the Timer was created with
-// NewTimer. It calls the Observe method of the Observer provided during
-// construction with the duration in seconds as an argument. The observed
-// duration is also returned. ObserveDuration is usually called with a defer
-// statement.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-func (t *Timer) ObserveDuration() time.Duration {
- d := time.Since(t.begin)
- if t.observer != nil {
- t.observer.Observe(d.Seconds())
- }
- return d
-}
-
-// ObserveDurationWithExemplar is like ObserveDuration, but it will also
-// observe exemplar with the duration unless exemplar is nil or provided Observer can't
-// be casted to ExemplarObserver.
-func (t *Timer) ObserveDurationWithExemplar(exemplar Labels) time.Duration {
- d := time.Since(t.begin)
- eo, ok := t.observer.(ExemplarObserver)
- if ok && exemplar != nil {
- eo.ObserveWithExemplar(d.Seconds(), exemplar)
- return d
- }
- if t.observer != nil {
- t.observer.Observe(d.Seconds())
- }
- return d
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/untyped.go b/vendor/github.com/prometheus/client_golang/prometheus/untyped.go
deleted file mode 100644
index 0f9ce63f4..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/untyped.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-// UntypedOpts is an alias for Opts. See there for doc comments.
-type UntypedOpts Opts
-
-// UntypedFunc works like GaugeFunc but the collected metric is of type
-// "Untyped". UntypedFunc is useful to mirror an external metric of unknown
-// type.
-//
-// To create UntypedFunc instances, use NewUntypedFunc.
-type UntypedFunc interface {
- Metric
- Collector
-}
-
-// NewUntypedFunc creates a new UntypedFunc based on the provided
-// UntypedOpts. The value reported is determined by calling the given function
-// from within the Write method. Take into account that metric collection may
-// happen concurrently. If that results in concurrent calls to Write, like in
-// the case where an UntypedFunc is directly registered with Prometheus, the
-// provided function must be concurrency-safe.
-func NewUntypedFunc(opts UntypedOpts, function func() float64) UntypedFunc {
- return newValueFunc(NewDesc(
- BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
- opts.Help,
- nil,
- opts.ConstLabels,
- ), UntypedValue, function)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/value.go b/vendor/github.com/prometheus/client_golang/prometheus/value.go
deleted file mode 100644
index cc23011fa..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/value.go
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "errors"
- "fmt"
- "sort"
- "time"
- "unicode/utf8"
-
- "github.com/prometheus/client_golang/prometheus/internal"
-
- dto "github.com/prometheus/client_model/go"
- "google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/types/known/timestamppb"
-)
-
-// ValueType is an enumeration of metric types that represent a simple value.
-type ValueType int
-
-// Possible values for the ValueType enum. Use UntypedValue to mark a metric
-// with an unknown type.
-const (
- _ ValueType = iota
- CounterValue
- GaugeValue
- UntypedValue
-)
-
-var (
- CounterMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_COUNTER; return &d }()
- GaugeMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_GAUGE; return &d }()
- UntypedMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_UNTYPED; return &d }()
-)
-
-func (v ValueType) ToDTO() *dto.MetricType {
- switch v {
- case CounterValue:
- return CounterMetricTypePtr
- case GaugeValue:
- return GaugeMetricTypePtr
- default:
- return UntypedMetricTypePtr
- }
-}
-
-// valueFunc is a generic metric for simple values retrieved on collect time
-// from a function. It implements Metric and Collector. Its effective type is
-// determined by ValueType. This is a low-level building block used by the
-// library to back the implementations of CounterFunc, GaugeFunc, and
-// UntypedFunc.
-type valueFunc struct {
- selfCollector
-
- desc *Desc
- valType ValueType
- function func() float64
- labelPairs []*dto.LabelPair
-}
-
-// newValueFunc returns a newly allocated valueFunc with the given Desc and
-// ValueType. The value reported is determined by calling the given function
-// from within the Write method. Take into account that metric collection may
-// happen concurrently. If that results in concurrent calls to Write, like in
-// the case where a valueFunc is directly registered with Prometheus, the
-// provided function must be concurrency-safe.
-func newValueFunc(desc *Desc, valueType ValueType, function func() float64) *valueFunc {
- result := &valueFunc{
- desc: desc,
- valType: valueType,
- function: function,
- labelPairs: MakeLabelPairs(desc, nil),
- }
- result.init(result)
- return result
-}
-
-func (v *valueFunc) Desc() *Desc {
- return v.desc
-}
-
-func (v *valueFunc) Write(out *dto.Metric) error {
- return populateMetric(v.valType, v.function(), v.labelPairs, nil, out, nil)
-}
-
-// NewConstMetric returns a metric with one fixed value that cannot be
-// changed. Users of this package will not have much use for it in regular
-// operations. However, when implementing custom Collectors, it is useful as a
-// throw-away metric that is generated on the fly to send it to Prometheus in
-// the Collect method. NewConstMetric returns an error if the length of
-// labelValues is not consistent with the variable labels in Desc or if Desc is
-// invalid.
-func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {
- if desc.err != nil {
- return nil, desc.err
- }
- if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
- return nil, err
- }
-
- metric := &dto.Metric{}
- if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, nil); err != nil {
- return nil, err
- }
-
- return &constMetric{
- desc: desc,
- metric: metric,
- }, nil
-}
-
-// MustNewConstMetric is a version of NewConstMetric that panics where
-// NewConstMetric would have returned an error.
-func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric {
- m, err := NewConstMetric(desc, valueType, value, labelValues...)
- if err != nil {
- panic(err)
- }
- return m
-}
-
-// NewConstMetricWithCreatedTimestamp does the same thing as NewConstMetric, but generates Counters
-// with created timestamp set and returns an error for other metric types.
-func NewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) (Metric, error) {
- if desc.err != nil {
- return nil, desc.err
- }
- if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
- return nil, err
- }
- switch valueType {
- case CounterValue:
- break
- default:
- return nil, errors.New("created timestamps are only supported for counters")
- }
-
- metric := &dto.Metric{}
- if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, timestamppb.New(ct)); err != nil {
- return nil, err
- }
-
- return &constMetric{
- desc: desc,
- metric: metric,
- }, nil
-}
-
-// MustNewConstMetricWithCreatedTimestamp is a version of NewConstMetricWithCreatedTimestamp that panics where
-// NewConstMetricWithCreatedTimestamp would have returned an error.
-func MustNewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) Metric {
- m, err := NewConstMetricWithCreatedTimestamp(desc, valueType, value, ct, labelValues...)
- if err != nil {
- panic(err)
- }
- return m
-}
-
-type constMetric struct {
- desc *Desc
- metric *dto.Metric
-}
-
-func (m *constMetric) Desc() *Desc {
- return m.desc
-}
-
-func (m *constMetric) Write(out *dto.Metric) error {
- out.Label = m.metric.Label
- out.Counter = m.metric.Counter
- out.Gauge = m.metric.Gauge
- out.Untyped = m.metric.Untyped
- return nil
-}
-
-func populateMetric(
- t ValueType,
- v float64,
- labelPairs []*dto.LabelPair,
- e *dto.Exemplar,
- m *dto.Metric,
- ct *timestamppb.Timestamp,
-) error {
- m.Label = labelPairs
- switch t {
- case CounterValue:
- m.Counter = &dto.Counter{Value: proto.Float64(v), Exemplar: e, CreatedTimestamp: ct}
- case GaugeValue:
- m.Gauge = &dto.Gauge{Value: proto.Float64(v)}
- case UntypedValue:
- m.Untyped = &dto.Untyped{Value: proto.Float64(v)}
- default:
- return fmt.Errorf("encountered unknown type %v", t)
- }
- return nil
-}
-
-// MakeLabelPairs is a helper function to create protobuf LabelPairs from the
-// variable and constant labels in the provided Desc. The values for the
-// variable labels are defined by the labelValues slice, which must be in the
-// same order as the corresponding variable labels in the Desc.
-//
-// This function is only needed for custom Metric implementations. See MetricVec
-// example.
-func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair {
- totalLen := len(desc.variableLabels.names) + len(desc.constLabelPairs)
- if totalLen == 0 {
- // Super fast path.
- return nil
- }
- if len(desc.variableLabels.names) == 0 {
- // Moderately fast path.
- return desc.constLabelPairs
- }
- labelPairs := make([]*dto.LabelPair, 0, totalLen)
- for i, l := range desc.variableLabels.names {
- labelPairs = append(labelPairs, &dto.LabelPair{
- Name: proto.String(l),
- Value: proto.String(labelValues[i]),
- })
- }
- labelPairs = append(labelPairs, desc.constLabelPairs...)
- sort.Sort(internal.LabelPairSorter(labelPairs))
- return labelPairs
-}
-
-// ExemplarMaxRunes is the max total number of runes allowed in exemplar labels.
-const ExemplarMaxRunes = 128
-
-// newExemplar creates a new dto.Exemplar from the provided values. An error is
-// returned if any of the label names or values are invalid or if the total
-// number of runes in the label names and values exceeds ExemplarMaxRunes.
-func newExemplar(value float64, ts time.Time, l Labels) (*dto.Exemplar, error) {
- e := &dto.Exemplar{}
- e.Value = proto.Float64(value)
- tsProto := timestamppb.New(ts)
- if err := tsProto.CheckValid(); err != nil {
- return nil, err
- }
- e.Timestamp = tsProto
- labelPairs := make([]*dto.LabelPair, 0, len(l))
- var runes int
- for name, value := range l {
- if !checkLabelName(name) {
- return nil, fmt.Errorf("exemplar label name %q is invalid", name)
- }
- runes += utf8.RuneCountInString(name)
- if !utf8.ValidString(value) {
- return nil, fmt.Errorf("exemplar label value %q is not valid UTF-8", value)
- }
- runes += utf8.RuneCountInString(value)
- labelPairs = append(labelPairs, &dto.LabelPair{
- Name: proto.String(name),
- Value: proto.String(value),
- })
- }
- if runes > ExemplarMaxRunes {
- return nil, fmt.Errorf("exemplar labels have %d runes, exceeding the limit of %d", runes, ExemplarMaxRunes)
- }
- e.Label = labelPairs
- return e, nil
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go
deleted file mode 100644
index 2c808eece..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go
+++ /dev/null
@@ -1,709 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "fmt"
- "sync"
-
- "github.com/prometheus/common/model"
-)
-
-// MetricVec is a Collector to bundle metrics of the same name that differ in
-// their label values. MetricVec is not used directly but as a building block
-// for implementations of vectors of a given metric type, like GaugeVec,
-// CounterVec, SummaryVec, and HistogramVec. It is exported so that it can be
-// used for custom Metric implementations.
-//
-// To create a FooVec for custom Metric Foo, embed a pointer to MetricVec in
-// FooVec and initialize it with NewMetricVec. Implement wrappers for
-// GetMetricWithLabelValues and GetMetricWith that return (Foo, error) rather
-// than (Metric, error). Similarly, create a wrapper for CurryWith that returns
-// (*FooVec, error) rather than (*MetricVec, error). It is recommended to also
-// add the convenience methods WithLabelValues, With, and MustCurryWith, which
-// panic instead of returning errors. See also the MetricVec example.
-type MetricVec struct {
- *metricMap
-
- curry []curriedLabelValue
-
- // hashAdd and hashAddByte can be replaced for testing collision handling.
- hashAdd func(h uint64, s string) uint64
- hashAddByte func(h uint64, b byte) uint64
-}
-
-// NewMetricVec returns an initialized metricVec.
-func NewMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec {
- return &MetricVec{
- metricMap: &metricMap{
- metrics: map[uint64][]metricWithLabelValues{},
- desc: desc,
- newMetric: newMetric,
- },
- hashAdd: hashAdd,
- hashAddByte: hashAddByte,
- }
-}
-
-// DeleteLabelValues removes the metric where the variable labels are the same
-// as those passed in as labels (same order as the VariableLabels in Desc). It
-// returns true if a metric was deleted.
-//
-// It is not an error if the number of label values is not the same as the
-// number of VariableLabels in Desc. However, such inconsistent label count can
-// never match an actual metric, so the method will always return false in that
-// case.
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider Delete(Labels) as an
-// alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the CounterVec example.
-func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
- lvs = constrainLabelValues(m.desc, lvs, m.curry)
-
- h, err := m.hashLabelValues(lvs)
- if err != nil {
- return false
- }
-
- return m.metricMap.deleteByHashWithLabelValues(h, lvs, m.curry)
-}
-
-// Delete deletes the metric where the variable labels are the same as those
-// passed in as labels. It returns true if a metric was deleted.
-//
-// It is not an error if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc. However, such inconsistent Labels
-// can never match an actual metric, so the method will always return false in
-// that case.
-//
-// This method is used for the same purpose as DeleteLabelValues(...string). See
-// there for pros and cons of the two methods.
-func (m *MetricVec) Delete(labels Labels) bool {
- labels, closer := constrainLabels(m.desc, labels)
- defer closer()
-
- h, err := m.hashLabels(labels)
- if err != nil {
- return false
- }
-
- return m.metricMap.deleteByHashWithLabels(h, labels, m.curry)
-}
-
-// DeletePartialMatch deletes all metrics where the variable labels contain all of those
-// passed in as labels. The order of the labels does not matter.
-// It returns the number of metrics deleted.
-//
-// Note that curried labels will never be matched if deleting from the curried vector.
-// To match curried labels with DeletePartialMatch, it must be called on the base vector.
-func (m *MetricVec) DeletePartialMatch(labels Labels) int {
- labels, closer := constrainLabels(m.desc, labels)
- defer closer()
-
- return m.metricMap.deleteByLabels(labels, m.curry)
-}
-
-// Without explicit forwarding of Describe, Collect, Reset, those methods won't
-// show up in GoDoc.
-
-// Describe implements Collector.
-func (m *MetricVec) Describe(ch chan<- *Desc) { m.metricMap.Describe(ch) }
-
-// Collect implements Collector.
-func (m *MetricVec) Collect(ch chan<- Metric) { m.metricMap.Collect(ch) }
-
-// Reset deletes all metrics in this vector.
-func (m *MetricVec) Reset() { m.metricMap.Reset() }
-
-// CurryWith returns a vector curried with the provided labels, i.e. the
-// returned vector has those labels pre-set for all labeled operations performed
-// on it. The cardinality of the curried vector is reduced accordingly. The
-// order of the remaining labels stays the same (just with the curried labels
-// taken out of the sequence – which is relevant for the
-// (GetMetric)WithLabelValues methods). It is possible to curry a curried
-// vector, but only with labels not yet used for currying before.
-//
-// The metrics contained in the MetricVec are shared between the curried and
-// uncurried vectors. They are just accessed differently. Curried and uncurried
-// vectors behave identically in terms of collection. Only one must be
-// registered with a given registry (usually the uncurried version). The Reset
-// method deletes all metrics, even if called on a curried vector.
-//
-// Note that CurryWith is usually not called directly but through a wrapper
-// around MetricVec, implementing a vector for a specific Metric
-// implementation, for example GaugeVec.
-func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) {
- var (
- newCurry []curriedLabelValue
- oldCurry = m.curry
- iCurry int
- )
- for i, labelName := range m.desc.variableLabels.names {
- val, ok := labels[labelName]
- if iCurry < len(oldCurry) && oldCurry[iCurry].index == i {
- if ok {
- return nil, fmt.Errorf("label name %q is already curried", labelName)
- }
- newCurry = append(newCurry, oldCurry[iCurry])
- iCurry++
- } else {
- if !ok {
- continue // Label stays uncurried.
- }
- newCurry = append(newCurry, curriedLabelValue{
- i,
- m.desc.variableLabels.constrain(labelName, val),
- })
- }
- }
- if l := len(oldCurry) + len(labels) - len(newCurry); l > 0 {
- return nil, fmt.Errorf("%d unknown label(s) found during currying", l)
- }
-
- return &MetricVec{
- metricMap: m.metricMap,
- curry: newCurry,
- hashAdd: m.hashAdd,
- hashAddByte: m.hashAddByte,
- }, nil
-}
-
-// GetMetricWithLabelValues returns the Metric for the given slice of label
-// values (same order as the variable labels in Desc). If that combination of
-// label values is accessed for the first time, a new Metric is created (by
-// calling the newMetric function provided during construction of the
-// MetricVec).
-//
-// It is possible to call this method without using the returned Metric to only
-// create the new Metric but leave it in its initial state.
-//
-// Keeping the Metric for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Metric from the MetricVec. In that case, the
-// Metric will still exist, but it will not be exported anymore, even if a
-// Metric with the same label values is created later.
-//
-// An error is returned if the number of label values is not the same as the
-// number of variable labels in Desc (minus any curried labels).
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-//
-// Note that GetMetricWithLabelValues is usually not called directly but through
-// a wrapper around MetricVec, implementing a vector for a specific Metric
-// implementation, for example GaugeVec.
-func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
- lvs = constrainLabelValues(m.desc, lvs, m.curry)
- h, err := m.hashLabelValues(lvs)
- if err != nil {
- return nil, err
- }
-
- return m.metricMap.getOrCreateMetricWithLabelValues(h, lvs, m.curry), nil
-}
-
-// GetMetricWith returns the Metric for the given Labels map (the label names
-// must match those of the variable labels in Desc). If that label map is
-// accessed for the first time, a new Metric is created. Implications of
-// creating a Metric without using it and keeping the Metric for later use
-// are the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the variable labels in Desc (minus any curried labels).
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-//
-// Note that GetMetricWith is usually not called directly but through a wrapper
-// around MetricVec, implementing a vector for a specific Metric implementation,
-// for example GaugeVec.
-func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
- labels, closer := constrainLabels(m.desc, labels)
- defer closer()
-
- h, err := m.hashLabels(labels)
- if err != nil {
- return nil, err
- }
-
- return m.metricMap.getOrCreateMetricWithLabels(h, labels, m.curry), nil
-}
-
-func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
- if err := validateLabelValues(vals, len(m.desc.variableLabels.names)-len(m.curry)); err != nil {
- return 0, err
- }
-
- var (
- h = hashNew()
- curry = m.curry
- iVals, iCurry int
- )
- for i := 0; i < len(m.desc.variableLabels.names); i++ {
- if iCurry < len(curry) && curry[iCurry].index == i {
- h = m.hashAdd(h, curry[iCurry].value)
- iCurry++
- } else {
- h = m.hashAdd(h, vals[iVals])
- iVals++
- }
- h = m.hashAddByte(h, model.SeparatorByte)
- }
- return h, nil
-}
-
-func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
- if err := validateValuesInLabels(labels, len(m.desc.variableLabels.names)-len(m.curry)); err != nil {
- return 0, err
- }
-
- var (
- h = hashNew()
- curry = m.curry
- iCurry int
- )
- for i, labelName := range m.desc.variableLabels.names {
- val, ok := labels[labelName]
- if iCurry < len(curry) && curry[iCurry].index == i {
- if ok {
- return 0, fmt.Errorf("label name %q is already curried", labelName)
- }
- h = m.hashAdd(h, curry[iCurry].value)
- iCurry++
- } else {
- if !ok {
- return 0, fmt.Errorf("label name %q missing in label map", labelName)
- }
- h = m.hashAdd(h, val)
- }
- h = m.hashAddByte(h, model.SeparatorByte)
- }
- return h, nil
-}
-
-// metricWithLabelValues provides the metric and its label values for
-// disambiguation on hash collision.
-type metricWithLabelValues struct {
- values []string
- metric Metric
-}
-
-// curriedLabelValue sets the curried value for a label at the given index.
-type curriedLabelValue struct {
- index int
- value string
-}
-
-// metricMap is a helper for metricVec and shared between differently curried
-// metricVecs.
-type metricMap struct {
- mtx sync.RWMutex // Protects metrics.
- metrics map[uint64][]metricWithLabelValues
- desc *Desc
- newMetric func(labelValues ...string) Metric
-}
-
-// Describe implements Collector. It will send exactly one Desc to the provided
-// channel.
-func (m *metricMap) Describe(ch chan<- *Desc) {
- ch <- m.desc
-}
-
-// Collect implements Collector.
-func (m *metricMap) Collect(ch chan<- Metric) {
- m.mtx.RLock()
- defer m.mtx.RUnlock()
-
- for _, metrics := range m.metrics {
- for _, metric := range metrics {
- ch <- metric.metric
- }
- }
-}
-
-// Reset deletes all metrics in this vector.
-func (m *metricMap) Reset() {
- m.mtx.Lock()
- defer m.mtx.Unlock()
-
- for h := range m.metrics {
- delete(m.metrics, h)
- }
-}
-
-// deleteByHashWithLabelValues removes the metric from the hash bucket h. If
-// there are multiple matches in the bucket, use lvs to select a metric and
-// remove only that metric.
-func (m *metricMap) deleteByHashWithLabelValues(
- h uint64, lvs []string, curry []curriedLabelValue,
-) bool {
- m.mtx.Lock()
- defer m.mtx.Unlock()
-
- metrics, ok := m.metrics[h]
- if !ok {
- return false
- }
-
- i := findMetricWithLabelValues(metrics, lvs, curry)
- if i >= len(metrics) {
- return false
- }
-
- if len(metrics) > 1 {
- old := metrics
- m.metrics[h] = append(metrics[:i], metrics[i+1:]...)
- old[len(old)-1] = metricWithLabelValues{}
- } else {
- delete(m.metrics, h)
- }
- return true
-}
-
-// deleteByHashWithLabels removes the metric from the hash bucket h. If there
-// are multiple matches in the bucket, use lvs to select a metric and remove
-// only that metric.
-func (m *metricMap) deleteByHashWithLabels(
- h uint64, labels Labels, curry []curriedLabelValue,
-) bool {
- m.mtx.Lock()
- defer m.mtx.Unlock()
-
- metrics, ok := m.metrics[h]
- if !ok {
- return false
- }
- i := findMetricWithLabels(m.desc, metrics, labels, curry)
- if i >= len(metrics) {
- return false
- }
-
- if len(metrics) > 1 {
- old := metrics
- m.metrics[h] = append(metrics[:i], metrics[i+1:]...)
- old[len(old)-1] = metricWithLabelValues{}
- } else {
- delete(m.metrics, h)
- }
- return true
-}
-
-// deleteByLabels deletes a metric if the given labels are present in the metric.
-func (m *metricMap) deleteByLabels(labels Labels, curry []curriedLabelValue) int {
- m.mtx.Lock()
- defer m.mtx.Unlock()
-
- var numDeleted int
-
- for h, metrics := range m.metrics {
- i := findMetricWithPartialLabels(m.desc, metrics, labels, curry)
- if i >= len(metrics) {
- // Didn't find matching labels in this metric slice.
- continue
- }
- delete(m.metrics, h)
- numDeleted++
- }
-
- return numDeleted
-}
-
-// findMetricWithPartialLabel returns the index of the matching metric or
-// len(metrics) if not found.
-func findMetricWithPartialLabels(
- desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue,
-) int {
- for i, metric := range metrics {
- if matchPartialLabels(desc, metric.values, labels, curry) {
- return i
- }
- }
- return len(metrics)
-}
-
-// indexOf searches the given slice of strings for the target string and returns
-// the index or len(items) as well as a boolean whether the search succeeded.
-func indexOf(target string, items []string) (int, bool) {
- for i, l := range items {
- if l == target {
- return i, true
- }
- }
- return len(items), false
-}
-
-// valueMatchesVariableOrCurriedValue determines if a value was previously curried,
-// and returns whether it matches either the "base" value or the curried value accordingly.
-// It also indicates whether the match is against a curried or uncurried value.
-func valueMatchesVariableOrCurriedValue(targetValue string, index int, values []string, curry []curriedLabelValue) (bool, bool) {
- for _, curriedValue := range curry {
- if curriedValue.index == index {
- // This label was curried. See if the curried value matches our target.
- return curriedValue.value == targetValue, true
- }
- }
- // This label was not curried. See if the current value matches our target label.
- return values[index] == targetValue, false
-}
-
-// matchPartialLabels searches the current metric and returns whether all of the target label:value pairs are present.
-func matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool {
- for l, v := range labels {
- // Check if the target label exists in our metrics and get the index.
- varLabelIndex, validLabel := indexOf(l, desc.variableLabels.names)
- if validLabel {
- // Check the value of that label against the target value.
- // We don't consider curried values in partial matches.
- matches, curried := valueMatchesVariableOrCurriedValue(v, varLabelIndex, values, curry)
- if matches && !curried {
- continue
- }
- }
- return false
- }
- return true
-}
-
-// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value
-// or creates it and returns the new one.
-//
-// This function holds the mutex.
-func (m *metricMap) getOrCreateMetricWithLabelValues(
- hash uint64, lvs []string, curry []curriedLabelValue,
-) Metric {
- m.mtx.RLock()
- metric, ok := m.getMetricWithHashAndLabelValues(hash, lvs, curry)
- m.mtx.RUnlock()
- if ok {
- return metric
- }
-
- m.mtx.Lock()
- defer m.mtx.Unlock()
- metric, ok = m.getMetricWithHashAndLabelValues(hash, lvs, curry)
- if !ok {
- inlinedLVs := inlineLabelValues(lvs, curry)
- metric = m.newMetric(inlinedLVs...)
- m.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: inlinedLVs, metric: metric})
- }
- return metric
-}
-
-// getOrCreateMetricWithLabels retrieves the metric by hash and label value
-// or creates it and returns the new one.
-//
-// This function holds the mutex.
-func (m *metricMap) getOrCreateMetricWithLabels(
- hash uint64, labels Labels, curry []curriedLabelValue,
-) Metric {
- m.mtx.RLock()
- metric, ok := m.getMetricWithHashAndLabels(hash, labels, curry)
- m.mtx.RUnlock()
- if ok {
- return metric
- }
-
- m.mtx.Lock()
- defer m.mtx.Unlock()
- metric, ok = m.getMetricWithHashAndLabels(hash, labels, curry)
- if !ok {
- lvs := extractLabelValues(m.desc, labels, curry)
- metric = m.newMetric(lvs...)
- m.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: lvs, metric: metric})
- }
- return metric
-}
-
-// getMetricWithHashAndLabelValues gets a metric while handling possible
-// collisions in the hash space. Must be called while holding the read mutex.
-func (m *metricMap) getMetricWithHashAndLabelValues(
- h uint64, lvs []string, curry []curriedLabelValue,
-) (Metric, bool) {
- metrics, ok := m.metrics[h]
- if ok {
- if i := findMetricWithLabelValues(metrics, lvs, curry); i < len(metrics) {
- return metrics[i].metric, true
- }
- }
- return nil, false
-}
-
-// getMetricWithHashAndLabels gets a metric while handling possible collisions in
-// the hash space. Must be called while holding read mutex.
-func (m *metricMap) getMetricWithHashAndLabels(
- h uint64, labels Labels, curry []curriedLabelValue,
-) (Metric, bool) {
- metrics, ok := m.metrics[h]
- if ok {
- if i := findMetricWithLabels(m.desc, metrics, labels, curry); i < len(metrics) {
- return metrics[i].metric, true
- }
- }
- return nil, false
-}
-
-// findMetricWithLabelValues returns the index of the matching metric or
-// len(metrics) if not found.
-func findMetricWithLabelValues(
- metrics []metricWithLabelValues, lvs []string, curry []curriedLabelValue,
-) int {
- for i, metric := range metrics {
- if matchLabelValues(metric.values, lvs, curry) {
- return i
- }
- }
- return len(metrics)
-}
-
-// findMetricWithLabels returns the index of the matching metric or len(metrics)
-// if not found.
-func findMetricWithLabels(
- desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue,
-) int {
- for i, metric := range metrics {
- if matchLabels(desc, metric.values, labels, curry) {
- return i
- }
- }
- return len(metrics)
-}
-
-func matchLabelValues(values, lvs []string, curry []curriedLabelValue) bool {
- if len(values) != len(lvs)+len(curry) {
- return false
- }
- var iLVs, iCurry int
- for i, v := range values {
- if iCurry < len(curry) && curry[iCurry].index == i {
- if v != curry[iCurry].value {
- return false
- }
- iCurry++
- continue
- }
- if v != lvs[iLVs] {
- return false
- }
- iLVs++
- }
- return true
-}
-
-func matchLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool {
- if len(values) != len(labels)+len(curry) {
- return false
- }
- iCurry := 0
- for i, k := range desc.variableLabels.names {
- if iCurry < len(curry) && curry[iCurry].index == i {
- if values[i] != curry[iCurry].value {
- return false
- }
- iCurry++
- continue
- }
- if values[i] != labels[k] {
- return false
- }
- }
- return true
-}
-
-func extractLabelValues(desc *Desc, labels Labels, curry []curriedLabelValue) []string {
- labelValues := make([]string, len(labels)+len(curry))
- iCurry := 0
- for i, k := range desc.variableLabels.names {
- if iCurry < len(curry) && curry[iCurry].index == i {
- labelValues[i] = curry[iCurry].value
- iCurry++
- continue
- }
- labelValues[i] = labels[k]
- }
- return labelValues
-}
-
-func inlineLabelValues(lvs []string, curry []curriedLabelValue) []string {
- labelValues := make([]string, len(lvs)+len(curry))
- var iCurry, iLVs int
- for i := range labelValues {
- if iCurry < len(curry) && curry[iCurry].index == i {
- labelValues[i] = curry[iCurry].value
- iCurry++
- continue
- }
- labelValues[i] = lvs[iLVs]
- iLVs++
- }
- return labelValues
-}
-
-var labelsPool = &sync.Pool{
- New: func() interface{} {
- return make(Labels)
- },
-}
-
-func constrainLabels(desc *Desc, labels Labels) (Labels, func()) {
- if len(desc.variableLabels.labelConstraints) == 0 {
- // Fast path when there's no constraints
- return labels, func() {}
- }
-
- constrainedLabels := labelsPool.Get().(Labels)
- for l, v := range labels {
- constrainedLabels[l] = desc.variableLabels.constrain(l, v)
- }
-
- return constrainedLabels, func() {
- for k := range constrainedLabels {
- delete(constrainedLabels, k)
- }
- labelsPool.Put(constrainedLabels)
- }
-}
-
-func constrainLabelValues(desc *Desc, lvs []string, curry []curriedLabelValue) []string {
- if len(desc.variableLabels.labelConstraints) == 0 {
- // Fast path when there's no constraints
- return lvs
- }
-
- constrainedValues := make([]string, len(lvs))
- var iCurry, iLVs int
- for i := 0; i < len(lvs)+len(curry); i++ {
- if iCurry < len(curry) && curry[iCurry].index == i {
- iCurry++
- continue
- }
-
- if i < len(desc.variableLabels.names) {
- constrainedValues[iLVs] = desc.variableLabels.constrain(
- desc.variableLabels.names[i],
- lvs[iLVs],
- )
- } else {
- constrainedValues[iLVs] = lvs[iLVs]
- }
- iLVs++
- }
- return constrainedValues
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vnext.go b/vendor/github.com/prometheus/client_golang/prometheus/vnext.go
deleted file mode 100644
index 42bc3a8f0..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/vnext.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2022 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-type v2 struct{}
-
-// V2 is a struct that can be referenced to access experimental API that might
-// be present in v2 of client golang someday. It offers extended functionality
-// of v1 with slightly changed API. It is acceptable to use some pieces from v1
-// and e.g `prometheus.NewGauge` and some from v2 e.g. `prometheus.V2.NewDesc`
-// in the same codebase.
-var V2 = v2{}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
deleted file mode 100644
index 25da157f1..000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
- "fmt"
- "sort"
-
- "github.com/prometheus/client_golang/prometheus/internal"
-
- dto "github.com/prometheus/client_model/go"
- "google.golang.org/protobuf/proto"
-)
-
-// WrapRegistererWith returns a Registerer wrapping the provided
-// Registerer. Collectors registered with the returned Registerer will be
-// registered with the wrapped Registerer in a modified way. The modified
-// Collector adds the provided Labels to all Metrics it collects (as
-// ConstLabels). The Metrics collected by the unmodified Collector must not
-// duplicate any of those labels. Wrapping a nil value is valid, resulting
-// in a no-op Registerer.
-//
-// WrapRegistererWith provides a way to add fixed labels to a subset of
-// Collectors. It should not be used to add fixed labels to all metrics
-// exposed. See also
-// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels
-//
-// Conflicts between Collectors registered through the original Registerer with
-// Collectors registered through the wrapping Registerer will still be
-// detected. Any AlreadyRegisteredError returned by the Register method of
-// either Registerer will contain the ExistingCollector in the form it was
-// provided to the respective registry.
-//
-// The Collector example demonstrates a use of WrapRegistererWith.
-func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
- return &wrappingRegisterer{
- wrappedRegisterer: reg,
- labels: labels,
- }
-}
-
-// WrapRegistererWithPrefix returns a Registerer wrapping the provided
-// Registerer. Collectors registered with the returned Registerer will be
-// registered with the wrapped Registerer in a modified way. The modified
-// Collector adds the provided prefix to the name of all Metrics it collects.
-// Wrapping a nil value is valid, resulting in a no-op Registerer.
-//
-// WrapRegistererWithPrefix is useful to have one place to prefix all metrics of
-// a sub-system. To make this work, register metrics of the sub-system with the
-// wrapping Registerer returned by WrapRegistererWithPrefix. It is rarely useful
-// to use the same prefix for all metrics exposed. In particular, do not prefix
-// metric names that are standardized across applications, as that would break
-// horizontal monitoring, for example the metrics provided by the Go collector
-// (see NewGoCollector) and the process collector (see NewProcessCollector). (In
-// fact, those metrics are already prefixed with “go_” or “process_”,
-// respectively.)
-//
-// Conflicts between Collectors registered through the original Registerer with
-// Collectors registered through the wrapping Registerer will still be
-// detected. Any AlreadyRegisteredError returned by the Register method of
-// either Registerer will contain the ExistingCollector in the form it was
-// provided to the respective registry.
-func WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer {
- return &wrappingRegisterer{
- wrappedRegisterer: reg,
- prefix: prefix,
- }
-}
-
-type wrappingRegisterer struct {
- wrappedRegisterer Registerer
- prefix string
- labels Labels
-}
-
-func (r *wrappingRegisterer) Register(c Collector) error {
- if r.wrappedRegisterer == nil {
- return nil
- }
- return r.wrappedRegisterer.Register(&wrappingCollector{
- wrappedCollector: c,
- prefix: r.prefix,
- labels: r.labels,
- })
-}
-
-func (r *wrappingRegisterer) MustRegister(cs ...Collector) {
- if r.wrappedRegisterer == nil {
- return
- }
- for _, c := range cs {
- if err := r.Register(c); err != nil {
- panic(err)
- }
- }
-}
-
-func (r *wrappingRegisterer) Unregister(c Collector) bool {
- if r.wrappedRegisterer == nil {
- return false
- }
- return r.wrappedRegisterer.Unregister(&wrappingCollector{
- wrappedCollector: c,
- prefix: r.prefix,
- labels: r.labels,
- })
-}
-
-type wrappingCollector struct {
- wrappedCollector Collector
- prefix string
- labels Labels
-}
-
-func (c *wrappingCollector) Collect(ch chan<- Metric) {
- wrappedCh := make(chan Metric)
- go func() {
- c.wrappedCollector.Collect(wrappedCh)
- close(wrappedCh)
- }()
- for m := range wrappedCh {
- ch <- &wrappingMetric{
- wrappedMetric: m,
- prefix: c.prefix,
- labels: c.labels,
- }
- }
-}
-
-func (c *wrappingCollector) Describe(ch chan<- *Desc) {
- wrappedCh := make(chan *Desc)
- go func() {
- c.wrappedCollector.Describe(wrappedCh)
- close(wrappedCh)
- }()
- for desc := range wrappedCh {
- ch <- wrapDesc(desc, c.prefix, c.labels)
- }
-}
-
-func (c *wrappingCollector) unwrapRecursively() Collector {
- switch wc := c.wrappedCollector.(type) {
- case *wrappingCollector:
- return wc.unwrapRecursively()
- default:
- return wc
- }
-}
-
-type wrappingMetric struct {
- wrappedMetric Metric
- prefix string
- labels Labels
-}
-
-func (m *wrappingMetric) Desc() *Desc {
- return wrapDesc(m.wrappedMetric.Desc(), m.prefix, m.labels)
-}
-
-func (m *wrappingMetric) Write(out *dto.Metric) error {
- if err := m.wrappedMetric.Write(out); err != nil {
- return err
- }
- if len(m.labels) == 0 {
- // No wrapping labels.
- return nil
- }
- for ln, lv := range m.labels {
- out.Label = append(out.Label, &dto.LabelPair{
- Name: proto.String(ln),
- Value: proto.String(lv),
- })
- }
- sort.Sort(internal.LabelPairSorter(out.Label))
- return nil
-}
-
-func wrapDesc(desc *Desc, prefix string, labels Labels) *Desc {
- constLabels := Labels{}
- for _, lp := range desc.constLabelPairs {
- constLabels[*lp.Name] = *lp.Value
- }
- for ln, lv := range labels {
- if _, alreadyUsed := constLabels[ln]; alreadyUsed {
- return &Desc{
- fqName: desc.fqName,
- help: desc.help,
- variableLabels: desc.variableLabels,
- constLabelPairs: desc.constLabelPairs,
- err: fmt.Errorf("attempted wrapping with already existing label name %q", ln),
- }
- }
- constLabels[ln] = lv
- }
- // NewDesc will do remaining validations.
- newDesc := V2.NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels)
- // Propagate errors if there was any. This will override any errer
- // created by NewDesc above, i.e. earlier errors get precedence.
- if desc.err != nil {
- newDesc.err = desc.err
- }
- return newDesc
-}