diff --git a/pkg/util/flowcontrol/apf_controller.go b/pkg/util/flowcontrol/apf_controller.go index 2a4b8987b..fa18875e9 100644 --- a/pkg/util/flowcontrol/apf_controller.go +++ b/pkg/util/flowcontrol/apf_controller.go @@ -102,7 +102,7 @@ type configController struct { name string // varies in tests of fighting controllers clock clock.PassiveClock queueSetFactory fq.QueueSetFactory - reqsGaugePairVec metrics.RatioedGaugePairVec + reqsGaugeVec metrics.RatioedGaugeVec execSeatsGaugeVec metrics.RatioedGaugeVec // How this controller appears in an ObjectMeta ManagedFieldsEntry.Manager @@ -205,7 +205,7 @@ func newTestableController(config TestableConfig) *configController { name: config.Name, clock: config.Clock, queueSetFactory: config.QueueSetFactory, - reqsGaugePairVec: config.ReqsGaugePairVec, + reqsGaugeVec: config.ReqsGaugeVec, execSeatsGaugeVec: config.ExecSeatsGaugeVec, asFieldManager: config.AsFieldManager, foundToDangling: config.FoundToDangling, @@ -539,7 +539,7 @@ func (meal *cfgMeal) digestNewPLsLocked(newPLs []*flowcontrol.PriorityLevelConfi state := meal.cfgCtlr.priorityLevelStates[pl.Name] if state == nil { labelValues := []string{pl.Name} - state = &priorityLevelState{reqsGaugePair: meal.cfgCtlr.reqsGaugePairVec.NewForLabelValuesSafe(1, 1, labelValues), execSeatsObs: meal.cfgCtlr.execSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelValues)} + state = &priorityLevelState{reqsGaugePair: metrics.RatioedGaugeVecPhasedElementPair(meal.cfgCtlr.reqsGaugeVec, 1, 1, labelValues), execSeatsObs: meal.cfgCtlr.execSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelValues)} } qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, state.queues, pl, meal.cfgCtlr.requestWaitLimit, state.reqsGaugePair, state.execSeatsObs) if err != nil { @@ -769,7 +769,7 @@ func (meal *cfgMeal) presyncFlowSchemaStatus(fs *flowcontrol.FlowSchema, isDangl func (meal *cfgMeal) imaginePL(proto *flowcontrol.PriorityLevelConfiguration, requestWaitLimit time.Duration) { klog.V(3).Infof("No %s PriorityLevelConfiguration found, imagining one", proto.Name) labelValues := []string{proto.Name} - reqsGaugePair := meal.cfgCtlr.reqsGaugePairVec.NewForLabelValuesSafe(1, 1, labelValues) + reqsGaugePair := metrics.RatioedGaugeVecPhasedElementPair(meal.cfgCtlr.reqsGaugeVec, 1, 1, labelValues) execSeatsObs := meal.cfgCtlr.execSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelValues) qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, nil, proto, requestWaitLimit, reqsGaugePair, execSeatsObs) if err != nil { diff --git a/pkg/util/flowcontrol/apf_filter.go b/pkg/util/flowcontrol/apf_filter.go index 54add96ed..554eb383d 100644 --- a/pkg/util/flowcontrol/apf_filter.go +++ b/pkg/util/flowcontrol/apf_filter.go @@ -100,7 +100,7 @@ func New( FlowcontrolClient: flowcontrolClient, ServerConcurrencyLimit: serverConcurrencyLimit, RequestWaitLimit: requestWaitLimit, - ReqsGaugePairVec: metrics.PriorityLevelConcurrencyPairVec, + ReqsGaugeVec: metrics.PriorityLevelConcurrencyGaugeVec, ExecSeatsGaugeVec: metrics.PriorityLevelExecutionSeatsGaugeVec, QueueSetFactory: fqs.NewQueueSetFactory(clk), }) @@ -140,8 +140,8 @@ type TestableConfig struct { // RequestWaitLimit configured on the server RequestWaitLimit time.Duration - // GaugePairVec for metrics about requests - ReqsGaugePairVec metrics.RatioedGaugePairVec + // GaugeVec for metrics about requests, broken down by phase and priority_level + ReqsGaugeVec metrics.RatioedGaugeVec // RatioedGaugePairVec for metrics about seats occupied by all phases of execution ExecSeatsGaugeVec metrics.RatioedGaugeVec diff --git a/pkg/util/flowcontrol/controller_test.go b/pkg/util/flowcontrol/controller_test.go index aeece8cb4..13737c1a6 100644 --- a/pkg/util/flowcontrol/controller_test.go +++ b/pkg/util/flowcontrol/controller_test.go @@ -261,7 +261,7 @@ func TestConfigConsumer(t *testing.T) { FlowcontrolClient: flowcontrolClient, ServerConcurrencyLimit: 100, // server concurrency limit RequestWaitLimit: time.Minute, // request wait limit - ReqsGaugePairVec: metrics.PriorityLevelConcurrencyPairVec, + ReqsGaugeVec: metrics.PriorityLevelConcurrencyGaugeVec, ExecSeatsGaugeVec: metrics.PriorityLevelExecutionSeatsGaugeVec, QueueSetFactory: cts, }) @@ -393,7 +393,7 @@ func TestAPFControllerWithGracefulShutdown(t *testing.T) { FlowcontrolClient: flowcontrolClient, ServerConcurrencyLimit: 100, RequestWaitLimit: time.Minute, - ReqsGaugePairVec: metrics.PriorityLevelConcurrencyPairVec, + ReqsGaugeVec: metrics.PriorityLevelConcurrencyGaugeVec, ExecSeatsGaugeVec: metrics.PriorityLevelExecutionSeatsGaugeVec, QueueSetFactory: cts, }) diff --git a/pkg/util/flowcontrol/fairqueuing/queueset/queueset_test.go b/pkg/util/flowcontrol/fairqueuing/queueset/queueset_test.go index 5bbbdf360..78e0fdee7 100644 --- a/pkg/util/flowcontrol/fairqueuing/queueset/queueset_test.go +++ b/pkg/util/flowcontrol/fairqueuing/queueset/queueset_test.go @@ -1462,7 +1462,7 @@ func newFIFO(requests ...*request) fifo { } func newGaugePair(clk clock.PassiveClock) metrics.RatioedGaugePair { - return metrics.PriorityLevelConcurrencyPairVec.NewForLabelValuesSafe(1, 1, []string{"test"}) + return metrics.RatioedGaugeVecPhasedElementPair(metrics.PriorityLevelConcurrencyGaugeVec, 1, 1, []string{"test"}) } func newExecSeatsGauge(clk clock.PassiveClock) metrics.RatioedGauge { diff --git a/pkg/util/flowcontrol/gen_test.go b/pkg/util/flowcontrol/gen_test.go index ee4403366..131e25753 100644 --- a/pkg/util/flowcontrol/gen_test.go +++ b/pkg/util/flowcontrol/gen_test.go @@ -57,7 +57,7 @@ func genPL(rng *rand.Rand, name string) *flowcontrol.PriorityLevelConfiguration QueueLengthLimit: 5} } labelVals := []string{"test"} - _, err := queueSetCompleterForPL(noRestraintQSF, nil, plc, time.Minute, metrics.PriorityLevelConcurrencyPairVec.NewForLabelValuesSafe(1, 1, labelVals), metrics.PriorityLevelExecutionSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelVals)) + _, err := queueSetCompleterForPL(noRestraintQSF, nil, plc, time.Minute, metrics.RatioedGaugeVecPhasedElementPair(metrics.PriorityLevelConcurrencyGaugeVec, 1, 1, labelVals), metrics.PriorityLevelExecutionSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelVals)) if err != nil { panic(err) } diff --git a/pkg/util/flowcontrol/metrics/interface.go b/pkg/util/flowcontrol/metrics/interface.go index aba79b5d7..1f33f02b0 100644 --- a/pkg/util/flowcontrol/metrics/interface.go +++ b/pkg/util/flowcontrol/metrics/interface.go @@ -65,14 +65,3 @@ type RatioedGaugePair struct { // RequestsExecuting is given observations of the number of requests currently executing RequestsExecuting RatioedGauge } - -// RatioedGaugePairVec generates pairs -type RatioedGaugePairVec interface { - // NewForLabelValuesSafe makes a new vector member for the given tuple of label values, - // initialized with the given denominators and zeros for numerators. - // Unlike the usual Vec WithLabelValues method, this is intended to be called only - // once per vector member (at the start of its lifecycle). - // The "Safe" part is saying that the returned object will function properly after metric registration - // even if this method is called before registration. - NewForLabelValuesSafe(initialWaitingDenominator, initialExecutingDenominator float64, labelValues []string) RatioedGaugePair -} diff --git a/pkg/util/flowcontrol/metrics/metrics.go b/pkg/util/flowcontrol/metrics/metrics.go index ae23d29cc..b72d549cd 100644 --- a/pkg/util/flowcontrol/metrics/metrics.go +++ b/pkg/util/flowcontrol/metrics/metrics.go @@ -127,8 +127,8 @@ var ( }, []string{priorityLevel}, ) - // PriorityLevelConcurrencyPairVec creates pairs that observe concurrency for priority levels - PriorityLevelConcurrencyPairVec = NewSampleAndWaterMarkHistogramsPairVec(clock.RealClock{}, time.Millisecond, + // PriorityLevelConcurrencyGaugeVec creates gauges of concurrency broken down by phase, priority level + PriorityLevelConcurrencyGaugeVec = NewSampleAndWaterMarkHistogramsVec(clock.RealClock{}, time.Millisecond, &compbasemetrics.HistogramOpts{ Namespace: namespace, Subsystem: subsystem, @@ -145,7 +145,7 @@ var ( Buckets: []float64{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1}, StabilityLevel: compbasemetrics.ALPHA, }, - []string{priorityLevel}, + []string{LabelNamePhase, priorityLevel}, ) // ReadWriteConcurrencyGaugeVec creates gauges of number of requests broken down by phase and mutating vs readonly ReadWriteConcurrencyGaugeVec = NewSampleAndWaterMarkHistogramsVec(clock.RealClock{}, time.Millisecond, @@ -356,7 +356,7 @@ var ( apiserverDispatchWithNoAccommodation, }. Append(PriorityLevelExecutionSeatsGaugeVec.metrics()...). - Append(PriorityLevelConcurrencyPairVec.metrics()...). + Append(PriorityLevelConcurrencyGaugeVec.metrics()...). Append(ReadWriteConcurrencyGaugeVec.metrics()...) ) diff --git a/pkg/util/flowcontrol/metrics/sample_and_watermark.go b/pkg/util/flowcontrol/metrics/sample_and_watermark.go index daa35b28f..b1f83e628 100644 --- a/pkg/util/flowcontrol/metrics/sample_and_watermark.go +++ b/pkg/util/flowcontrol/metrics/sample_and_watermark.go @@ -34,33 +34,6 @@ const ( LabelValueExecuting = "executing" ) -// SampleAndWaterMarkPairVec makes pairs of RatioedGauges that -// track samples and watermarks. -type SampleAndWaterMarkPairVec struct { - urVec SampleAndWaterMarkObserverVec -} - -var _ RatioedGaugePairVec = SampleAndWaterMarkPairVec{} - -// NewSampleAndWaterMarkHistogramsPairVec makes a new pair generator -func NewSampleAndWaterMarkHistogramsPairVec(clock clock.PassiveClock, samplePeriod time.Duration, sampleOpts, waterMarkOpts *compbasemetrics.HistogramOpts, labelNames []string) SampleAndWaterMarkPairVec { - return SampleAndWaterMarkPairVec{ - urVec: NewSampleAndWaterMarkHistogramsVec(clock, samplePeriod, sampleOpts, waterMarkOpts, append([]string{LabelNamePhase}, labelNames...)), - } -} - -// NewForLabelValuesSafe makes a new pair -func (spg SampleAndWaterMarkPairVec) NewForLabelValuesSafe(initialWaitingDenominator, initialExecutingDenominator float64, labelValues []string) RatioedGaugePair { - return RatioedGaugePair{ - RequestsWaiting: spg.urVec.NewForLabelValuesSafe(0, initialWaitingDenominator, append([]string{LabelValueWaiting}, labelValues...)), - RequestsExecuting: spg.urVec.NewForLabelValuesSafe(0, initialExecutingDenominator, append([]string{LabelValueExecuting}, labelValues...)), - } -} - -func (spg SampleAndWaterMarkPairVec) metrics() Registerables { - return spg.urVec.metrics() -} - // SampleAndWaterMarkObserverVec creates RatioedGauges that // populate histograms of samples and low- and high-water-marks. The // generator has a samplePeriod, and the histograms get an observation diff --git a/pkg/util/flowcontrol/metrics/vec_element_pair.go b/pkg/util/flowcontrol/metrics/vec_element_pair.go new file mode 100644 index 000000000..6dcef12c2 --- /dev/null +++ b/pkg/util/flowcontrol/metrics/vec_element_pair.go @@ -0,0 +1,25 @@ +/* +Copyright 2019 The Kubernetes 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 metrics + +// RatioedGaugeVecPhasedElementPair extracts a pair of elements that differ in handling phase +func RatioedGaugeVecPhasedElementPair(vec RatioedGaugeVec, initialWaitingDenominator, initialExecutingDenominator float64, labelValues []string) RatioedGaugePair { + return RatioedGaugePair{ + RequestsWaiting: vec.NewForLabelValuesSafe(0, initialWaitingDenominator, append([]string{LabelValueWaiting}, labelValues...)), + RequestsExecuting: vec.NewForLabelValuesSafe(0, initialExecutingDenominator, append([]string{LabelValueExecuting}, labelValues...)), + } +}