Bump github.com/prometheus/client_golang from 1.19.1 to 1.20.3

Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.19.1 to 1.20.3.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/v1.20.3/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.19.1...v1.20.3)

---
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>
This commit is contained in:
dependabot[bot] 2024-09-05 12:45:16 +00:00 committed by GitHub
parent de0c50cc32
commit 33e24f8166
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 396 additions and 69 deletions

2
go.mod
View file

@ -16,7 +16,7 @@ require (
github.com/go-sql-driver/mysql v1.8.1 github.com/go-sql-driver/mysql v1.8.1
github.com/lib/pq v1.10.9 github.com/lib/pq v1.10.9
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.19.1 github.com/prometheus/client_golang v1.20.3
github.com/redis/go-redis/v9 v9.6.1 github.com/redis/go-redis/v9 v9.6.1
) )

6
go.sum
View file

@ -96,6 +96,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -116,8 +118,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
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.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=

View file

@ -16,8 +16,3 @@ Go support for Protocol Buffers - Google's data interchange format
http://github.com/golang/protobuf/ http://github.com/golang/protobuf/
Copyright 2010 The Go Authors Copyright 2010 The Go Authors
See source code for license details. See source code for license details.
Support for streaming Protocol Buffer messages for the Go language (golang).
https://github.com/matttproud/golang_protobuf_extensions
Copyright 2013 Matt T. Proud
Licensed under the Apache License, Version 2.0

View file

