@@ -174,21 +174,42 @@ func (assoc Associator) AssociateMetricToResource(cwMetric *model.Metric) (*mode
174174
175175 // A regex mapping has been found. The metric has all (and possibly more)
176176 // 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.
178185 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+ }
181204
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
187208 }
188209
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" )
192213 }
193214 }
194215
@@ -204,38 +225,48 @@ func (assoc Associator) AssociateMetricToResource(cwMetric *model.Metric) (*mode
204225 return nil , mappingFound
205226}
206227
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 .
208229// For some namespaces, values might need to be modified in order
209230// 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 ) {
211232 labels := make (map [string ]string , len (cwMetric .Dimensions ))
233+ dimFixApplied := false
212234 for _ , rDimension := range regexpMapping .dimensions {
213235 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 )
231238 }
232239
233240 if rDimension == mDimension .Name {
234- labels [name ] = value
241+ labels [mDimension . Name ] = mDimension . Value
235242 }
236243 }
237244 }
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
239270}
240271
241272// containsAll returns true if a contains all elements of b
0 commit comments