[chore]: Bump github.com/prometheus/client_golang from 1.20.5 to 1.21.0 (#3860)
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.5 to 1.21.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.5...v1.21.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
861b5cd920
commit
ddd9210614
4
go.mod
4
go.mod
|
@ -55,7 +55,7 @@ require (
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/ncruces/go-sqlite3 v0.24.0
|
github.com/ncruces/go-sqlite3 v0.24.0
|
||||||
github.com/oklog/ulid v1.3.1
|
github.com/oklog/ulid v1.3.1
|
||||||
github.com/prometheus/client_golang v1.20.5
|
github.com/prometheus/client_golang v1.21.0
|
||||||
github.com/rivo/uniseg v0.4.7
|
github.com/rivo/uniseg v0.4.7
|
||||||
github.com/spf13/cobra v1.9.1
|
github.com/spf13/cobra v1.9.1
|
||||||
github.com/spf13/viper v1.19.0
|
github.com/spf13/viper v1.19.0
|
||||||
|
@ -184,7 +184,7 @@ require (
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.61.0 // indirect
|
github.com/prometheus/common v0.62.0 // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.0 // indirect
|
github.com/puzpuzpuz/xsync/v3 v3.5.0 // indirect
|
||||||
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect
|
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect
|
||||||
|
|
|
@ -343,12 +343,12 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
|
||||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ=
|
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||||
github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
|
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.0 h1:i+cMcpEDY1BkNm7lPDkCtE4oElsYLn+EKF8kAu2vXT4=
|
github.com/puzpuzpuz/xsync/v3 v3.5.0 h1:i+cMcpEDY1BkNm7lPDkCtE4oElsYLn+EKF8kAu2vXT4=
|
||||||
|
|
50
vendor/github.com/prometheus/client_golang/prometheus/atomic_update.go
generated
vendored
Normal file
50
vendor/github.com/prometheus/client_golang/prometheus/atomic_update.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// atomicUpdateFloat atomically updates the float64 value pointed to by bits
|
||||||
|
// using the provided updateFunc, with an exponential backoff on contention.
|
||||||
|
func atomicUpdateFloat(bits *uint64, updateFunc func(float64) float64) {
|
||||||
|
const (
|
||||||
|
// both numbers are derived from empirical observations
|
||||||
|
// documented in this PR: https://github.com/prometheus/client_golang/pull/1661
|
||||||
|
maxBackoff = 320 * time.Millisecond
|
||||||
|
initialBackoff = 10 * time.Millisecond
|
||||||
|
)
|
||||||
|
backoff := initialBackoff
|
||||||
|
|
||||||
|
for {
|
||||||
|
loadedBits := atomic.LoadUint64(bits)
|
||||||
|
oldFloat := math.Float64frombits(loadedBits)
|
||||||
|
newFloat := updateFunc(oldFloat)
|
||||||
|
newBits := math.Float64bits(newFloat)
|
||||||
|
|
||||||
|
if atomic.CompareAndSwapUint64(bits, loadedBits, newBits) {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
// Exponential backoff with sleep and cap to avoid infinite wait
|
||||||
|
time.Sleep(backoff)
|
||||||
|
backoff *= 2
|
||||||
|
if backoff > maxBackoff {
|
||||||
|
backoff = maxBackoff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -134,13 +134,9 @@ func (c *counter) Add(v float64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
atomicUpdateFloat(&c.valBits, func(oldVal float64) float64 {
|
||||||
oldBits := atomic.LoadUint64(&c.valBits)
|
return oldVal + v
|
||||||
newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
|
})
|
||||||
if atomic.CompareAndSwapUint64(&c.valBits, oldBits, newBits) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *counter) AddWithExemplar(v float64, e Labels) {
|
func (c *counter) AddWithExemplar(v float64, e Labels) {
|
||||||
|
|
|
@ -189,12 +189,15 @@ func (d *Desc) String() string {
|
||||||
fmt.Sprintf("%s=%q", lp.GetName(), lp.GetValue()),
|
fmt.Sprintf("%s=%q", lp.GetName(), lp.GetValue()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
vlStrings := make([]string, 0, len(d.variableLabels.names))
|
vlStrings := []string{}
|
||||||
for _, vl := range d.variableLabels.names {
|
if d.variableLabels != nil {
|
||||||
if fn, ok := d.variableLabels.labelConstraints[vl]; ok && fn != nil {
|
vlStrings = make([]string, 0, len(d.variableLabels.names))
|
||||||
vlStrings = append(vlStrings, fmt.Sprintf("c(%s)", vl))
|
for _, vl := range d.variableLabels.names {
|
||||||
} else {
|
if fn, ok := d.variableLabels.labelConstraints[vl]; ok && fn != nil {
|
||||||
vlStrings = append(vlStrings, vl)
|
vlStrings = append(vlStrings, fmt.Sprintf("c(%s)", vl))
|
||||||
|
} else {
|
||||||
|
vlStrings = append(vlStrings, vl)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
|
|
|
@ -120,13 +120,9 @@ func (g *gauge) Dec() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *gauge) Add(val float64) {
|
func (g *gauge) Add(val float64) {
|
||||||
for {
|
atomicUpdateFloat(&g.valBits, func(oldVal float64) float64 {
|
||||||
oldBits := atomic.LoadUint64(&g.valBits)
|
return oldVal + val
|
||||||
newBits := math.Float64bits(math.Float64frombits(oldBits) + val)
|
})
|
||||||
if atomic.CompareAndSwapUint64(&g.valBits, oldBits, newBits) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *gauge) Sub(val float64) {
|
func (g *gauge) Sub(val float64) {
|
||||||
|
|
|
@ -288,7 +288,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
|
||||||
}
|
}
|
||||||
|
|
||||||
func attachOriginalName(desc, origName string) string {
|
func attachOriginalName(desc, origName string) string {
|
||||||
return fmt.Sprintf("%s Sourced from %s", desc, origName)
|
return fmt.Sprintf("%s Sourced from %s.", desc, origName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe returns all descriptions of the collector.
|
// Describe returns all descriptions of the collector.
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
package prometheus
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -28,6 +29,11 @@ import (
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
nativeHistogramSchemaMaximum = 8
|
||||||
|
nativeHistogramSchemaMinimum = -4
|
||||||
|
)
|
||||||
|
|
||||||
// nativeHistogramBounds for the frac of observed values. Only relevant for
|
// 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
|
// 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.)
|
// here for convenience of using the schema directly as the index.)
|
||||||
|
@ -330,11 +336,11 @@ func ExponentialBuckets(start, factor float64, count int) []float64 {
|
||||||
// used for the Buckets field of HistogramOpts.
|
// used for the Buckets field of HistogramOpts.
|
||||||
//
|
//
|
||||||
// The function panics if 'count' is 0 or negative, if 'min' is 0 or negative.
|
// The function panics if 'count' is 0 or negative, if 'min' is 0 or negative.
|
||||||
func ExponentialBucketsRange(min, max float64, count int) []float64 {
|
func ExponentialBucketsRange(minBucket, maxBucket float64, count int) []float64 {
|
||||||
if count < 1 {
|
if count < 1 {
|
||||||
panic("ExponentialBucketsRange count needs a positive count")
|
panic("ExponentialBucketsRange count needs a positive count")
|
||||||
}
|
}
|
||||||
if min <= 0 {
|
if minBucket <= 0 {
|
||||||
panic("ExponentialBucketsRange min needs to be greater than 0")
|
panic("ExponentialBucketsRange min needs to be greater than 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,12 +348,12 @@ func ExponentialBucketsRange(min, max float64, count int) []float64 {
|
||||||
// max = min*growthFactor^(bucketCount-1)
|
// max = min*growthFactor^(bucketCount-1)
|
||||||
|
|
||||||
// We know max/min and highest bucket. Solve for growthFactor.
|
// We know max/min and highest bucket. Solve for growthFactor.
|
||||||
growthFactor := math.Pow(max/min, 1.0/float64(count-1))
|
growthFactor := math.Pow(maxBucket/minBucket, 1.0/float64(count-1))
|
||||||
|
|
||||||
// Now that we know growthFactor, solve for each bucket.
|
// Now that we know growthFactor, solve for each bucket.
|
||||||
buckets := make([]float64, count)
|
buckets := make([]float64, count)
|
||||||
for i := 1; i <= count; i++ {
|
for i := 1; i <= count; i++ {
|
||||||
buckets[i-1] = min * math.Pow(growthFactor, float64(i-1))
|
buckets[i-1] = minBucket * math.Pow(growthFactor, float64(i-1))
|
||||||
}
|
}
|
||||||
return buckets
|
return buckets
|
||||||
}
|
}
|
||||||
|
@ -858,15 +864,35 @@ func (h *histogram) Write(out *dto.Metric) error {
|
||||||
// findBucket returns the index of the bucket for the provided value, or
|
// findBucket returns the index of the bucket for the provided value, or
|
||||||
// len(h.upperBounds) for the +Inf bucket.
|
// len(h.upperBounds) for the +Inf bucket.
|
||||||
func (h *histogram) findBucket(v float64) int {
|
func (h *histogram) findBucket(v float64) int {
|
||||||
// TODO(beorn7): For small numbers of buckets (<30), a linear search is
|
n := len(h.upperBounds)
|
||||||
// slightly faster than the binary search. If we really care, we could
|
if n == 0 {
|
||||||
// switch from one search strategy to the other depending on the number
|
return 0
|
||||||
// of buckets.
|
}
|
||||||
//
|
|
||||||
// Microbenchmarks (BenchmarkHistogramNoLabels):
|
// Early exit: if v is less than or equal to the first upper bound, return 0
|
||||||
// 11 buckets: 38.3 ns/op linear - binary 48.7 ns/op
|
if v <= h.upperBounds[0] {
|
||||||
// 100 buckets: 78.1 ns/op linear - binary 54.9 ns/op
|
return 0
|
||||||
// 300 buckets: 154 ns/op linear - binary 61.6 ns/op
|
}
|
||||||
|
|
||||||
|
// Early exit: if v is greater than the last upper bound, return len(h.upperBounds)
|
||||||
|
if v > h.upperBounds[n-1] {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// For small arrays, use simple linear search
|
||||||
|
// "magic number" 35 is result of tests on couple different (AWS and baremetal) servers
|
||||||
|
// see more details here: https://github.com/prometheus/client_golang/pull/1662
|
||||||
|
if n < 35 {
|
||||||
|
for i, bound := range h.upperBounds {
|
||||||
|
if v <= bound {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If v is greater than all upper bounds, return len(h.upperBounds)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// For larger arrays, use stdlib's binary search
|
||||||
return sort.SearchFloat64s(h.upperBounds, v)
|
return sort.SearchFloat64s(h.upperBounds, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1440,9 +1466,9 @@ func pickSchema(bucketFactor float64) int32 {
|
||||||
floor := math.Floor(math.Log2(math.Log2(bucketFactor)))
|
floor := math.Floor(math.Log2(math.Log2(bucketFactor)))
|
||||||
switch {
|
switch {
|
||||||
case floor <= -8:
|
case floor <= -8:
|
||||||
return 8
|
return nativeHistogramSchemaMaximum
|
||||||
case floor >= 4:
|
case floor >= 4:
|
||||||
return -4
|
return nativeHistogramSchemaMinimum
|
||||||
default:
|
default:
|
||||||
return -int32(floor)
|
return -int32(floor)
|
||||||
}
|
}
|
||||||
|
@ -1621,13 +1647,9 @@ func waitForCooldown(count uint64, counts *histogramCounts) {
|
||||||
// atomicAddFloat adds the provided float atomically to another float
|
// atomicAddFloat adds the provided float atomically to another float
|
||||||
// represented by the bit pattern the bits pointer is pointing to.
|
// represented by the bit pattern the bits pointer is pointing to.
|
||||||
func atomicAddFloat(bits *uint64, v float64) {
|
func atomicAddFloat(bits *uint64, v float64) {
|
||||||
for {
|
atomicUpdateFloat(bits, func(oldVal float64) float64 {
|
||||||
loadedBits := atomic.LoadUint64(bits)
|
return oldVal + v
|
||||||
newBits := math.Float64bits(math.Float64frombits(loadedBits) + v)
|
})
|
||||||
if atomic.CompareAndSwapUint64(bits, loadedBits, newBits) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// atomicDecUint32 atomically decrements the uint32 p points to. See
|
// atomicDecUint32 atomically decrements the uint32 p points to. See
|
||||||
|
@ -1835,3 +1857,196 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
|
||||||
n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, append(n.exemplars[nIdx:rIdx], n.exemplars[rIdx+1:]...)...)...)
|
n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, append(n.exemplars[nIdx:rIdx], n.exemplars[rIdx+1:]...)...)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type constNativeHistogram struct {
|
||||||
|
desc *Desc
|
||||||
|
dto.Histogram
|
||||||
|
labelPairs []*dto.LabelPair
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateCount(sum float64, count uint64, negativeBuckets, positiveBuckets map[int]int64, zeroBucket uint64) error {
|
||||||
|
var bucketPopulationSum int64
|
||||||
|
for _, v := range positiveBuckets {
|
||||||
|
bucketPopulationSum += v
|
||||||
|
}
|
||||||
|
for _, v := range negativeBuckets {
|
||||||
|
bucketPopulationSum += v
|
||||||
|
}
|
||||||
|
bucketPopulationSum += int64(zeroBucket)
|
||||||
|
|
||||||
|
// If the sum of observations is NaN, the number of observations must be greater or equal to the sum of all bucket counts.
|
||||||
|
// Otherwise, the number of observations must be equal to the sum of all bucket counts .
|
||||||
|
|
||||||
|
if math.IsNaN(sum) && bucketPopulationSum > int64(count) ||
|
||||||
|
!math.IsNaN(sum) && bucketPopulationSum != int64(count) {
|
||||||
|
return errors.New("the sum of all bucket populations exceeds the count of observations")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConstNativeHistogram returns a metric representing a Prometheus native histogram with
|
||||||
|
// fixed values for the count, sum, and positive/negative/zero 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
|
||||||
|
// OpenTelemetry Collectors, it is useful as a throw-away metric that is generated on the fly
|
||||||
|
// to send it to Prometheus in the Collect method.
|
||||||
|
//
|
||||||
|
// zeroBucket counts all (positive and negative)
|
||||||
|
// observations in the zero bucket (with an absolute value less or equal
|
||||||
|
// the current threshold).
|
||||||
|
// positiveBuckets and negativeBuckets are separate maps for negative and positive
|
||||||
|
// observations. The map's value is an int64, counting observations in
|
||||||
|
// that bucket. The map's key is the
|
||||||
|
// index of the bucket according to the used
|
||||||
|
// Schema. Index 0 is for an upper bound of 1 in positive buckets and for a lower bound of -1 in negative buckets.
|
||||||
|
// NewConstNativeHistogram returns an error if
|
||||||
|
// - the length of labelValues is not consistent with the variable labels in Desc or if Desc is invalid.
|
||||||
|
// - the schema passed is not between 8 and -4
|
||||||
|
// - the sum of counts in all buckets including the zero bucket does not equal the count if sum is not NaN (or exceeds the count if sum is NaN)
|
||||||
|
//
|
||||||
|
// See https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/#exponential-histograms for more details about the conversion from OTel to Prometheus.
|
||||||
|
func NewConstNativeHistogram(
|
||||||
|
desc *Desc,
|
||||||
|
count uint64,
|
||||||
|
sum float64,
|
||||||
|
positiveBuckets, negativeBuckets map[int]int64,
|
||||||
|
zeroBucket uint64,
|
||||||
|
schema int32,
|
||||||
|
zeroThreshold float64,
|
||||||
|
createdTimestamp 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
|
||||||
|
}
|
||||||
|
if schema > nativeHistogramSchemaMaximum || schema < nativeHistogramSchemaMinimum {
|
||||||
|
return nil, errors.New("invalid native histogram schema")
|
||||||
|
}
|
||||||
|
if err := validateCount(sum, count, negativeBuckets, positiveBuckets, zeroBucket); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
NegativeSpan, NegativeDelta := makeBucketsFromMap(negativeBuckets)
|
||||||
|
PositiveSpan, PositiveDelta := makeBucketsFromMap(positiveBuckets)
|
||||||
|
ret := &constNativeHistogram{
|
||||||
|
desc: desc,
|
||||||
|
Histogram: dto.Histogram{
|
||||||
|
CreatedTimestamp: timestamppb.New(createdTimestamp),
|
||||||
|
Schema: &schema,
|
||||||
|
ZeroThreshold: &zeroThreshold,
|
||||||
|
SampleCount: &count,
|
||||||
|
SampleSum: &sum,
|
||||||
|
|
||||||
|
NegativeSpan: NegativeSpan,
|
||||||
|
NegativeDelta: NegativeDelta,
|
||||||
|
|
||||||
|
PositiveSpan: PositiveSpan,
|
||||||
|
PositiveDelta: PositiveDelta,
|
||||||
|
|
||||||
|
ZeroCount: proto.Uint64(zeroBucket),
|
||||||
|
},
|
||||||
|
labelPairs: MakeLabelPairs(desc, labelValues),
|
||||||
|
}
|
||||||
|
if *ret.ZeroThreshold == 0 && *ret.ZeroCount == 0 && len(ret.PositiveSpan) == 0 && len(ret.NegativeSpan) == 0 {
|
||||||
|
ret.PositiveSpan = []*dto.BucketSpan{{
|
||||||
|
Offset: proto.Int32(0),
|
||||||
|
Length: proto.Uint32(0),
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustNewConstNativeHistogram is a version of NewConstNativeHistogram that panics where
|
||||||
|
// NewConstNativeHistogram would have returned an error.
|
||||||
|
func MustNewConstNativeHistogram(
|
||||||
|
desc *Desc,
|
||||||
|
count uint64,
|
||||||
|
sum float64,
|
||||||
|
positiveBuckets, negativeBuckets map[int]int64,
|
||||||
|
zeroBucket uint64,
|
||||||
|
nativeHistogramSchema int32,
|
||||||
|
nativeHistogramZeroThreshold float64,
|
||||||
|
createdTimestamp time.Time,
|
||||||
|
labelValues ...string,
|
||||||
|
) Metric {
|
||||||
|
nativehistogram, err := NewConstNativeHistogram(desc,
|
||||||
|
count,
|
||||||
|
sum,
|
||||||
|
positiveBuckets,
|
||||||
|
negativeBuckets,
|
||||||
|
zeroBucket,
|
||||||
|
nativeHistogramSchema,
|
||||||
|
nativeHistogramZeroThreshold,
|
||||||
|
createdTimestamp,
|
||||||
|
labelValues...)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return nativehistogram
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *constNativeHistogram) Desc() *Desc {
|
||||||
|
return h.desc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *constNativeHistogram) Write(out *dto.Metric) error {
|
||||||
|
out.Histogram = &h.Histogram
|
||||||
|
out.Label = h.labelPairs
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeBucketsFromMap(buckets map[int]int64) ([]*dto.BucketSpan, []int64) {
|
||||||
|
if len(buckets) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
var ii []int
|
||||||
|
for k := range buckets {
|
||||||
|
ii = append(ii, k)
|
||||||
|
}
|
||||||
|
sort.Ints(ii)
|
||||||
|
|
||||||
|
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 {
|
||||||
|
count := buckets[i]
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
|
@ -22,17 +22,18 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func min(a, b int) int {
|
func minInt(a, b int) int {
|
||||||
if a < b {
|
if a < b {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func max(a, b int) int {
|
func maxInt(a, b int) int {
|
||||||
if a > b {
|
if a > b {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
@ -427,12 +428,12 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
|
||||||
if codes[0].Tag == 'e' {
|
if codes[0].Tag == 'e' {
|
||||||
c := codes[0]
|
c := codes[0]
|
||||||
i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
|
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}
|
codes[0] = OpCode{c.Tag, maxInt(i1, i2-n), i2, maxInt(j1, j2-n), j2}
|
||||||
}
|
}
|
||||||
if codes[len(codes)-1].Tag == 'e' {
|
if codes[len(codes)-1].Tag == 'e' {
|
||||||
c := codes[len(codes)-1]
|
c := codes[len(codes)-1]
|
||||||
i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
|
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)}
|
codes[len(codes)-1] = OpCode{c.Tag, i1, minInt(i2, i1+n), j1, minInt(j2, j1+n)}
|
||||||
}
|
}
|
||||||
nn := n + n
|
nn := n + n
|
||||||
groups := [][]OpCode{}
|
groups := [][]OpCode{}
|
||||||
|
@ -443,12 +444,12 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
|
||||||
// there is a large range with no changes.
|
// there is a large range with no changes.
|
||||||
if c.Tag == 'e' && i2-i1 > nn {
|
if c.Tag == 'e' && i2-i1 > nn {
|
||||||
group = append(group, OpCode{
|
group = append(group, OpCode{
|
||||||
c.Tag, i1, min(i2, i1+n),
|
c.Tag, i1, minInt(i2, i1+n),
|
||||||
j1, min(j2, j1+n),
|
j1, minInt(j2, j1+n),
|
||||||
})
|
})
|
||||||
groups = append(groups, group)
|
groups = append(groups, group)
|
||||||
group = []OpCode{}
|
group = []OpCode{}
|
||||||
i1, j1 = max(i1, i2-n), max(j1, j2-n)
|
i1, j1 = maxInt(i1, i2-n), maxInt(j1, j2-n)
|
||||||
}
|
}
|
||||||
group = append(group, OpCode{c.Tag, i1, i2, j1, j2})
|
group = append(group, OpCode{c.Tag, i1, i2, j1, j2})
|
||||||
}
|
}
|
||||||
|
@ -515,7 +516,7 @@ func (m *SequenceMatcher) QuickRatio() float64 {
|
||||||
// is faster to compute than either .Ratio() or .QuickRatio().
|
// is faster to compute than either .Ratio() or .QuickRatio().
|
||||||
func (m *SequenceMatcher) RealQuickRatio() float64 {
|
func (m *SequenceMatcher) RealQuickRatio() float64 {
|
||||||
la, lb := len(m.a), len(m.b)
|
la, lb := len(m.a), len(m.b)
|
||||||
return calculateRatio(min(la, lb), la+lb)
|
return calculateRatio(minInt(la, lb), la+lb)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert range to the "ed" format
|
// Convert range to the "ed" format
|
||||||
|
@ -524,7 +525,7 @@ func formatRangeUnified(start, stop int) string {
|
||||||
beginning := start + 1 // lines start numbering with one
|
beginning := start + 1 // lines start numbering with one
|
||||||
length := stop - start
|
length := stop - start
|
||||||
if length == 1 {
|
if length == 1 {
|
||||||
return fmt.Sprintf("%d", beginning)
|
return strconv.Itoa(beginning)
|
||||||
}
|
}
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
beginning-- // empty ranges begin at line just before the range
|
beginning-- // empty ranges begin at line just before the range
|
||||||
|
|
3
vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go
generated
vendored
3
vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go
generated
vendored
|
@ -66,7 +66,8 @@ func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool)
|
||||||
name += "_total"
|
name += "_total"
|
||||||
}
|
}
|
||||||
|
|
||||||
valid := model.IsValidMetricName(model.LabelValue(namespace + "_" + subsystem + "_" + name))
|
// Our current conversion moves to legacy naming, so use legacy validation.
|
||||||
|
valid := model.IsValidLegacyMetricName(namespace + "_" + subsystem + "_" + name)
|
||||||
switch d.Kind {
|
switch d.Kind {
|
||||||
case metrics.KindUint64:
|
case metrics.KindUint64:
|
||||||
case metrics.KindFloat64:
|
case metrics.KindFloat64:
|
||||||
|
|
|
@ -108,15 +108,23 @@ func BuildFQName(namespace, subsystem, name string) string {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
switch {
|
|
||||||
case namespace != "" && subsystem != "":
|
sb := strings.Builder{}
|
||||||
return strings.Join([]string{namespace, subsystem, name}, "_")
|
sb.Grow(len(namespace) + len(subsystem) + len(name) + 2)
|
||||||
case namespace != "":
|
|
||||||
return strings.Join([]string{namespace, name}, "_")
|
if namespace != "" {
|
||||||
case subsystem != "":
|
sb.WriteString(namespace)
|
||||||
return strings.Join([]string{subsystem, name}, "_")
|
sb.WriteString("_")
|
||||||
}
|
}
|
||||||
return name
|
|
||||||
|
if subsystem != "" {
|
||||||
|
sb.WriteString(subsystem)
|
||||||
|
sb.WriteString("_")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.WriteString(name)
|
||||||
|
|
||||||
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type invalidMetric struct {
|
type invalidMetric struct {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
|
|
||||||
type processCollector struct {
|
type processCollector struct {
|
||||||
collectFn func(chan<- Metric)
|
collectFn func(chan<- Metric)
|
||||||
|
describeFn func(chan<- *Desc)
|
||||||
pidFn func() (int, error)
|
pidFn func() (int, error)
|
||||||
reportErrors bool
|
reportErrors bool
|
||||||
cpuTotal *Desc
|
cpuTotal *Desc
|
||||||
|
@ -122,26 +123,23 @@ func NewProcessCollector(opts ProcessCollectorOpts) Collector {
|
||||||
// Set up process metric collection if supported by the runtime.
|
// Set up process metric collection if supported by the runtime.
|
||||||
if canCollectProcess() {
|
if canCollectProcess() {
|
||||||
c.collectFn = c.processCollect
|
c.collectFn = c.processCollect
|
||||||
|
c.describeFn = c.describe
|
||||||
} else {
|
} else {
|
||||||
c.collectFn = func(ch chan<- Metric) {
|
c.collectFn = c.errorCollectFn
|
||||||
c.reportError(ch, nil, errors.New("process metrics not supported on this platform"))
|
c.describeFn = c.errorDescribeFn
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe returns all descriptions of the collector.
|
func (c *processCollector) errorCollectFn(ch chan<- Metric) {
|
||||||
func (c *processCollector) Describe(ch chan<- *Desc) {
|
c.reportError(ch, nil, errors.New("process metrics not supported on this platform"))
|
||||||
ch <- c.cpuTotal
|
}
|
||||||
ch <- c.openFDs
|
|
||||||
ch <- c.maxFDs
|
func (c *processCollector) errorDescribeFn(ch chan<- *Desc) {
|
||||||
ch <- c.vsize
|
if c.reportErrors {
|
||||||
ch <- c.maxVsize
|
ch <- NewInvalidDesc(errors.New("process metrics not supported on this platform"))
|
||||||
ch <- c.rss
|
}
|
||||||
ch <- c.startTime
|
|
||||||
ch <- c.inBytes
|
|
||||||
ch <- c.outBytes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect returns the current state of all metrics of the collector.
|
// Collect returns the current state of all metrics of the collector.
|
||||||
|
@ -149,6 +147,11 @@ func (c *processCollector) Collect(ch chan<- Metric) {
|
||||||
c.collectFn(ch)
|
c.collectFn(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Describe returns all descriptions of the collector.
|
||||||
|
func (c *processCollector) Describe(ch chan<- *Desc) {
|
||||||
|
c.describeFn(ch)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {
|
func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {
|
||||||
if !c.reportErrors {
|
if !c.reportErrors {
|
||||||
return
|
return
|
||||||
|
|
84
vendor/github.com/prometheus/client_golang/prometheus/process_collector_cgo_darwin.c
generated
vendored
Normal file
84
vendor/github.com/prometheus/client_golang/prometheus/process_collector_cgo_darwin.c
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// Copyright 2024 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 darwin && cgo
|
||||||
|
|
||||||
|
#include <mach/mach_init.h>
|
||||||
|
#include <mach/task.h>
|
||||||
|
#include <mach/mach_vm.h>
|
||||||
|
|
||||||
|
// The compiler warns that mach/shared_memory_server.h is deprecated, and to use
|
||||||
|
// mach/shared_region.h instead. But that doesn't define
|
||||||
|
// SHARED_DATA_REGION_SIZE or SHARED_TEXT_REGION_SIZE, so redefine them here and
|
||||||
|
// avoid a warning message when running tests.
|
||||||
|
#define GLOBAL_SHARED_TEXT_SEGMENT 0x90000000U
|
||||||
|
#define SHARED_DATA_REGION_SIZE 0x10000000
|
||||||
|
#define SHARED_TEXT_REGION_SIZE 0x10000000
|
||||||
|
|
||||||
|
|
||||||
|
int get_memory_info(unsigned long long *rss, unsigned long long *vsize)
|
||||||
|
{
|
||||||
|
// This is lightly adapted from how ps(1) obtains its memory info.
|
||||||
|
// https://github.com/apple-oss-distributions/adv_cmds/blob/8744084ea0ff41ca4bb96b0f9c22407d0e48e9b7/ps/tasks.c#L109
|
||||||
|
|
||||||
|
kern_return_t error;
|
||||||
|
task_t task = MACH_PORT_NULL;
|
||||||
|
mach_task_basic_info_data_t info;
|
||||||
|
mach_msg_type_number_t info_count = MACH_TASK_BASIC_INFO_COUNT;
|
||||||
|
|
||||||
|
error = task_info(
|
||||||
|
mach_task_self(),
|
||||||
|
MACH_TASK_BASIC_INFO,
|
||||||
|
(task_info_t) &info,
|
||||||
|
&info_count );
|
||||||
|
|
||||||
|
if( error != KERN_SUCCESS )
|
||||||
|
{
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*rss = info.resident_size;
|
||||||
|
*vsize = info.virtual_size;
|
||||||
|
|
||||||
|
{
|
||||||
|
vm_region_basic_info_data_64_t b_info;
|
||||||
|
mach_vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT;
|
||||||
|
mach_vm_size_t size;
|
||||||
|
mach_port_t object_name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* try to determine if this task has the split libraries
|
||||||
|
* mapped in... if so, adjust its virtual size down by
|
||||||
|
* the 2 segments that are used for split libraries
|
||||||
|
*/
|
||||||
|
info_count = VM_REGION_BASIC_INFO_COUNT_64;
|
||||||
|
|
||||||
|
error = mach_vm_region(
|
||||||
|
mach_task_self(),
|
||||||
|
&address,
|
||||||
|
&size,
|
||||||
|
VM_REGION_BASIC_INFO_64,
|
||||||
|
(vm_region_info_t) &b_info,
|
||||||
|
&info_count,
|
||||||
|
&object_name);
|
||||||
|
|
||||||
|
if (error == KERN_SUCCESS) {
|
||||||
|
if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) &&
|
||||||
|
*vsize > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) {
|
||||||
|
*vsize -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
51
vendor/github.com/prometheus/client_golang/prometheus/process_collector_cgo_darwin.go
generated
vendored
Normal file
51
vendor/github.com/prometheus/client_golang/prometheus/process_collector_cgo_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright 2024 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 darwin && cgo
|
||||||
|
|
||||||
|
package prometheus
|
||||||
|
|
||||||
|
/*
|
||||||
|
int get_memory_info(unsigned long long *rss, unsigned long long *vs);
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func getMemory() (*memoryInfo, error) {
|
||||||
|
var rss, vsize C.ulonglong
|
||||||
|
|
||||||
|
if err := C.get_memory_info(&rss, &vsize); err != 0 {
|
||||||
|
return nil, fmt.Errorf("task_info() failed with 0x%x", int(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &memoryInfo{vsize: uint64(vsize), rss: uint64(rss)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// describe returns all descriptions of the collector for Darwin.
|
||||||
|
// Ensure that this list of descriptors is kept in sync with the metrics collected
|
||||||
|
// in the processCollect method. Any changes to the metrics in processCollect
|
||||||
|
// (such as adding or removing metrics) should be reflected in this list of descriptors.
|
||||||
|
func (c *processCollector) describe(ch chan<- *Desc) {
|
||||||
|
ch <- c.cpuTotal
|
||||||
|
ch <- c.openFDs
|
||||||
|
ch <- c.maxFDs
|
||||||
|
ch <- c.maxVsize
|
||||||
|
ch <- c.startTime
|
||||||
|
ch <- c.rss
|
||||||
|
ch <- c.vsize
|
||||||
|
|
||||||
|
/* the process could be collected but not implemented yet
|
||||||
|
ch <- c.inBytes
|
||||||
|
ch <- c.outBytes
|
||||||
|
*/
|
||||||
|
}
|
128
vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go
generated
vendored
Normal file
128
vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
// Copyright 2024 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"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// notImplementedErr is returned by stub functions that replace cgo functions, when cgo
|
||||||
|
// isn't available.
|
||||||
|
var notImplementedErr = errors.New("not implemented")
|
||||||
|
|
||||||
|
type memoryInfo struct {
|
||||||
|
vsize uint64 // Virtual memory size in bytes
|
||||||
|
rss uint64 // Resident memory size in bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
func canCollectProcess() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSoftLimit(which int) (uint64, error) {
|
||||||
|
rlimit := syscall.Rlimit{}
|
||||||
|
|
||||||
|
if err := syscall.Getrlimit(which, &rlimit); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return rlimit.Cur, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOpenFileCount() (float64, error) {
|
||||||
|
// Alternately, the undocumented proc_pidinfo(PROC_PIDLISTFDS) can be used to
|
||||||
|
// return a list of open fds, but that requires a way to call C APIs. The
|
||||||
|
// benefits, however, include fewer system calls and not failing when at the
|
||||||
|
// open file soft limit.
|
||||||
|
|
||||||
|
if dir, err := os.Open("/dev/fd"); err != nil {
|
||||||
|
return 0.0, err
|
||||||
|
} else {
|
||||||
|
defer dir.Close()
|
||||||
|
|
||||||
|
// Avoid ReadDir(), as it calls stat(2) on each descriptor. Not only is
|
||||||
|
// that info not used, but KQUEUE descriptors fail stat(2), which causes
|
||||||
|
// the whole method to fail.
|
||||||
|
if names, err := dir.Readdirnames(0); err != nil {
|
||||||
|
return 0.0, err
|
||||||
|
} else {
|
||||||
|
// Subtract 1 to ignore the open /dev/fd descriptor above.
|
||||||
|
return float64(len(names) - 1), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *processCollector) processCollect(ch chan<- Metric) {
|
||||||
|
if procs, err := unix.SysctlKinfoProcSlice("kern.proc.pid", os.Getpid()); err == nil {
|
||||||
|
if len(procs) == 1 {
|
||||||
|
startTime := float64(procs[0].Proc.P_starttime.Nano() / 1e9)
|
||||||
|
ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("sysctl() returned %d proc structs (expected 1)", len(procs))
|
||||||
|
c.reportError(ch, c.startTime, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.reportError(ch, c.startTime, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The proc structure returned by kern.proc.pid above has an Rusage member,
|
||||||
|
// but it is not filled in, so it needs to be fetched by getrusage(2). For
|
||||||
|
// that call, the UTime, STime, and Maxrss members are filled out, but not
|
||||||
|
// Ixrss, Idrss, or Isrss for the memory usage. Memory stats will require
|
||||||
|
// access to the C API to call task_info(TASK_BASIC_INFO).
|
||||||
|
rusage := unix.Rusage{}
|
||||||
|
|
||||||
|
if err := unix.Getrusage(syscall.RUSAGE_SELF, &rusage); err == nil {
|
||||||
|
cpuTime := time.Duration(rusage.Stime.Nano() + rusage.Utime.Nano()).Seconds()
|
||||||
|
ch <- MustNewConstMetric(c.cpuTotal, CounterValue, cpuTime)
|
||||||
|
} else {
|
||||||
|
c.reportError(ch, c.cpuTotal, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if memInfo, err := getMemory(); err == nil {
|
||||||
|
ch <- MustNewConstMetric(c.rss, GaugeValue, float64(memInfo.rss))
|
||||||
|
ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(memInfo.vsize))
|
||||||
|
} else if !errors.Is(err, notImplementedErr) {
|
||||||
|
// Don't report an error when support is not compiled in.
|
||||||
|
c.reportError(ch, c.rss, err)
|
||||||
|
c.reportError(ch, c.vsize, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fds, err := getOpenFileCount(); err == nil {
|
||||||
|
ch <- MustNewConstMetric(c.openFDs, GaugeValue, fds)
|
||||||
|
} else {
|
||||||
|
c.reportError(ch, c.openFDs, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if openFiles, err := getSoftLimit(syscall.RLIMIT_NOFILE); err == nil {
|
||||||
|
ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(openFiles))
|
||||||
|
} else {
|
||||||
|
c.reportError(ch, c.maxFDs, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if addressSpace, err := getSoftLimit(syscall.RLIMIT_AS); err == nil {
|
||||||
|
ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(addressSpace))
|
||||||
|
} else {
|
||||||
|
c.reportError(ch, c.maxVsize, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: socket(PF_SYSTEM) to fetch "com.apple.network.statistics" might
|
||||||
|
// be able to get the per-process network send/receive counts.
|
||||||
|
}
|
39
vendor/github.com/prometheus/client_golang/prometheus/process_collector_nocgo_darwin.go
generated
vendored
Normal file
39
vendor/github.com/prometheus/client_golang/prometheus/process_collector_nocgo_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2024 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 darwin && !cgo
|
||||||
|
|
||||||
|
package prometheus
|
||||||
|
|
||||||
|
func getMemory() (*memoryInfo, error) {
|
||||||
|
return nil, notImplementedErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// describe returns all descriptions of the collector for Darwin.
|
||||||
|
// Ensure that this list of descriptors is kept in sync with the metrics collected
|
||||||
|
// in the processCollect method. Any changes to the metrics in processCollect
|
||||||
|
// (such as adding or removing metrics) should be reflected in this list of descriptors.
|
||||||
|
func (c *processCollector) describe(ch chan<- *Desc) {
|
||||||
|
ch <- c.cpuTotal
|
||||||
|
ch <- c.openFDs
|
||||||
|
ch <- c.maxFDs
|
||||||
|
ch <- c.maxVsize
|
||||||
|
ch <- c.startTime
|
||||||
|
|
||||||
|
/* the process could be collected but not implemented yet
|
||||||
|
ch <- c.rss
|
||||||
|
ch <- c.vsize
|
||||||
|
ch <- c.inBytes
|
||||||
|
ch <- c.outBytes
|
||||||
|
*/
|
||||||
|
}
|
20
vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
generated
vendored
20
vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
generated
vendored
|
@ -11,8 +11,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !windows && !js && !wasip1
|
//go:build !windows && !js && !wasip1 && !darwin
|
||||||
// +build !windows,!js,!wasip1
|
// +build !windows,!js,!wasip1,!darwin
|
||||||
|
|
||||||
package prometheus
|
package prometheus
|
||||||
|
|
||||||
|
@ -78,3 +78,19 @@ func (c *processCollector) processCollect(ch chan<- Metric) {
|
||||||
c.reportError(ch, nil, err)
|
c.reportError(ch, nil, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// describe returns all descriptions of the collector for others than windows, js, wasip1 and darwin.
|
||||||
|
// Ensure that this list of descriptors is kept in sync with the metrics collected
|
||||||
|
// in the processCollect method. Any changes to the metrics in processCollect
|
||||||
|
// (such as adding or removing metrics) should be reflected in this list of descriptors.
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
26
vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go
generated
vendored
26
vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go
generated
vendored
|
@ -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
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019 The Prometheus Authors
|
// Copyright 2023 The Prometheus Authors
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
|
@ -11,8 +11,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build js
|
//go:build wasip1 || js
|
||||||
// +build js
|
// +build wasip1 js
|
||||||
|
|
||||||
package prometheus
|
package prometheus
|
||||||
|
|
||||||
|
@ -21,6 +21,13 @@ func canCollectProcess() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *processCollector) processCollect(ch chan<- Metric) {
|
func (c *processCollector) processCollect(ch chan<- Metric) {
|
||||||
// noop on this platform
|
c.errorCollectFn(ch)
|
||||||
return
|
}
|
||||||
|
|
||||||
|
// describe returns all descriptions of the collector for wasip1 and js.
|
||||||
|
// Ensure that this list of descriptors is kept in sync with the metrics collected
|
||||||
|
// in the processCollect method. Any changes to the metrics in processCollect
|
||||||
|
// (such as adding or removing metrics) should be reflected in this list of descriptors.
|
||||||
|
func (c *processCollector) describe(ch chan<- *Desc) {
|
||||||
|
c.errorDescribeFn(ch)
|
||||||
}
|
}
|
21
vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
generated
vendored
21
vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
generated
vendored
|
@ -79,14 +79,10 @@ func getProcessHandleCount(handle windows.Handle) (uint32, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *processCollector) processCollect(ch chan<- Metric) {
|
func (c *processCollector) processCollect(ch chan<- Metric) {
|
||||||
h, err := windows.GetCurrentProcess()
|
h := windows.CurrentProcess()
|
||||||
if err != nil {
|
|
||||||
c.reportError(ch, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var startTime, exitTime, kernelTime, userTime windows.Filetime
|
var startTime, exitTime, kernelTime, userTime windows.Filetime
|
||||||
err = windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime)
|
err := windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.reportError(ch, nil, err)
|
c.reportError(ch, nil, err)
|
||||||
return
|
return
|
||||||
|
@ -111,6 +107,19 @@ func (c *processCollector) processCollect(ch chan<- Metric) {
|
||||||
ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process.
|
ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// describe returns all descriptions of the collector for windows.
|
||||||
|
// Ensure that this list of descriptors is kept in sync with the metrics collected
|
||||||
|
// in the processCollect method. Any changes to the metrics in processCollect
|
||||||
|
// (such as adding or removing metrics) should be reflected in this list of descriptors.
|
||||||
|
func (c *processCollector) describe(ch chan<- *Desc) {
|
||||||
|
ch <- c.cpuTotal
|
||||||
|
ch <- c.openFDs
|
||||||
|
ch <- c.maxFDs
|
||||||
|
ch <- c.vsize
|
||||||
|
ch <- c.rss
|
||||||
|
ch <- c.startTime
|
||||||
|
}
|
||||||
|
|
||||||
func fileTimeToSeconds(ft windows.Filetime) float64 {
|
func fileTimeToSeconds(ft windows.Filetime) float64 {
|
||||||
return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7
|
return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,13 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO
|
||||||
if encodingHeader != string(Identity) {
|
if encodingHeader != string(Identity) {
|
||||||
rsp.Header().Set(contentEncodingHeader, encodingHeader)
|
rsp.Header().Set(contentEncodingHeader, encodingHeader)
|
||||||
}
|
}
|
||||||
enc := expfmt.NewEncoder(w, contentType)
|
|
||||||
|
var enc expfmt.Encoder
|
||||||
|
if opts.EnableOpenMetricsTextCreatedSamples {
|
||||||
|
enc = expfmt.NewEncoder(w, contentType, expfmt.WithCreatedLines())
|
||||||
|
} else {
|
||||||
|
enc = expfmt.NewEncoder(w, contentType)
|
||||||
|
}
|
||||||
|
|
||||||
// handleError handles the error according to opts.ErrorHandling
|
// handleError handles the error according to opts.ErrorHandling
|
||||||
// and returns true if we have to abort after the handling.
|
// and returns true if we have to abort after the handling.
|
||||||
|
@ -408,6 +414,21 @@ type HandlerOpts struct {
|
||||||
// (which changes the identity of the resulting series on the Prometheus
|
// (which changes the identity of the resulting series on the Prometheus
|
||||||
// server).
|
// server).
|
||||||
EnableOpenMetrics bool
|
EnableOpenMetrics bool
|
||||||
|
// EnableOpenMetricsTextCreatedSamples specifies if this handler should add, extra, synthetic
|
||||||
|
// Created Timestamps for counters, histograms and summaries, which for the current
|
||||||
|
// version of OpenMetrics are defined as extra series with the same name and "_created"
|
||||||
|
// suffix. See also the OpenMetrics specification for more details
|
||||||
|
// https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#counter-1
|
||||||
|
//
|
||||||
|
// Created timestamps are used to improve the accuracy of reset detection,
|
||||||
|
// but the way it's designed in OpenMetrics 1.0 it also dramatically increases cardinality
|
||||||
|
// if the scraper does not handle those metrics correctly (converting to created timestamp
|
||||||
|
// instead of leaving those series as-is). New OpenMetrics versions might improve
|
||||||
|
// this situation.
|
||||||
|
//
|
||||||
|
// Prometheus introduced the feature flag 'created-timestamp-zero-ingestion'
|
||||||
|
// in version 2.50.0 to handle this situation.
|
||||||
|
EnableOpenMetricsTextCreatedSamples bool
|
||||||
// ProcessStartTime allows setting process start timevalue that will be exposed
|
// ProcessStartTime allows setting process start timevalue that will be exposed
|
||||||
// with "Process-Start-Time-Unix" response header along with the metrics
|
// with "Process-Start-Time-Unix" response header along with the metrics
|
||||||
// payload. This allow callers to have efficient transformations to cumulative
|
// payload. This allow callers to have efficient transformations to cumulative
|
||||||
|
|
|
@ -243,6 +243,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
|
||||||
|
|
||||||
s := &summary{
|
s := &summary{
|
||||||
desc: desc,
|
desc: desc,
|
||||||
|
now: opts.now,
|
||||||
|
|
||||||
objectives: opts.Objectives,
|
objectives: opts.Objectives,
|
||||||
sortedObjectives: make([]float64, 0, len(opts.Objectives)),
|
sortedObjectives: make([]float64, 0, len(opts.Objectives)),
|
||||||
|
@ -280,6 +281,8 @@ type summary struct {
|
||||||
|
|
||||||
desc *Desc
|
desc *Desc
|
||||||
|
|
||||||
|
now func() time.Time
|
||||||
|
|
||||||
objectives map[float64]float64
|
objectives map[float64]float64
|
||||||
sortedObjectives []float64
|
sortedObjectives []float64
|
||||||
|
|
||||||
|
@ -307,7 +310,7 @@ func (s *summary) Observe(v float64) {
|
||||||
s.bufMtx.Lock()
|
s.bufMtx.Lock()
|
||||||
defer s.bufMtx.Unlock()
|
defer s.bufMtx.Unlock()
|
||||||
|
|
||||||
now := time.Now()
|
now := s.now()
|
||||||
if now.After(s.hotBufExpTime) {
|
if now.After(s.hotBufExpTime) {
|
||||||
s.asyncFlush(now)
|
s.asyncFlush(now)
|
||||||
}
|
}
|
||||||
|
@ -326,7 +329,7 @@ func (s *summary) Write(out *dto.Metric) error {
|
||||||
s.bufMtx.Lock()
|
s.bufMtx.Lock()
|
||||||
s.mtx.Lock()
|
s.mtx.Lock()
|
||||||
// Swap bufs even if hotBuf is empty to set new hotBufExpTime.
|
// Swap bufs even if hotBuf is empty to set new hotBufExpTime.
|
||||||
s.swapBufs(time.Now())
|
s.swapBufs(s.now())
|
||||||
s.bufMtx.Unlock()
|
s.bufMtx.Unlock()
|
||||||
|
|
||||||
s.flushColdBuf()
|
s.flushColdBuf()
|
||||||
|
@ -468,13 +471,9 @@ func (s *noObjectivesSummary) Observe(v float64) {
|
||||||
n := atomic.AddUint64(&s.countAndHotIdx, 1)
|
n := atomic.AddUint64(&s.countAndHotIdx, 1)
|
||||||
hotCounts := s.counts[n>>63]
|
hotCounts := s.counts[n>>63]
|
||||||
|
|
||||||
for {
|
atomicUpdateFloat(&hotCounts.sumBits, func(oldVal float64) float64 {
|
||||||
oldBits := atomic.LoadUint64(&hotCounts.sumBits)
|
return oldVal + v
|
||||||
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
|
// Increment count last as we take it as a signal that the observation
|
||||||
// is complete.
|
// is complete.
|
||||||
atomic.AddUint64(&hotCounts.count, 1)
|
atomic.AddUint64(&hotCounts.count, 1)
|
||||||
|
@ -516,14 +515,13 @@ func (s *noObjectivesSummary) Write(out *dto.Metric) error {
|
||||||
// Finally add all the cold counts to the new hot counts and reset the cold counts.
|
// Finally add all the cold counts to the new hot counts and reset the cold counts.
|
||||||
atomic.AddUint64(&hotCounts.count, count)
|
atomic.AddUint64(&hotCounts.count, count)
|
||||||
atomic.StoreUint64(&coldCounts.count, 0)
|
atomic.StoreUint64(&coldCounts.count, 0)
|
||||||
for {
|
|
||||||
oldBits := atomic.LoadUint64(&hotCounts.sumBits)
|
// Use atomicUpdateFloat to update hotCounts.sumBits atomically.
|
||||||
newBits := math.Float64bits(math.Float64frombits(oldBits) + sum.GetSampleSum())
|
atomicUpdateFloat(&hotCounts.sumBits, func(oldVal float64) float64 {
|
||||||
if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
|
return oldVal + sum.GetSampleSum()
|
||||||
atomic.StoreUint64(&coldCounts.sumBits, 0)
|
})
|
||||||
break
|
atomic.StoreUint64(&coldCounts.sumBits, 0)
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ type EncoderOption func(*encoderOption)
|
||||||
|
|
||||||
// WithCreatedLines is an EncoderOption that configures the OpenMetrics encoder
|
// WithCreatedLines is an EncoderOption that configures the OpenMetrics encoder
|
||||||
// to include _created lines (See
|
// to include _created lines (See
|
||||||
// https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#counter-1).
|
// https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#counter-1).
|
||||||
// Created timestamps can improve the accuracy of series reset detection, but
|
// Created timestamps can improve the accuracy of series reset detection, but
|
||||||
// come with a bandwidth cost.
|
// come with a bandwidth cost.
|
||||||
//
|
//
|
||||||
|
@ -102,7 +102,7 @@ func WithUnit() EncoderOption {
|
||||||
//
|
//
|
||||||
// - According to the OM specs, the `# UNIT` line is optional, but if populated,
|
// - According to the OM specs, the `# UNIT` line is optional, but if populated,
|
||||||
// the unit has to be present in the metric name as its suffix:
|
// the unit has to be present in the metric name as its suffix:
|
||||||
// (see https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#unit).
|
// (see https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#unit).
|
||||||
// However, in order to accommodate any potential scenario where such a change in the
|
// However, in order to accommodate any potential scenario where such a change in the
|
||||||
// metric name is not desirable, the users are here given the choice of either explicitly
|
// metric name is not desirable, the users are here given the choice of either explicitly
|
||||||
// opt in, in case they wish for the unit to be included in the output AND in the metric name
|
// opt in, in case they wish for the unit to be included in the output AND in the metric name
|
||||||
|
|
|
@ -28,13 +28,13 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// NameValidationScheme determines the method of name validation to be used by
|
// NameValidationScheme determines the method of name validation to be used by
|
||||||
// all calls to IsValidMetricName() and LabelName IsValid(). Setting UTF-8 mode
|
// all calls to IsValidMetricName() and LabelName IsValid(). Setting UTF-8
|
||||||
// in isolation from other components that don't support UTF-8 may result in
|
// mode in isolation from other components that don't support UTF-8 may result
|
||||||
// bugs or other undefined behavior. This value is intended to be set by
|
// in bugs or other undefined behavior. This value can be set to
|
||||||
// UTF-8-aware binaries as part of their startup. To avoid need for locking,
|
// LegacyValidation during startup if a binary is not UTF-8-aware binaries. To
|
||||||
// this value should be set once, ideally in an init(), before multiple
|
// avoid need for locking, this value should be set once, ideally in an
|
||||||
// goroutines are started.
|
// init(), before multiple goroutines are started.
|
||||||
NameValidationScheme = LegacyValidation
|
NameValidationScheme = UTF8Validation
|
||||||
|
|
||||||
// NameEscapingScheme defines the default way that names will be escaped when
|
// NameEscapingScheme defines the default way that names will be escaped when
|
||||||
// presented to systems that do not support UTF-8 names. If the Content-Type
|
// presented to systems that do not support UTF-8 names. If the Content-Type
|
||||||
|
|
|
@ -735,8 +735,8 @@ github.com/pkg/errors
|
||||||
# github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
|
# github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
|
||||||
## explicit
|
## explicit
|
||||||
github.com/pmezard/go-difflib/difflib
|
github.com/pmezard/go-difflib/difflib
|
||||||
# github.com/prometheus/client_golang v1.20.5
|
# github.com/prometheus/client_golang v1.21.0
|
||||||
## explicit; go 1.20
|
## explicit; go 1.21
|
||||||
github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil
|
github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil
|
||||||
github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header
|
github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header
|
||||||
github.com/prometheus/client_golang/prometheus
|
github.com/prometheus/client_golang/prometheus
|
||||||
|
@ -745,7 +745,7 @@ github.com/prometheus/client_golang/prometheus/promhttp
|
||||||
# github.com/prometheus/client_model v0.6.1
|
# github.com/prometheus/client_model v0.6.1
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
github.com/prometheus/client_model/go
|
github.com/prometheus/client_model/go
|
||||||
# github.com/prometheus/common v0.61.0
|
# github.com/prometheus/common v0.62.0
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
github.com/prometheus/common/expfmt
|
github.com/prometheus/common/expfmt
|
||||||
github.com/prometheus/common/model
|
github.com/prometheus/common/model
|
||||||
|
|
Loading…
Reference in New Issue