@ -22,13 +22,13 @@ import (
// goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats. // goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats.
// From Go 1.17 those similar (and better) statistics are provided by runtime/metrics, so // 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 // while eval closure works on runtime.MemStats, the struct from Go 1.17+ is
// populated using runtime/metrics. // populated using runtime/metrics. Those are the defaults we can't alter.
func goRuntimeMemStats() memStatsMetrics { func goRuntimeMemStats() memStatsMetrics {
return memStatsMetrics{ return memStatsMetrics{
{ {
desc: NewDesc( desc: NewDesc(
memstatNamespace("alloc_bytes"), memstatNamespace("alloc_bytes"),
"Number of bytes allocated and still in use.", "Number of bytes allocated in heap and currently in use. Equals to /memory/classes/heap/objects:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) },
@ -36,7 +36,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("alloc_bytes_total"), memstatNamespace("alloc_bytes_total"),
"Total number of bytes allocated, even if freed.", "Total number of bytes allocated in heap until now, even if released already. Equals to /gc/heap/allocs:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) },
@ -44,23 +44,16 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("sys_bytes"), memstatNamespace("sys_bytes"),
"Number of bytes obtained from system.", "Number of bytes obtained from system. Equals to /memory/classes/total:byte.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.Sys) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.Sys) },
valType: GaugeValue, valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("lookups_total"),
"Total number of pointer lookups.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.Lookups) },
valType: CounterValue,
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("mallocs_total"), memstatNamespace("mallocs_total"),
"Total number of mallocs.", // 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, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) },
@ -68,7 +61,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("frees_total"), memstatNamespace("frees_total"),
"Total number of frees.", "Total number of heap objects frees. Equals to /gc/heap/frees:objects + /gc/heap/tiny/allocs:objects.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.Frees) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.Frees) },
@ -76,7 +69,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("heap_alloc_bytes"), memstatNamespace("heap_alloc_bytes"),
"Number of heap bytes allocated and still in use.", "Number of heap bytes allocated and currently in use, same as go_memstats_alloc_bytes. Equals to /memory/classes/heap/objects:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) },
@ -84,7 +77,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("heap_sys_bytes"), memstatNamespace("heap_sys_bytes"),
"Number of heap bytes obtained from system.", "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, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) },
@ -92,7 +85,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("heap_idle_bytes"), memstatNamespace("heap_idle_bytes"),
"Number of heap bytes waiting to be used.", "Number of heap bytes waiting to be used. Equals to /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) },
@ -100,7 +93,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("heap_inuse_bytes"), memstatNamespace("heap_inuse_bytes"),
"Number of heap bytes that are in use.", "Number of heap bytes that are in use. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) },
@ -108,7 +101,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("heap_released_bytes"), memstatNamespace("heap_released_bytes"),
"Number of heap bytes released to OS.", "Number of heap bytes released to OS. Equals to /memory/classes/heap/released:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) },
@ -116,7 +109,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("heap_objects"), memstatNamespace("heap_objects"),
"Number of allocated objects.", "Number of currently allocated objects. Equals to /gc/heap/objects:objects.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) },
@ -124,7 +117,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("stack_inuse_bytes"), memstatNamespace("stack_inuse_bytes"),
"Number of bytes in use by the stack allocator.", "Number of bytes obtained from system for stack allocator in non-CGO environments. Equals to /memory/classes/heap/stacks:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) },
@ -132,7 +125,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("stack_sys_bytes"), memstatNamespace("stack_sys_bytes"),
"Number of bytes obtained from system for stack allocator.", "Number of bytes obtained from system for stack allocator. Equals to /memory/classes/heap/stacks:bytes + /memory/classes/os-stacks:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) },
@ -140,7 +133,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("mspan_inuse_bytes"), memstatNamespace("mspan_inuse_bytes"),
"Number of bytes in use by mspan structures.", "Number of bytes in use by mspan structures. Equals to /memory/classes/metadata/mspan/inuse:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) },
@ -148,7 +141,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("mspan_sys_bytes"), memstatNamespace("mspan_sys_bytes"),
"Number of bytes used for mspan structures obtained from system.", "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, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) },
@ -156,7 +149,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("mcache_inuse_bytes"), memstatNamespace("mcache_inuse_bytes"),
"Number of bytes in use by mcache structures.", "Number of bytes in use by mcache structures. Equals to /memory/classes/metadata/mcache/inuse:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) },
@ -164,7 +157,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("mcache_sys_bytes"), memstatNamespace("mcache_sys_bytes"),
"Number of bytes used for mcache structures obtained from system.", "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, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) },
@ -172,7 +165,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("buck_hash_sys_bytes"), memstatNamespace("buck_hash_sys_bytes"),
"Number of bytes used by the profiling bucket hash table.", "Number of bytes used by the profiling bucket hash table. Equals to /memory/classes/profiling/buckets:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) },
@ -180,7 +173,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("gc_sys_bytes"), memstatNamespace("gc_sys_bytes"),
"Number of bytes used for garbage collection system metadata.", "Number of bytes used for garbage collection system metadata. Equals to /memory/classes/metadata/other:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) },
@ -188,7 +181,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("other_sys_bytes"), memstatNamespace("other_sys_bytes"),
"Number of bytes used for other system allocations.", "Number of bytes used for other system allocations. Equals to /memory/classes/other:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) },
@ -196,7 +189,7 @@ func goRuntimeMemStats() memStatsMetrics {
}, { }, {
desc: NewDesc( desc: NewDesc(
memstatNamespace("next_gc_bytes"), memstatNamespace("next_gc_bytes"),
"Number of heap bytes when next garbage collection will take place.", "Number of heap bytes when next garbage collection will take place. Equals to /gc/heap/goal:bytes.",
nil, nil, nil, nil,
), ),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) }, eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) },
@ -225,7 +218,7 @@ func newBaseGoCollector() baseGoCollector {
nil, nil), nil, nil),
gcDesc: NewDesc( gcDesc: NewDesc(
"go_gc_duration_seconds", "go_gc_duration_seconds",
"A summary of the pause duration of garbage collection cycles.", "A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.",
nil, nil), nil, nil),
gcLastTimeDesc: NewDesc( gcLastTimeDesc: NewDesc(
"go_memstats_last_gc_time_seconds", "go_memstats_last_gc_time_seconds",

View file

@ -17,6 +17,7 @@
package prometheus package prometheus
import ( import (
"fmt"
"math" "math"
"runtime" "runtime"
"runtime/metrics" "runtime/metrics"
@ -153,7 +154,8 @@ func defaultGoCollectorOptions() internal.GoCollectorOptions {
"/gc/heap/frees-by-size:bytes": goGCHeapFreesBytes, "/gc/heap/frees-by-size:bytes": goGCHeapFreesBytes,
}, },
RuntimeMetricRules: []internal.GoCollectorRule{ RuntimeMetricRules: []internal.GoCollectorRule{
//{Matcher: regexp.MustCompile("")}, // Recommended metrics we want by default from runtime/metrics.
{Matcher: internal.GoCollectorDefaultRuntimeMetrics},
}, },
} }
} }
@ -203,6 +205,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
// to fail here. This condition is tested in TestExpectedRuntimeMetrics. // to fail here. This condition is tested in TestExpectedRuntimeMetrics.
continue continue
} }
help := attachOriginalName(d.Description.Description, d.Name)
sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name}) sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name})
sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1] sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1]
@ -214,7 +217,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
m = newBatchHistogram( m = newBatchHistogram(
NewDesc( NewDesc(
BuildFQName(namespace, subsystem, name), BuildFQName(namespace, subsystem, name),
d.Description.Description, help,
nil, nil,
nil, nil,
), ),
@ -226,7 +229,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
Namespace: namespace, Namespace: namespace,
Subsystem: subsystem, Subsystem: subsystem,
Name: name, Name: name,
Help: d.Description.Description, Help: help,
}, },
) )
} else { } else {
@ -234,7 +237,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
Namespace: namespace, Namespace: namespace,
Subsystem: subsystem, Subsystem: subsystem,
Name: name, Name: name,
Help: d.Description.Description, Help: help,
}) })
} }
metricSet = append(metricSet, m) metricSet = append(metricSet, m)
@ -284,6 +287,10 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
} }
} }
func attachOriginalName(desc, origName string) string {
return fmt.Sprintf("%s Sourced from %s", desc, origName)
}
// Describe returns all descriptions of the collector. // Describe returns all descriptions of the collector.
func (c *goCollector) Describe(ch chan<- *Desc) { func (c *goCollector) Describe(ch chan<- *Desc) {
c.base.Describe(ch) c.base.Describe(ch)
@ -376,13 +383,13 @@ func unwrapScalarRMValue(v metrics.Value) float64 {
// //
// This should never happen because we always populate our metric // This should never happen because we always populate our metric
// set from the runtime/metrics package. // set from the runtime/metrics package.
panic("unexpected unsupported metric") panic("unexpected bad kind metric")
default: default:
// Unsupported metric kind. // Unsupported metric kind.
// //
// This should never happen because we check for this during initialization // This should never happen because we check for this during initialization
// and flag and filter metrics whose kinds we don't understand. // and flag and filter metrics whose kinds we don't understand.
panic("unexpected unsupported metric kind") panic(fmt.Sprintf("unexpected unsupported metric: %v", v.Kind()))
} }
} }

