@@ -229,26 +229,18 @@ func (cmm *csiMetricsManager) RecordMetrics(
229229 operationName string ,
230230 operationErr error ,
231231 operationDuration time.Duration ) {
232- cmm .recordMetricsWithLabels (operationName , operationErr , operationDuration )
232+ cmm .recordMetricsWithLabels (operationName , operationErr , operationDuration , nil )
233233}
234234
235235// recordMetricsWithLabels is the internal implementation of RecordMetrics.
236236func (cmm * csiMetricsManager ) recordMetricsWithLabels (
237237 operationName string ,
238238 operationErr error ,
239239 operationDuration time.Duration ,
240- labelValues ... string ) {
240+ labelValues map [ string ] string ) {
241241 values := []string {cmm .driverName , operationName , getErrorCode (operationErr )}
242- toAdd := len (labelValues )
243- if toAdd > len (cmm .additionalLabelNames ) {
244- // To many labels?! Truncate. Shouldn't happen because of
245- // error checking in WithLabelValues.
246- toAdd = len (cmm .additionalLabelNames )
247- }
248- values = append (values , labelValues [0 :toAdd ]... )
249- for i := toAdd ; i < len (cmm .additionalLabelNames ); i ++ {
250- // Backfill missing values with empty string.
251- values = append (values , "" )
242+ for _ , name := range cmm .additionalLabelNames {
243+ values = append (values , labelValues [name ])
252244 }
253245 for _ , label := range cmm .additionalLabels {
254246 values = append (values , label .value )
@@ -260,34 +252,42 @@ type csiMetricsManagerWithValues struct {
260252 * csiMetricsManager
261253
262254 // additionalValues holds the values passed via WithLabelValues.
263- additionalValues [ ]string
255+ additionalValues map [ string ]string
264256}
265257
266258// WithLabelValues in the base metrics manager creates a fresh wrapper with no labels and let's
267259// that deal with adding the label values.
268260func (cmm * csiMetricsManager ) WithLabelValues (labels map [string ]string ) (CSIMetricsManager , error ) {
269- cmmv := & csiMetricsManagerWithValues {csiMetricsManager : cmm }
261+ cmmv := & csiMetricsManagerWithValues {
262+ csiMetricsManager : cmm ,
263+ additionalValues : map [string ]string {},
264+ }
270265 return cmmv .WithLabelValues (labels )
271266}
272267
273268// WithLabelValues in the wrapper creates a wrapper which has all existing labels and
274- // adds the new ones, with error checking.
269+ // adds the new ones, with error checking. Can be called multiple times. Each call then
270+ // can add some new value(s). It is an error to overwrite an already set value.
271+ // If RecordMetrics is called before setting all additional values, the missing ones will
272+ // be empty.
275273func (cmmv * csiMetricsManagerWithValues ) WithLabelValues (labels map [string ]string ) (CSIMetricsManager , error ) {
276- extended := & csiMetricsManagerWithValues {cmmv .csiMetricsManager , append ([]string {}, cmmv .additionalValues ... )}
277-
278- for name := range labels {
279- if ! cmmv .haveAdditionalLabel (name ) {
274+ extended := & csiMetricsManagerWithValues {
275+ csiMetricsManager : cmmv .csiMetricsManager ,
276+ additionalValues : map [string ]string {},
277+ }
278+ // We need to copy the old values to avoid modifying the map in cmmv.
279+ for name , value := range cmmv .additionalValues {
280+ extended .additionalValues [name ] = value
281+ }
282+ // Now add all new values.
283+ for name , value := range labels {
284+ if ! extended .haveAdditionalLabel (name ) {
280285 return nil , fmt .Errorf ("label %q was not defined via WithLabelNames" , name )
281286 }
282- }
283- // Add in same order as in the label definition.
284- for _ , name := range cmmv .additionalLabelNames {
285- if value , ok := labels [name ]; ok {
286- if len (cmmv .additionalValues ) >= len (extended .additionalLabelNames ) {
287- return nil , fmt .Errorf ("label %q = %q cannot be added, all labels already have values %v" , name , value , cmmv .additionalValues )
288- }
289- extended .additionalValues = append (extended .additionalValues , value )
287+ if v , ok := extended .additionalValues [name ]; ok {
288+ return nil , fmt .Errorf ("label %q already has value %q" , name , v )
290289 }
290+ extended .additionalValues [name ] = value
291291 }
292292 return extended , nil
293293}
@@ -306,7 +306,7 @@ func (cmmv *csiMetricsManagerWithValues) RecordMetrics(
306306 operationName string ,
307307 operationErr error ,
308308 operationDuration time.Duration ) {
309- cmmv .recordMetricsWithLabels (operationName , operationErr , operationDuration , cmmv .additionalValues ... )
309+ cmmv .recordMetricsWithLabels (operationName , operationErr , operationDuration , cmmv .additionalValues )
310310}
311311
312312// SetDriverName is called to update the CSI driver name. This should be done
0 commit comments