Change:
I would like to propose the graduation of the following apiserver metrics from alpha to stable: With the exception of the metric these metrics have been stable for 2 years. The metric has been stable for 12 months.
/sig api-machinery /sig instrumentation
/assign /triage accepted
I'm okay with promoting all of these except I am hesitant about since it is relatively new. Can we omit that one?
I agree with the metric was patched a year ago as part of , so it would be best to wait a bit more until the majority of Kubernetes users catch up to the patched version and start using the new version of the metric in production.
A couple of renaming suggestions, since it is important to get it right before graduation: apiserverresponsesizes =apiserverresponsesizebytes aggregatorunavailableapiservice =aggregatorunavailableapiservices One concern regarding . It was very recently changed but the change was later reverted by In the end, the metric wasn't really changed, but it might raise the concern that some users may still need additional information from this metric so I am on the fence with this one. Side implementation note that we will need to keep in mind if we graduate is that the graduation should only affect the webhook admission metric and not the other, so we will need to pass the stability level to
Thank you and for the feedback. To clarify then, are the decisions to not graduate and final?
I'm actually okay with , the namespace addition was recent but it was a bad idea and was reverted. It has otherwise been in use for quite some time, so I'd be comfortable with promoting it.
I'm willing to make a PR for this one
+1 it wasn't a hard no from my side, just wanted to raise some concerns in case anyone had an objection.
/assign /unassign
Thank you for the feedback, and To summarize, we are in agreement to graduate all but the metric. Please correct me if I'm wrong.
/cc
since all the three metrics that are created with this function are graduating to stable, do you think I should still pass the to the function or should I just set the metrics created by this functions as stable by default? update: Seems like is designed to parse whatever's in front of . So putting a variable there (that is passed to the function) will cause the script to fail. Please correct me if I'm wrong. update: Even setting the metrics to be stable by default will cause the script to fail and you'll get an error saying for the following line: It appears that the name of the stable metrics should be given to that object as a string and using the output of a function ( in this case) will cause the script to fail.
The PR is ready to be reviewed:

Discussion:
import ( "context" <del> "fmt" </del> "strconv" "time"

) var ( <del> // Use buckets ranging from 5 ms to 2.5 seconds (admission webhooks timeout at 30 seconds by default). latencyBuckets       = []float64{0.005, 0.025, 0.1, 0.5, 1.0, 2.5} </del> latencySummaryMaxAge = 5 * time.Hour // Metrics provides access to all admission metrics.

func newAdmissionMetrics() *AdmissionMetrics { // Admission metrics for a step of the admission flow. The entire admission flow is broken down into a series of steps // Each step is identified by a distinct type label value. <del> step := newMetricSet("step", []string{"type", "operation", "rejected"}, "Admission sub-step %s, broken out for each operation and API resource and step type (validate or admit).", true) </del> <ins> // Use buckets ranging from 5 ms to 2.5 seconds. step := &metricSet{ latencies: metrics.NewHistogramVec( &metrics.HistogramOpts{ Namespace:      namespace, Subsystem:      subsystem, Name:           "step_admission_duration_seconds", Help:           "Admission sub-step latency histogram in seconds, broken out for each operation and API resource and step type (validate or admit).", Buckets:        []float64{0.005, 0.025, 0.1, 0.5, 1.0, 2.5}, StabilityLevel: metrics.STABLE, }, []string{"type", "operation", "rejected"}, ), latenciesSummary: metrics.NewSummaryVec( &metrics.SummaryOpts{ Namespace:      namespace, Subsystem:      subsystem, Name:           "step_admission_duration_seconds_summary", Help:           "Admission sub-step latency summary in seconds, broken out for each operation and API resource and step type (validate or admit).", MaxAge:         latencySummaryMaxAge, StabilityLevel: metrics.ALPHA, }, []string{"type", "operation", "rejected"}, ), } </ins> // Built-in admission controller metrics. Each admission controller is identified by name. <del> controller := newMetricSet("controller", []string{"name", "type", "operation", "rejected"}, "Admission controller %s, identified by name and broken out for each operation and API resource and type (validate or admit).", false) </del> <ins> // Use buckets ranging from 5 ms to 2.5 seconds. controller := &metricSet{ latencies: metrics.NewHistogramVec( &metrics.HistogramOpts{ Namespace:      namespace, Subsystem:      subsystem, Name:           "controller_admission_duration_seconds", Help:           "Admission controller latency histogram in seconds, identified by name and broken out for each operation and API resource and type (validate or admit).", Buckets:        []float64{0.005, 0.025, 0.1, 0.5, 1.0, 2.5}, StabilityLevel: metrics.STABLE, }, []string{"name", "type", "operation", "rejected"}, ), latenciesSummary: nil, } </ins> // Admission webhook metrics. Each webhook is identified by name. <del> webhook := newMetricSet("webhook", []string{"name", "type", "operation", "rejected"}, "Admission webhook %s, identified by name and broken out for each operation and API resource and type (validate or admit).", false) </del> <ins> // Use buckets ranging from 5 ms to 2.5 seconds (admission webhooks timeout at 30 seconds by default). webhook := &metricSet{ latencies: metrics.NewHistogramVec( &metrics.HistogramOpts{ Namespace:      namespace, Subsystem:      subsystem, Name:           "webhook_admission_duration_seconds", Help:           "Admission webhook latency histogram in seconds, identified by name and broken out for each operation and API resource and type (validate or admit).", Buckets:        []float64{0.005, 0.025, 0.1, 0.5, 1.0, 2.5}, StabilityLevel: metrics.STABLE, }, []string{"name", "type", "operation", "rejected"}, ), latenciesSummary: nil, } </ins> webhookRejection := metrics.NewCounterVec( &metrics.CounterOpts{

latenciesSummary *metrics.SummaryVec } <del> func newMetricSet(name string, labels []string, helpTemplate string, hasSummary bool) *metricSet { var summary *metrics.SummaryVec if hasSummary { summary = metrics.NewSummaryVec( &metrics.SummaryOpts{ Namespace:      namespace, Subsystem:      subsystem, Name:           fmt.Sprintf("%s_admission_duration_seconds_summary", name), Help:           fmt.Sprintf(helpTemplate, "latency summary in seconds"), MaxAge:         latencySummaryMaxAge, StabilityLevel: metrics.ALPHA, }, labels, ) } return &metricSet{ latencies: metrics.NewHistogramVec( &metrics.HistogramOpts{ Namespace:      namespace, Subsystem:      subsystem, Name:           fmt.Sprintf("%s_admission_duration_seconds", name), Help:           fmt.Sprintf(helpTemplate, "latency histogram in seconds"), Buckets:        latencyBuckets, StabilityLevel: metrics.ALPHA, }, labels, ), latenciesSummary: summary, } } </del> // MustRegister registers all the prometheus metrics in the metricSet. func (m *metricSet) mustRegister() { legacyregistry.MustRegister(m.latencies)

Help: "Response size distribution in bytes for each group, version, verb, resource, subresource, scope and component.", // Use buckets ranging from 1000 bytes (1KB) to 10^9 bytes (1GB). Buckets:        compbasemetrics.ExponentialBuckets(1000, 10.0, 7), <del> StabilityLevel: compbasemetrics.ALPHA, </del> <ins> StabilityLevel: compbasemetrics.STABLE, </ins> }, []string{"verb", "group", "version", "resource", "subresource", "scope", "component"}, )

&compbasemetrics.GaugeOpts{ Name:           "apiserver_current_inflight_requests", Help:           "Maximal number of currently used inflight request limit of this apiserver per request kind in last second.", <del> StabilityLevel: compbasemetrics.ALPHA, </del> <ins> StabilityLevel: compbasemetrics.STABLE, </ins> }, []string{"request_kind"}, )

- 4.096 - 8.192 - 16.384 <ins> - name: controller_admission_duration_seconds subsystem: admission namespace: apiserver help: Admission controller latency histogram in seconds, identified by name and broken out for each operation and API resource and type (validate or admit). type: Histogram stabilityLevel: STABLE labels: - name - operation - rejected - type buckets: - 0.005 - 0.025 - 0.1 - 0.5 - 1 - 2.5 - name: step_admission_duration_seconds subsystem: admission namespace: apiserver help: Admission sub-step latency histogram in seconds, broken out for each operation and API resource and step type (validate or admit). type: Histogram stabilityLevel: STABLE labels: - operation - rejected - type buckets: - 0.005 - 0.025 - 0.1 - 0.5 - 1 - 2.5 - name: webhook_admission_duration_seconds subsystem: admission namespace: apiserver help: Admission webhook latency histogram in seconds, identified by name and broken out for each operation and API resource and type (validate or admit). type: Histogram stabilityLevel: STABLE labels: - name - operation - rejected - type buckets: - 0.005 - 0.025 - 0.1 - 0.5 - 1 - 2.5 - name: apiserver_current_inflight_requests help: Maximal number of currently used inflight request limit of this apiserver per request kind in last second. type: Gauge stabilityLevel: STABLE labels: - request_kind </ins> - name: apiserver_request_duration_seconds help: Response latency distribution in seconds for each verb, dry run value, group, version, resource, subresource, scope and component.

- resource - subresource - version <ins> - name: apiserver_response_sizes help: Response size distribution in bytes for each group, version, verb, resource, subresource, scope and component. type: Histogram stabilityLevel: STABLE labels: - component - group - resource - scope - subresource - verb - version buckets: - 1000 - 10000 - 100000 - 1e+06 - 1e+07 - 1e+08 - 1e+09 </ins> - name: apiserver_storage_objects help: Number of stored objects at the time of last check split by kind. type: Gauge