View file

@ -440,7 +440,7 @@ type HistogramOpts struct {
// constant (or any negative float value). // constant (or any negative float value).
NativeHistogramZeroThreshold float64 NativeHistogramZeroThreshold float64
// The remaining fields define a strategy to limit the number of // The next three fields define a strategy to limit the number of
// populated sparse buckets. If NativeHistogramMaxBucketNumber is left // populated sparse buckets. If NativeHistogramMaxBucketNumber is left
// at zero, the number of buckets is not limited. (Note that this might // at zero, the number of buckets is not limited. (Note that this might
// lead to unbounded memory consumption if the values observed by the // lead to unbounded memory consumption if the values observed by the
@ -473,6 +473,22 @@ type HistogramOpts struct {
NativeHistogramMinResetDuration time.Duration NativeHistogramMinResetDuration time.Duration
NativeHistogramMaxZeroThreshold float64 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 is for testing purposes, by default it's time.Now.
now func() time.Time now func() time.Time
@ -532,6 +548,7 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
if opts.afterFunc == nil { if opts.afterFunc == nil {
opts.afterFunc = time.AfterFunc opts.afterFunc = time.AfterFunc
} }
h := &histogram{ h := &histogram{
desc: desc, desc: desc,
upperBounds: opts.Buckets, upperBounds: opts.Buckets,
@ -556,6 +573,7 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
h.nativeHistogramZeroThreshold = DefNativeHistogramZeroThreshold h.nativeHistogramZeroThreshold = DefNativeHistogramZeroThreshold
} // Leave h.nativeHistogramZeroThreshold at 0 otherwise. } // Leave h.nativeHistogramZeroThreshold at 0 otherwise.
h.nativeHistogramSchema = pickSchema(opts.NativeHistogramBucketFactor) h.nativeHistogramSchema = pickSchema(opts.NativeHistogramBucketFactor)
h.nativeExemplars = makeNativeExemplars(opts.NativeHistogramExemplarTTL, opts.NativeHistogramMaxExemplars)
} }
for i, upperBound := range h.upperBounds { for i, upperBound := range h.upperBounds {
if i < len(h.upperBounds)-1 { if i < len(h.upperBounds)-1 {
@ -726,6 +744,7 @@ type histogram struct {
// scheduled for a later time (when nativeHistogramMinResetDuration has // scheduled for a later time (when nativeHistogramMinResetDuration has
// passed). // passed).
resetScheduled bool resetScheduled bool
nativeExemplars nativeExemplars
// now is for testing purposes, by default it's time.Now. // now is for testing purposes, by default it's time.Now.
now func() time.Time now func() time.Time
@ -742,6 +761,9 @@ func (h *histogram) Observe(v float64) {
h.observe(v, h.findBucket(v)) 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) { func (h *histogram) ObserveWithExemplar(v float64, e Labels) {
i := h.findBucket(v) i := h.findBucket(v)
h.observe(v, i) h.observe(v, i)
@ -821,6 +843,15 @@ func (h *histogram) Write(out *dto.Metric) error {
Length: proto.Uint32(0), Length: proto.Uint32(0),
}} }}
} }
// If exemplars are not configured, the cap will be 0.
// So append is not needed in this case.
if cap(h.nativeExemplars.exemplars) > 0 {
h.nativeExemplars.Lock()
his.Exemplars = append(his.Exemplars, h.nativeExemplars.exemplars...)
h.nativeExemplars.Unlock()
}
} }
addAndResetCounts(hotCounts, coldCounts) addAndResetCounts(hotCounts, coldCounts)
return nil return nil
@ -1091,8 +1122,10 @@ func (h *histogram) resetCounts(counts *histogramCounts) {
deleteSyncMap(&counts.nativeHistogramBucketsPositive) deleteSyncMap(&counts.nativeHistogramBucketsPositive)
} }
// updateExemplar replaces the exemplar for the provided bucket. With empty // updateExemplar replaces the exemplar for the provided classic bucket.
// labels, it's a no-op. It panics if any of the labels is invalid. // 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) { func (h *histogram) updateExemplar(v float64, bucket int, l Labels) {
if l == nil { if l == nil {
return return
@ -1102,6 +1135,10 @@ func (h *histogram) updateExemplar(v float64, bucket int, l Labels) {
panic(err) panic(err)
} }
h.exemplars[bucket].Store(e) 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 // HistogramVec is a Collector that bundles a set of Histograms that all share the
@ -1336,6 +1373,48 @@ func MustNewConstHistogram(
return m 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 type buckSort []*dto.Bucket
func (s buckSort) Len() int { func (s buckSort) Len() int {
@ -1575,3 +1654,182 @@ func addAndResetCounts(hot, cold *histogramCounts) {
atomic.AddUint64(&hot.nativeHistogramZeroBucket, atomic.LoadUint64(&cold.nativeHistogramZeroBucket)) atomic.AddUint64(&hot.nativeHistogramZeroBucket, atomic.LoadUint64(&cold.nativeHistogramZeroBucket))
atomic.StoreUint64(&cold.nativeHistogramZeroBucket, 0) 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 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.ttl == -1 {
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:]...)...)...)
}
}

