Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Metricbeat] Add ability to collect tags for aws services #12480

Merged
merged 14 commits into from
Jun 23, 2019
Merged

[Metricbeat] Add ability to collect tags for aws services #12480

merged 14 commits into from
Jun 23, 2019

Conversation

kaiyan-sheng
Copy link
Contributor

@kaiyan-sheng kaiyan-sheng commented Jun 7, 2019

This PR is to add the ability of collecting tags for AWS services using AWS Resource Groups Tagging API. With using get-resources, we don't have to add different code into each metricsets in order to collect from different services (Like the previous implementation: #12372).

Instead, we just need to specify resource-type-filters to specify on the resources that you want this api call to return in order to get the resources that you want with their tags. For example, specifying a resource type of ec2 returns all tagged Amazon EC2 resources, which includes tagged EC2 instances, and security groups, subnets and etc. Specifying a resource type of ec2:instance returns only EC2 instances.

Introduction on tags:
A tag is a label(with a key and a value) that users assign to an AWS resource. If there are two EC2 instances, they can be both assigned a tag key of "Stack" and the value of "Stack" might be "Testing" for one and "Production" for the other. Tagging can help organizing resources and simplifying resource management.

With this change, tags will be a part of the metrics reported by aws module:

  "aws": {
        "cloudwatch": {
            "dimensions": {
                "DBInstanceIdentifier": "test1"
            },
            "metrics": {
                "ActiveTransactions": 0,
                "AuroraBinlogReplicaLag": 0,
                "AuroraReplicaLagMaximum": 18.62599983215332,
                "AuroraReplicaLagMinimum": 18.62599983215332,
                "BinLogDiskUsage": 0,
                "BlockedTransactions": 0,
                "BufferCacheHitRatio": 100,
                "CPUUtilization": 3.2,
                "CommitLatency": 7.324593333333333,
                "CommitThroughput": 0.49995937707131555,
            },
            "namespace": "AWS/RDS"
        },
        "tags": {
            "workload-type": "other",
            "owner": "ks"
            "dept": "engr"
        }
    },

Right now, this PR is only adding tags in cloudwatch metricset. For existing s3 and sqs metricsets, we can call the same function. But for ec2, since the response from DescribeInstances api call already includes tags information, there is no need to make another get-resources api call to obtain the same information.

closes #12263

How to test it?

If you have services which aws supports tags, then add tags onto some of them. Or create services in AWS first, then add tags to them. Start metricbeat with aws module cloudwatch metricset. Please remember to specify tags.resource_type_filter in configuration.

@kaiyan-sheng kaiyan-sheng requested review from a team as code owners June 7, 2019 20:31
@kaiyan-sheng kaiyan-sheng self-assigned this Jun 7, 2019
@kaiyan-sheng kaiyan-sheng added Team:Integrations Label for the Integrations team [zube]: In Progress in progress Pull request is currently in progress. labels Jun 7, 2019
@@ -431,6 +439,22 @@
"version": "v2.0.0-preview.5",
"versionExact": "v2.0.0-preview.5"
},
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should find a way to keep track of our binary size to be aware of changes. Just one line in such libraries could have a big impact.

@exekias @kuisathaverat Would be great to have this as a metric in the CI job so we see in Kibana when the binary size increases (ci stats)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I would expect MB binary to keep growing in the short term, is that possible with jenkins already? I know we could log the binary size, but wondering if we can get it stored as a KPI we can graph.

@kaiyan-sheng
Copy link
Contributor Author

One problem in this approach/PR that I'm not sure about is: https://github.com/elastic/beats/pull/12480/files#diff-149c3579568dabccec12ddeca87f73c7R371 how to pass in the proper --resource-type-filters into get-resources api?

Resource type format: service[:resourceType]
For example, specifying a resource type of ec2 returns all tagged Amazon EC2 resources (which includes tagged EC2 instances). Specifying a resource type of ec2:instance returns only EC2 instances.
Please see https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html for more details.

What I currently have in the PR is a function called getResourceTypeUsingNamespace: most of the time, the resourceType/service name can be obtained from namespace, which is a config input for aws cloudwatch metricset. For example, AWS/EC2 is the namespace and ec2 is the resourceType/service name. But there are exceptions for sure, such as AWS/ELB is the namespace but elasticloadbalancing is the resourceType/service name.

Another solution for this is to add a separate parameter in configuration called resource-type: this will make users' life probably a bit more confusing because we are asking for both namespace and resource-type.

Or we can add the parameter for resource-type in the config but not required. If it's empty, then we will use getResourceTypeUsingNamespace method.

Copy link
Member

@jsoriano jsoriano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But there are exceptions for sure, such as AWS/ELB is the namespace but elasticloadbalancing is the resourceType/service name.

Could we have a prebuilt mapping for the ones we know, and query some API to get the rest of exceptions?

Or we can add the parameter for resource-type in the config but not required. If it's empty, then we will use getResourceTypeUsingNamespace method.

We could go for this, specially if we have some automatic mechanism so getResourceTypeUsingNamespace can always work, even if it is doing some additional query for the namespaces it doesn't know.

Also when we have light modules we can have modules for the most common resource types.

@exekias
Copy link
Contributor

exekias commented Jun 12, 2019

Or we can add the parameter for resource-type in the config but not required. If it's empty, then we will use getResourceTypeUsingNamespace method.

We could go for this, specially if we have some automatic mechanism so getResourceTypeUsingNamespace can always work, even if it is doing some additional query for the namespaces it doesn't know.

++ On having this as a config parameter, I wouldn't put much effort on a magic mechanism if it's not trivial. If I understand this correctly, probably we are using this in combination with lightweight modules, that means we can configure the resource type in the same way we are already defining the namespace.

Another note: this will need to update docs on the new needed permissions

@exekias
Copy link
Contributor

exekias commented Jun 12, 2019

btw, it is great you found a generic way of retrieving tags!! 👏 👏

CHANGELOG.next.asciidoc Outdated Show resolved Hide resolved
@kaiyan-sheng kaiyan-sheng added review and removed in progress Pull request is currently in progress. [zube]: In Progress labels Jun 14, 2019
Copy link
Member

@jsoriano jsoriano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I would only consider making resource_type_filter required by now to avoid unexpected behaviours if we cannot guess the correct filter.

Namespace string `config:"namespace" validate:"nonzero,required"`
MetricName string `config:"metricname"`
Dimensions []Dimension `config:"dimensions"`
ResourceTypeFilter string `config:"tags.resource_type_filter"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this should be a struct, but if it works, I am fine with this.

metricbeat/docs/modules/aws.asciidoc Show resolved Hide resolved
@kaiyan-sheng
Copy link
Contributor Author

jenkins, test this please

@kaiyan-sheng kaiyan-sheng merged commit 3a4d34f into elastic:master Jun 23, 2019
@kaiyan-sheng kaiyan-sheng deleted the resource_groups_tagging_api branch June 23, 2019 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review Team:Integrations Label for the Integrations team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Metricbeat] Add ability to collect tags for aws services
6 participants