Add native histogram support for histogram metrics (#9971)

Co-authored-by: Ricardo Katz <rikatz@users.noreply.github.com>
This commit is contained in:
Sebastian Rabenhorst 2024-08-23 18:32:48 +02:00 committed by GitHub
parent 1ea376a0ee
commit ffee96c58c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 128 additions and 38 deletions

View file

@ -108,6 +108,8 @@ type Configuration struct {
EnableMetrics bool
MetricsPerHost bool
MetricsBuckets *collectors.HistogramBuckets
MetricsBucketFactor float64
MetricsMaxBuckets uint32
ReportStatusClasses bool
ExcludeSocketMetrics []string

View file

@ -99,7 +99,7 @@ var requestTags = []string{
// NewSocketCollector creates a new SocketCollector instance using
// the ingress watch namespace and class used by the controller
func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStatusClasses bool, buckets HistogramBuckets, excludeMetrics []string) (*SocketCollector, error) {
func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStatusClasses bool, buckets HistogramBuckets, bucketFactor float64, maxBuckets uint32, excludeMetrics []string) (*SocketCollector, error) {
socket := "/tmp/nginx/prometheus-nginx.socket"
// unix sockets must be unlink()ed before being used
//nolint:errcheck // Ignore unlink error
@ -144,11 +144,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat
connectTime: histogramMetric(
&prometheus.HistogramOpts{
Name: "connect_duration_seconds",
Help: "The time spent on establishing a connection with the upstream server",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.TimeBuckets,
Name: "connect_duration_seconds",
Help: "The time spent on establishing a connection with the upstream server",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.TimeBuckets,
NativeHistogramBucketFactor: bucketFactor,
NativeHistogramMaxBucketNumber: maxBuckets,
},
requestTags,
em,
@ -157,11 +159,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat
headerTime: histogramMetric(
&prometheus.HistogramOpts{
Name: "header_duration_seconds",
Help: "The time spent on receiving first header from the upstream server",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.TimeBuckets,
Name: "header_duration_seconds",
Help: "The time spent on receiving first header from the upstream server",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.TimeBuckets,
NativeHistogramBucketFactor: bucketFactor,
NativeHistogramMaxBucketNumber: maxBuckets,
},
requestTags,
em,
@ -169,11 +173,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat
),
responseTime: histogramMetric(
&prometheus.HistogramOpts{
Name: "response_duration_seconds",
Help: "The time spent on receiving the response from the upstream server",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.TimeBuckets,
Name: "response_duration_seconds",
Help: "The time spent on receiving the response from the upstream server",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.TimeBuckets,
NativeHistogramBucketFactor: bucketFactor,
NativeHistogramMaxBucketNumber: maxBuckets,
},
requestTags,
em,
@ -182,11 +188,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat
requestTime: histogramMetric(
&prometheus.HistogramOpts{
Name: "request_duration_seconds",
Help: "The request processing time in milliseconds",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.TimeBuckets,
Name: "request_duration_seconds",
Help: "The request processing time in milliseconds",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.TimeBuckets,
NativeHistogramBucketFactor: bucketFactor,
NativeHistogramMaxBucketNumber: maxBuckets,
},
requestTags,
em,
@ -195,11 +203,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat
responseLength: histogramMetric(
&prometheus.HistogramOpts{
Name: "response_size",
Help: "The response length (including request line, header, and request body)",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.LengthBuckets,
Name: "response_size",
Help: "The response length (including request line, header, and request body)",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.LengthBuckets,
NativeHistogramBucketFactor: bucketFactor,
NativeHistogramMaxBucketNumber: maxBuckets,
},
requestTags,
em,
@ -208,11 +218,13 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat
requestLength: histogramMetric(
&prometheus.HistogramOpts{
Name: "request_size",
Help: "The request length (including request line, header, and request body)",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.LengthBuckets,
Name: "request_size",
Help: "The request length (including request line, header, and request body)",
Namespace: PrometheusNamespace,
ConstLabels: constLabels,
Buckets: buckets.LengthBuckets,
NativeHistogramBucketFactor: bucketFactor,
NativeHistogramMaxBucketNumber: maxBuckets,
},
requestTags,
em,

View file

@ -83,6 +83,9 @@ func TestCollector(t *testing.T) {
prometheus.ExponentialBuckets(10, 10, 7),
}
bucketFactor := 1.1
maxBuckets := uint32(100)
cases := []struct {
name string
data []string
@ -594,7 +597,7 @@ func TestCollector(t *testing.T) {
t.Run(c.name, func(t *testing.T) {
registry := prometheus.NewPedanticRegistry()
sc, err := NewSocketCollector("pod", "default", "ingress", true, c.useStatusClasses, buckets, c.excludeMetrics)
sc, err := NewSocketCollector("pod", "default", "ingress", true, c.useStatusClasses, buckets, bucketFactor, maxBuckets, c.excludeMetrics)
if err != nil {
t.Errorf("%v: unexpected error creating new SocketCollector: %v", c.name, err)
}

View file

@ -71,7 +71,7 @@ type collector struct {
}
// NewCollector creates a new metric collector the for ingress controller
func NewCollector(metricsPerHost, reportStatusClasses bool, registry *prometheus.Registry, ingressclass string, buckets collectors.HistogramBuckets, excludedSocketMetrics []string) (Collector, error) {
func NewCollector(metricsPerHost, reportStatusClasses bool, registry *prometheus.Registry, ingressclass string, buckets collectors.HistogramBuckets, bucketFactor float64, maxBuckets uint32, excludedSocketMetrics []string) (Collector, error) {
podNamespace := os.Getenv("POD_NAMESPACE")
if podNamespace == "" {
podNamespace = "default"
@ -89,7 +89,7 @@ func NewCollector(metricsPerHost, reportStatusClasses bool, registry *prometheus
return nil, err
}
s, err := collectors.NewSocketCollector(podName, podNamespace, ingressclass, metricsPerHost, reportStatusClasses, buckets, excludedSocketMetrics)
s, err := collectors.NewSocketCollector(podName, podNamespace, ingressclass, metricsPerHost, reportStatusClasses, buckets, bucketFactor, maxBuckets, excludedSocketMetrics)
if err != nil {
return nil, err
}