View file

@ -30,3 +30,5 @@ type GoCollectorOptions struct {
RuntimeMetricSumForHist map[string]string RuntimeMetricSumForHist map[string]string
RuntimeMetricRules []GoCollectorRule RuntimeMetricRules []GoCollectorRule
} }
var GoCollectorDefaultRuntimeMetrics = regexp.MustCompile(`/gc/gogc:percent|/gc/gomemlimit:bytes|/sched/gomaxprocs:threads`)

View file

@ -234,7 +234,7 @@ func NewMetricWithExemplars(m Metric, exemplars ...Exemplar) (Metric, error) {
) )
for i, e := range exemplars { for i, e := range exemplars {
ts := e.Timestamp ts := e.Timestamp
if ts == (time.Time{}) { if ts.IsZero() {
ts = now ts = now
} }
exs[i], err = newExemplar(e.Value, ts, e.Labels) exs[i], err = newExemplar(e.Value, ts, e.Labels)

View file

@ -30,6 +30,7 @@ type processCollector struct {
vsize, maxVsize *Desc vsize, maxVsize *Desc
rss *Desc rss *Desc
startTime *Desc startTime *Desc
inBytes, outBytes *Desc
} }
// ProcessCollectorOpts defines the behavior of a process metrics collector // ProcessCollectorOpts defines the behavior of a process metrics collector
@ -100,6 +101,16 @@ func NewProcessCollector(opts ProcessCollectorOpts) Collector {
"Start time of the process since unix epoch in seconds.", "Start time of the process since unix epoch in seconds.",
nil, nil, 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 { if opts.PidFn == nil {
@ -129,6 +140,8 @@ func (c *processCollector) Describe(ch chan<- *Desc) {
ch <- c.maxVsize ch <- c.maxVsize
ch <- c.rss ch <- c.rss
ch <- c.startTime 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.

View file

@ -63,4 +63,18 @@ func (c *processCollector) processCollect(ch chan<- Metric) {
} else { } else {
c.reportError(ch, nil, err) 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)
}
} }

View file

@ -314,17 +314,18 @@ func (r *Registry) Register(c Collector) error {
if dimHash != desc.dimHash { 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) 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)
} }
} else { continue
}
// ...then check the new descriptors already seen. // ...then check the new descriptors already seen.
if dimHash, exists := newDimHashesByName[desc.fqName]; exists { if dimHash, exists := newDimHashesByName[desc.fqName]; exists {
if dimHash != desc.dimHash { 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) return fmt.Errorf("descriptors reported by collector have inconsistent label names or help strings for the same fully-qualified name, offender is %s", desc)
} }
} else { continue
}
newDimHashesByName[desc.fqName] = desc.dimHash newDimHashesByName[desc.fqName] = desc.dimHash
} }
}
}
// A Collector yielding no Desc at all is considered unchecked. // A Collector yielding no Desc at all is considered unchecked.
if len(newDescIDs) == 0 { if len(newDescIDs) == 0 {
r.uncheckedCollectors = append(r.uncheckedCollectors, c) r.uncheckedCollectors = append(r.uncheckedCollectors, c)

View file

@ -783,3 +783,45 @@ func MustNewConstSummary(
} }
return m 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
}

View file

@ -507,7 +507,7 @@ func (m *metricMap) getOrCreateMetricWithLabelValues(
return metric return metric
} }
// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value // getOrCreateMetricWithLabels retrieves the metric by hash and label value
// or creates it and returns the new one. // or creates it and returns the new one.
// //
// This function holds the mutex. // This function holds the mutex.

2
vendor/modules.txt vendored
View file

@ -177,7 +177,7 @@ github.com/munnerz/goautoneg
# github.com/pkg/errors v0.9.1 # github.com/pkg/errors v0.9.1
## explicit ## explicit
github.com/pkg/errors github.com/pkg/errors
# github.com/prometheus/client_golang v1.19.1 # github.com/prometheus/client_golang v1.20.3
## explicit; go 1.20 ## explicit; go 1.20
github.com/prometheus/client_golang/prometheus github.com/prometheus/client_golang/prometheus
github.com/prometheus/client_golang/prometheus/internal github.com/prometheus/client_golang/prometheus/internal