@@ -174,21 +174,42 @@ func (assoc Associator) AssociateMetricToResource(cwMetric *model.Metric) (*mode
174
174
175
175
// A regex mapping has been found. The metric has all (and possibly more)
176
176
// the dimensions computed for the mapping. Now compute a signature
177
- // of the labels (names and values) of the dimensions of this mapping.
177
+ // of the labels (names and values) of the dimensions of this mapping, and try to
178
+ // find a resource match.
179
+ // This loop can run up to two times:
180
+ // On the first iteration, special-case dimension value
181
+ // fixes to match the value up with the resource ARN are applied to particular namespaces.
182
+ // The second iteration will only run if a fix was applied for one of the special-case
183
+ // namespaces and no match was found. It will try to find a match without applying the fixes.
184
+ // This covers cases where the dimension value does line up with the resource ARN.
178
185
mappingFound = true
179
- labels := buildLabelsMap (cwMetric , regexpMapping )
180
- signature := prom_model .LabelsToSignature (labels )
186
+ dimFixApplied := false
187
+ shouldTryFixDimension := true
188
+ for {
189
+ if ! dimFixApplied && ! shouldTryFixDimension {
190
+ // If no dimension fixes were applied, no need to try running again without the fixer
191
+ break
192
+ }
193
+
194
+ var labels map [string ]string
195
+ labels , dimFixApplied = buildLabelsMap (cwMetric , regexpMapping , shouldTryFixDimension )
196
+ signature := prom_model .LabelsToSignature (labels )
197
+
198
+ // Check if there's an entry for the labels (names and values) of the metric,
199
+ // and return the resource in case.
200
+ if resource , ok := regexpMapping .dimensionsMapping [signature ]; ok {
201
+ logger .Debug ("resource matched" , "signature" , signature )
202
+ return resource , false
203
+ }
181
204
182
- // Check if there's an entry for the labels (names and values) of the metric,
183
- // and return the resource in case.
184
- if resource , ok := regexpMapping .dimensionsMapping [signature ]; ok {
185
- logger .Debug ("resource matched" , "signature" , signature )
186
- return resource , false
205
+ // No resource was matched for the current signature.
206
+ logger .Debug ("resource signature attempt not matched" , "signature" , signature )
207
+ shouldTryFixDimension = false
187
208
}
188
209
189
- // Otherwise , continue iterating across the rest of regex mappings
190
- // to attempt to find another one with fewer dimensions.
191
- logger .Debug ("resource not matched" , "signature" , signature )
210
+ // No resource was matched for any signature , continue iterating across the
211
+ // rest of regex mappings to attempt to find another one with fewer dimensions.
212
+ logger .Debug ("resource not matched" )
192
213
}
193
214
}
194
215
@@ -204,38 +225,48 @@ func (assoc Associator) AssociateMetricToResource(cwMetric *model.Metric) (*mode
204
225
return nil , mappingFound
205
226
}
206
227
207
- // buildLabelsMap returns a map of labels names and values.
228
+ // buildLabelsMap returns a map of labels names and values, as well as whether the dimension fixer was applied .
208
229
// For some namespaces, values might need to be modified in order
209
230
// to match the dimension value extracted from ARN.
210
- func buildLabelsMap (cwMetric * model.Metric , regexpMapping * dimensionsRegexpMapping ) map [string ]string {
231
+ func buildLabelsMap (cwMetric * model.Metric , regexpMapping * dimensionsRegexpMapping , shouldTryFixDimension bool ) ( map [string ]string , bool ) {
211
232
labels := make (map [string ]string , len (cwMetric .Dimensions ))
233
+ dimFixApplied := false
212
234
for _ , rDimension := range regexpMapping .dimensions {
213
235
for _ , mDimension := range cwMetric .Dimensions {
214
- name := mDimension .Name
215
- value := mDimension .Value
216
-
217
- // AmazonMQ is special - for active/standby ActiveMQ brokers,
218
- // the value of the "Broker" dimension contains a number suffix
219
- // that is not part of the resource ARN
220
- if cwMetric .Namespace == "AWS/AmazonMQ" && name == "Broker" {
221
- if amazonMQBrokerSuffix .MatchString (value ) {
222
- value = amazonMQBrokerSuffix .ReplaceAllString (value , "" )
223
- }
224
- }
225
-
226
- // AWS Sagemaker endpoint name may have upper case characters
227
- // Resource ARN is only in lower case, hence transforming
228
- // endpoint name value to be able to match the resource ARN
229
- if cwMetric .Namespace == "AWS/SageMaker" && name == "EndpointName" {
230
- value = strings .ToLower (value )
236
+ if shouldTryFixDimension {
237
+ mDimension , dimFixApplied = fixDimension (cwMetric .Namespace , mDimension )
231
238
}
232
239
233
240
if rDimension == mDimension .Name {
234
- labels [name ] = value
241
+ labels [mDimension . Name ] = mDimension . Value
235
242
}
236
243
}
237
244
}
238
- return labels
245
+ return labels , dimFixApplied
246
+ }
247
+
248
+ // fixDimension modifies the dimension value to accommodate special cases where
249
+ // the dimension value doesn't match the resource ARN.
250
+ func fixDimension (namespace string , dim model.Dimension ) (model.Dimension , bool ) {
251
+ // AmazonMQ is special - for active/standby ActiveMQ brokers,
252
+ // the value of the "Broker" dimension contains a number suffix
253
+ // that is not part of the resource ARN
254
+ if namespace == "AWS/AmazonMQ" && dim .Name == "Broker" {
255
+ if amazonMQBrokerSuffix .MatchString (dim .Value ) {
256
+ dim .Value = amazonMQBrokerSuffix .ReplaceAllString (dim .Value , "" )
257
+ return dim , true
258
+ }
259
+ }
260
+
261
+ // AWS Sagemaker endpoint name may have upper case characters
262
+ // Resource ARN is only in lower case, hence transforming
263
+ // endpoint name value to be able to match the resource ARN
264
+ if namespace == "AWS/SageMaker" && dim .Name == "EndpointName" {
265
+ dim .Value = strings .ToLower (dim .Value )
266
+ return dim , true
267
+ }
268
+
269
+ return dim , false
239
270
}
240
271
241
272
// containsAll returns true if a contains all elements of b
0 commit comments