Skip to content

[MetricBeat] [AWS] if the number of resources is a multiple of 50, there is no tags field in the event #26385

@kwinstonix

Description

@kwinstonix

the problem

I found a strange problem of AWS cloudwatch module, there are some EC2 instances cross some regions, but sometimes metricbeat event of some region has no tags. I can query tags with aws CLI aws resourcegroupstaggingapi, then I think there is some bug in the logic of querying tags.

  • Version: 7.13

  • Operating System: linux

  • Steps to Reproduce:

    • Some AWS resource's amount is a multiple of 50(e.g. 100 EC2 instances)
    • Use aws CloudWatch Module

metricbeat config:

  - module: aws
    access_key_id: 'your access key'
    secret_access_key: 'your secret key'
    period: 300s
    regions:
      - ap-northeast-1
    metricsets:
      - cloudwatch
    metrics:
      - namespace: AWS/EC2
        name: CPUUtilization
        statistic: ["Average"]
        resource_type: "ec2:instance"

the reason

  • aws resourcegroupstaggingapi has strange behavior, with the default pagination size of 50 and 100 EC2 instances, we need send three times request and there is zero result in the last request
  • line 191 is not safe and correct, we should break the for loop if output.ResourceTagMappingList is an empty result, then the function can return resourceTagMap to the caller.

func GetResourcesTags(svc resourcegroupstaggingapiiface.ClientAPI, resourceTypeFilters []string) (map[string][]resourcegroupstaggingapi.Tag, error) {
if resourceTypeFilters == nil {
return map[string][]resourcegroupstaggingapi.Tag{}, nil
}
resourceTagMap := make(map[string][]resourcegroupstaggingapi.Tag)
getResourcesInput := &resourcegroupstaggingapi.GetResourcesInput{
PaginationToken: nil,
ResourceTypeFilters: resourceTypeFilters,
}
init := true
for init || *getResourcesInput.PaginationToken != "" {
init = false
getResourcesRequest := svc.GetResourcesRequest(getResourcesInput)
output, err := getResourcesRequest.Send(context.TODO())
if err != nil {
err = errors.Wrap(err, "error GetResources")
return nil, err
}
getResourcesInput.PaginationToken = output.PaginationToken
if resourceTypeFilters == nil || len(output.ResourceTagMappingList) == 0 {
return nil, nil
}
for _, resourceTag := range output.ResourceTagMappingList {

I modify the if statemen, then metricebeat event has tags field.

if len(output.ResourceTagMappingList) == 0 {  	
    break
} 

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions