From 98b5bdda43069415e5901ad0ce4cb1f2b7b03b0d Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Thu, 24 Jun 2021 05:04:43 +0800 Subject: [PATCH] Add linked account information into billing metricset (#26285) (#26451) (cherry picked from commit d512dc04a40de07a260fc1a653e20d0fc62abed7) --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/fields.asciidoc | 21 ++ x-pack/metricbeat/module/aws/_meta/config.yml | 5 +- x-pack/metricbeat/module/aws/_meta/fields.yml | 11 + .../Metricbeat-aws-billing-overview.json | 290 +++++++++--------- .../module/aws/billing/_meta/data.json | 32 +- .../aws/billing/_meta/data_cloudwatch.json | 4 +- .../_meta/data_group_by_instance_type.json | 14 +- .../_meta/data_group_by_linked_account.json | 55 ++++ .../module/aws/billing/_meta/docs.asciidoc | 1 + .../metricbeat/module/aws/billing/billing.go | 37 +++ .../aws/billing/billing_integration_test.go | 20 +- x-pack/metricbeat/module/aws/fields.go | 2 +- .../module/aws/mtest/integration.go | 31 -- x-pack/metricbeat/modules.d/aws.yml.disabled | 5 +- 15 files changed, 315 insertions(+), 214 deletions(-) create mode 100644 x-pack/metricbeat/module/aws/billing/_meta/data_group_by_linked_account.json diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 55aaf612633..f197e9c1d56 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -663,6 +663,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Reduce number of requests done by kubernetes metricsets to kubelet. {pull}25782[25782] - Migrate rds metricsets to use cloudwatch input. {pull}26077[26077] - Migrate sqs metricsets to use cloudwatch input. {pull}26117[26117] +- Collect linked account information in AWS billing. {pull}26285[26285] - Add total CPU to vSphere virtual machine metrics. {pull}26167[26167] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 6dd0ed69daa..134c619b550 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -1563,6 +1563,27 @@ type: object -- + +*`aws.linked_account.id`*:: ++ +-- +ID used to identify linked account. + + +type: keyword + +-- + +*`aws.linked_account.name`*:: ++ +-- +Name or alias used to identify linked account. + + +type: keyword + +-- + [float] === billing diff --git a/x-pack/metricbeat/module/aws/_meta/config.yml b/x-pack/metricbeat/module/aws/_meta/config.yml index 6f604138505..6fc2787fa8c 100644 --- a/x-pack/metricbeat/module/aws/_meta/config.yml +++ b/x-pack/metricbeat/module/aws/_meta/config.yml @@ -38,8 +38,9 @@ - "AZ" - "INSTANCE_TYPE" - "SERVICE" -# group_by_tag_keys: -# - "aws:createdBy" + - "LINKED_ACCOUNT" + group_by_tag_keys: + - "aws:createdBy" - module: aws period: 24h metricsets: diff --git a/x-pack/metricbeat/module/aws/_meta/fields.yml b/x-pack/metricbeat/module/aws/_meta/fields.yml index 4272b5aeab9..7e0bca24a17 100644 --- a/x-pack/metricbeat/module/aws/_meta/fields.yml +++ b/x-pack/metricbeat/module/aws/_meta/fields.yml @@ -30,3 +30,14 @@ object_type_mapping_type: "*" description: > Metrics that returned from Cloudwatch API query. + - name: linked_account + type: group + fields: + - name: id + type: keyword + description: > + ID used to identify linked account. + - name: name + type: keyword + description: > + Name or alias used to identify linked account. diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json index 6a601bc7471..2aa069c63f9 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json @@ -20,7 +20,7 @@ "panelsJSON": [ { "embeddableConfig": { - "title": "AWS Account Filter" + "enhancements": {} }, "gridData": { "h": 5, @@ -30,13 +30,14 @@ "y": 0 }, "panelIndex": "89dccfe8-a25e-44ea-afdb-ff01ab1f05d6", - "panelRefName": "panel_0", + "panelRefName": "panel_89dccfe8-a25e-44ea-afdb-ff01ab1f05d6", "title": "AWS Account Filter", - "version": "7.9.0" + "type": "visualization", + "version": "7.13.2" }, { "embeddableConfig": { - "title": "Current Total Unblended Cost" + "enhancements": {} }, "gridData": { "h": 18, @@ -46,13 +47,14 @@ "y": 0 }, "panelIndex": "f1db16b5-ce0a-4f21-885f-434c16346c26", - "panelRefName": "panel_1", + "panelRefName": "panel_f1db16b5-ce0a-4f21-885f-434c16346c26", "title": "Current Total Unblended Cost", - "version": "7.9.0" + "type": "visualization", + "version": "7.13.2" }, { "embeddableConfig": { - "title": "Availability Zone Utilization" + "enhancements": {} }, "gridData": { "h": 18, @@ -62,13 +64,14 @@ "y": 0 }, "panelIndex": "57912f48-42ec-4d3e-ba54-bf94757d1eec", - "panelRefName": "panel_2", + "panelRefName": "panel_57912f48-42ec-4d3e-ba54-bf94757d1eec", "title": "Availability Zone Utilization", - "version": "7.9.0" + "type": "visualization", + "version": "7.13.2" }, { "embeddableConfig": { - "title": "Total Estimated Charges For This Month" + "enhancements": {} }, "gridData": { "h": 13, @@ -78,13 +81,14 @@ "y": 5 }, "panelIndex": "221aab02-2747-4d84-9dde-028ccd51bdce", - "panelRefName": "panel_3", + "panelRefName": "panel_221aab02-2747-4d84-9dde-028ccd51bdce", "title": "Total Estimated Charges For This Month", - "version": "7.9.0" + "type": "visualization", + "version": "7.13.2" }, { "embeddableConfig": { - "title": "Cost Per Service Per User" + "enhancements": {} }, "gridData": { "h": 20, @@ -94,13 +98,14 @@ "y": 18 }, "panelIndex": "376f236b-1365-4e80-8076-eec88c1a67bd", - "panelRefName": "panel_4", + "panelRefName": "panel_376f236b-1365-4e80-8076-eec88c1a67bd", "title": "Cost Per Service Per User", - "version": "7.9.0" + "type": "lens", + "version": "7.13.2" }, { "embeddableConfig": { - "title": "High Spenders" + "enhancements": {} }, "gridData": { "h": 20, @@ -110,13 +115,14 @@ "y": 18 }, "panelIndex": "dd5220c2-dc8a-4d3e-964b-6137d1e447ad", - "panelRefName": "panel_5", + "panelRefName": "panel_dd5220c2-dc8a-4d3e-964b-6137d1e447ad", "title": "High Spenders", - "version": "7.9.0" + "type": "lens", + "version": "7.13.2" }, { "embeddableConfig": { - "title": "Top 10 Estimated Charges per Service Name" + "enhancements": {} }, "gridData": { "h": 18, @@ -126,13 +132,14 @@ "y": 38 }, "panelIndex": "1de716e2-bad9-4fe3-ba49-0e2ea2a59bb4", - "panelRefName": "panel_6", + "panelRefName": "panel_1de716e2-bad9-4fe3-ba49-0e2ea2a59bb4", "title": "Top 10 Estimated Charges per Service Name", - "version": "7.9.0" + "type": "lens", + "version": "7.13.2" }, { "embeddableConfig": { - "title": "Daily Unblended Cost" + "enhancements": {} }, "gridData": { "h": 18, @@ -142,18 +149,20 @@ "y": 38 }, "panelIndex": "60181fec-fea9-4f99-b5f9-a53ffbc2ac65", - "panelRefName": "panel_7", + "panelRefName": "panel_60181fec-fea9-4f99-b5f9-a53ffbc2ac65", "title": "Daily Unblended Cost", - "version": "7.9.0" + "type": "visualization", + "version": "7.13.2" } ], "timeRestore": false, "title": "[Metricbeat AWS] Billing Overview", "version": 1 }, + "coreMigrationVersion": "7.13.2", "id": "e6776b10-1534-11ea-841c-01bf20a6c8ba", "migrationVersion": { - "dashboard": "7.3.0" + "dashboard": "7.13.1" }, "namespaces": [ "default" @@ -161,48 +170,48 @@ "references": [ { "id": "deab0260-2981-11e9-86eb-a3a07a77f530", - "name": "panel_0", + "name": "89dccfe8-a25e-44ea-afdb-ff01ab1f05d6:panel_89dccfe8-a25e-44ea-afdb-ff01ab1f05d6", "type": "visualization" }, { "id": "1731c440-e649-11ea-a838-3f4a45f85600", - "name": "panel_1", + "name": "f1db16b5-ce0a-4f21-885f-434c16346c26:panel_f1db16b5-ce0a-4f21-885f-434c16346c26", "type": "visualization" }, { "id": "a5670a20-e65a-11ea-a838-3f4a45f85600", - "name": "panel_2", + "name": "57912f48-42ec-4d3e-ba54-bf94757d1eec:panel_57912f48-42ec-4d3e-ba54-bf94757d1eec", "type": "visualization" }, { "id": "83f08eb0-1532-11ea-841c-01bf20a6c8ba", - "name": "panel_3", + "name": "221aab02-2747-4d84-9dde-028ccd51bdce:panel_221aab02-2747-4d84-9dde-028ccd51bdce", "type": "visualization" }, { "id": "b3da5ac0-e6f1-11ea-a5b5-d5a0accaec95", - "name": "panel_4", + "name": "376f236b-1365-4e80-8076-eec88c1a67bd:panel_376f236b-1365-4e80-8076-eec88c1a67bd", "type": "lens" }, { "id": "d7b399c0-e6f1-11ea-a5b5-d5a0accaec95", - "name": "panel_5", + "name": "dd5220c2-dc8a-4d3e-964b-6137d1e447ad:panel_dd5220c2-dc8a-4d3e-964b-6137d1e447ad", "type": "lens" }, { "id": "cde34840-e6f2-11ea-a5b5-d5a0accaec95", - "name": "panel_6", + "name": "1de716e2-bad9-4fe3-ba49-0e2ea2a59bb4:panel_1de716e2-bad9-4fe3-ba49-0e2ea2a59bb4", "type": "lens" }, { "id": "3e091620-e64b-11ea-a838-3f4a45f85600", - "name": "panel_7", + "name": "60181fec-fea9-4f99-b5f9-a53ffbc2ac65:panel_60181fec-fea9-4f99-b5f9-a53ffbc2ac65", "type": "visualization" } ], "type": "dashboard", - "updated_at": "2020-09-14T04:08:21.260Z", - "version": "WzcyNjksOF0=" + "updated_at": "2021-06-16T19:03:42.260Z", + "version": "WzEwMzEsMV0=" }, { "attributes": { @@ -237,6 +246,21 @@ }, "parent": "", "type": "list" + }, + { + "fieldName": "cloud.linked_account.name", + "id": "1623870032405", + "indexPatternRefName": "control_1_index_pattern", + "label": "linked account name", + "options": { + "dynamicOptions": true, + "multiselect": true, + "order": "desc", + "size": 5, + "type": "terms" + }, + "parent": "1549397251041", + "type": "list" } ], "pinFilters": false, @@ -247,9 +271,10 @@ "type": "input_control_vis" } }, + "coreMigrationVersion": "7.13.2", "id": "deab0260-2981-11e9-86eb-a3a07a77f530", "migrationVersion": { - "visualization": "7.8.0" + "visualization": "7.13.1" }, "namespaces": [ "default" @@ -259,23 +284,22 @@ "id": "metricbeat-*", "name": "control_0_index_pattern", "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "control_1_index_pattern", + "type": "index-pattern" } ], "type": "visualization", - "updated_at": "2020-09-14T04:04:04.990Z", - "version": "WzY2MDYsOF0=" + "updated_at": "2021-06-16T19:03:22.893Z", + "version": "WzEwMjcsMV0=" }, { "attributes": { "description": "", "kibanaSavedObjectMeta": { - "searchSourceJSON": { - "filter": [], - "query": { - "language": "kuery", - "query": "" - } - } + "searchSourceJSON": {} }, "title": "Total Unblended Cost [Metricbeat AWS]", "uiStateJSON": {}, @@ -291,13 +315,12 @@ "id": "cf04e620-e648-11ea-bdad-df8839db1393" } ], - "default_index_pattern": "metricbeat-*", - "default_timefield": "@timestamp", "drop_last_bucket": 0, "filter": { "language": "kuery", "query": "aws.billing.group_definition.key : \"AZ\"" }, + "hide_last_value_indicator": true, "id": "61ca57f0-469d-11e7-af02-69e470af7417", "index_pattern": "metricbeat-*", "interval": "\u003e=2d", @@ -341,23 +364,25 @@ "time_field": "@timestamp", "time_range_mode": "last_value", "tooltip_mode": "show_all", - "type": "metric" + "type": "metric", + "use_kibana_indexes": false }, "title": "Total Unblended Cost [Metricbeat AWS]", "type": "metrics" } }, + "coreMigrationVersion": "7.13.2", "id": "1731c440-e649-11ea-a838-3f4a45f85600", "migrationVersion": { - "visualization": "7.8.0" + "visualization": "7.13.1" }, "namespaces": [ "default" ], "references": [], "type": "visualization", - "updated_at": "2020-09-14T04:03:51.696Z", - "version": "WzY0NjksOF0=" + "updated_at": "2021-06-16T18:25:55.172Z", + "version": "Wzc2LDFd" }, { "attributes": { @@ -419,9 +444,10 @@ "type": "pie" } }, + "coreMigrationVersion": "7.13.2", "id": "a5670a20-e65a-11ea-a838-3f4a45f85600", "migrationVersion": { - "visualization": "7.8.0" + "visualization": "7.13.1" }, "namespaces": [ "default" @@ -434,20 +460,14 @@ } ], "type": "visualization", - "updated_at": "2020-09-14T04:03:51.696Z", - "version": "WzY0NzAsOF0=" + "updated_at": "2021-06-16T18:25:55.172Z", + "version": "Wzc3LDFd" }, { "attributes": { "description": "", "kibanaSavedObjectMeta": { - "searchSourceJSON": { - "filter": [], - "query": { - "language": "kuery", - "query": "" - } - } + "searchSourceJSON": {} }, "title": "Total Estimated Charges [Metricbeat AWS]", "uiStateJSON": {}, @@ -468,8 +488,6 @@ "id": "ebb52700-1531-11ea-961e-c1db9cc6166e" } ], - "default_index_pattern": "metricbeat-*", - "default_timefield": "@timestamp", "drop_last_bucket": 0, "filter": { "language": "kuery", @@ -483,6 +501,7 @@ "gauge_inner_width": 10, "gauge_style": "half", "gauge_width": 10, + "hide_last_value_indicator": true, "id": "61ca57f0-469d-11e7-af02-69e470af7417", "index_pattern": "metricbeat-*", "interval": "\u003e=1d", @@ -527,40 +546,31 @@ "time_field": "@timestamp", "time_range_mode": "last_value", "tooltip_mode": "show_all", - "type": "metric" + "type": "metric", + "use_kibana_indexes": false }, "title": "Total Estimated Charges [Metricbeat AWS]", "type": "metrics" } }, + "coreMigrationVersion": "7.13.2", "id": "83f08eb0-1532-11ea-841c-01bf20a6c8ba", "migrationVersion": { - "visualization": "7.8.0" + "visualization": "7.13.1" }, "namespaces": [ "default" ], "references": [], "type": "visualization", - "updated_at": "2020-09-14T04:03:51.696Z", - "version": "WzY0NzEsOF0=" + "updated_at": "2021-06-16T18:25:55.172Z", + "version": "Wzc4LDFd" }, { "attributes": { - "description": "", - "expression": "kibana\n| kibana_context query=\"{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"kuery\\\"}\" filters=\"[]\"\n| lens_merge_tables layerIds=\"cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3\" \n tables={esaggs index=\"metricbeat-*\" metricsAtAllLevels=true partialRows=true includeFormatHints=true aggConfigs=\"[{\\\"id\\\":\\\"5d850e8e-f3e0-4ad2-9697-b8c00c03f753\\\",\\\"enabled\\\":true,\\\"type\\\":\\\"terms\\\",\\\"schema\\\":\\\"segment\\\",\\\"params\\\":{\\\"field\\\":\\\"aws.billing.group_by.SERVICE\\\",\\\"orderBy\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\",\\\"order\\\":\\\"desc\\\",\\\"size\\\":5,\\\"otherBucket\\\":false,\\\"otherBucketLabel\\\":\\\"Other\\\",\\\"missingBucket\\\":false,\\\"missingBucketLabel\\\":\\\"Missing\\\"}},{\\\"id\\\":\\\"a1f5b3b8-41da-452b-8683-7a9ca6b6267f\\\",\\\"enabled\\\":true,\\\"type\\\":\\\"terms\\\",\\\"schema\\\":\\\"segment\\\",\\\"params\\\":{\\\"field\\\":\\\"aws.billing.group_by.aws:createdBy\\\",\\\"orderBy\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\",\\\"order\\\":\\\"desc\\\",\\\"size\\\":10,\\\"otherBucket\\\":false,\\\"otherBucketLabel\\\":\\\"Other\\\",\\\"missingBucket\\\":false,\\\"missingBucketLabel\\\":\\\"Missing\\\"}},{\\\"id\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\",\\\"enabled\\\":true,\\\"type\\\":\\\"sum\\\",\\\"schema\\\":\\\"metric\\\",\\\"params\\\":{\\\"field\\\":\\\"aws.billing.UnblendedCost.amount\\\",\\\"missing\\\":0}}]\" | lens_rename_columns idMap=\"{\\\"col-0-5d850e8e-f3e0-4ad2-9697-b8c00c03f753\\\":{\\\"label\\\":\\\"Service Name\\\",\\\"dataType\\\":\\\"string\\\",\\\"operationType\\\":\\\"terms\\\",\\\"scale\\\":\\\"ordinal\\\",\\\"sourceField\\\":\\\"aws.billing.group_by.SERVICE\\\",\\\"isBucketed\\\":true,\\\"params\\\":{\\\"size\\\":5,\\\"orderBy\\\":{\\\"type\\\":\\\"column\\\",\\\"columnId\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\"},\\\"orderDirection\\\":\\\"desc\\\"},\\\"customLabel\\\":true,\\\"id\\\":\\\"5d850e8e-f3e0-4ad2-9697-b8c00c03f753\\\"},\\\"col-2-a1f5b3b8-41da-452b-8683-7a9ca6b6267f\\\":{\\\"label\\\":\\\"Top values of aws.billing.group_by.aws:createdBy\\\",\\\"dataType\\\":\\\"string\\\",\\\"operationType\\\":\\\"terms\\\",\\\"scale\\\":\\\"ordinal\\\",\\\"suggestedPriority\\\":0,\\\"sourceField\\\":\\\"aws.billing.group_by.aws:createdBy\\\",\\\"isBucketed\\\":true,\\\"params\\\":{\\\"size\\\":10,\\\"orderBy\\\":{\\\"type\\\":\\\"column\\\",\\\"columnId\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\"},\\\"orderDirection\\\":\\\"desc\\\"},\\\"id\\\":\\\"a1f5b3b8-41da-452b-8683-7a9ca6b6267f\\\"},\\\"col-3-75188758-7734-4fc3-af1d-297c455715f0\\\":{\\\"label\\\":\\\"Total Unblended Cost\\\",\\\"dataType\\\":\\\"number\\\",\\\"operationType\\\":\\\"sum\\\",\\\"sourceField\\\":\\\"aws.billing.UnblendedCost.amount\\\",\\\"isBucketed\\\":false,\\\"scale\\\":\\\"ratio\\\",\\\"customLabel\\\":true,\\\"id\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\"}}\"}\n| lens_xy_chart xTitle=\"Service Name\" yTitle=\"Total Unblended Cost\" legend={lens_xy_legendConfig isVisible=true position=\"right\"} fittingFunction=\"None\" \n layers={lens_xy_layer layerId=\"cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3\" hide=false xAccessor=\"5d850e8e-f3e0-4ad2-9697-b8c00c03f753\" yScaleType=\"linear\" xScaleType=\"ordinal\" isHistogram=false splitAccessor=\"a1f5b3b8-41da-452b-8683-7a9ca6b6267f\" seriesType=\"bar_stacked\" accessors=\"75188758-7734-4fc3-af1d-297c455715f0\" columnToLabel=\"{\\\"75188758-7734-4fc3-af1d-297c455715f0\\\":\\\"Total Unblended Cost\\\",\\\"a1f5b3b8-41da-452b-8683-7a9ca6b6267f\\\":\\\"Top values of aws.billing.group_by.aws:createdBy\\\"}\"}", "state": { - "datasourceMetaData": { - "filterableIndexPatterns": [ - { - "id": "metricbeat-*", - "title": "metricbeat-*" - } - ] - }, "datasourceStates": { "indexpattern": { - "currentIndexPatternId": "metricbeat-*", "layers": { "cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3": { "columnOrder": [ @@ -609,11 +619,9 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "aws.billing.group_by.aws:createdBy", - "suggestedPriority": 0 + "sourceField": "aws.billing.group_by.aws:createdBy" } - }, - "indexPatternId": "metricbeat-*" + } } } } @@ -646,34 +654,35 @@ "title": "Cost Per Service Per User [Metricbeat AWS]", "visualizationType": "lnsXY" }, + "coreMigrationVersion": "7.13.2", "id": "b3da5ac0-e6f1-11ea-a5b5-d5a0accaec95", "migrationVersion": { - "lens": "7.8.0" + "lens": "7.13.1" }, "namespaces": [ "default" ], - "references": [], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3", + "type": "index-pattern" + } + ], "type": "lens", - "updated_at": "2020-09-14T04:03:51.696Z", - "version": "WzY0NzIsOF0=" + "updated_at": "2021-06-16T18:25:55.172Z", + "version": "Wzc5LDFd" }, { "attributes": { - "description": "", - "expression": "kibana\n| kibana_context query=\"{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"kuery\\\"}\" filters=\"[]\"\n| lens_merge_tables layerIds=\"cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3\" \n tables={esaggs index=\"metricbeat-*\" metricsAtAllLevels=true partialRows=true includeFormatHints=true aggConfigs=\"[{\\\"id\\\":\\\"a1f5b3b8-41da-452b-8683-7a9ca6b6267f\\\",\\\"enabled\\\":true,\\\"type\\\":\\\"terms\\\",\\\"schema\\\":\\\"segment\\\",\\\"params\\\":{\\\"field\\\":\\\"aws.billing.group_by.aws:createdBy\\\",\\\"orderBy\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\",\\\"order\\\":\\\"desc\\\",\\\"size\\\":10,\\\"otherBucket\\\":false,\\\"otherBucketLabel\\\":\\\"Other\\\",\\\"missingBucket\\\":false,\\\"missingBucketLabel\\\":\\\"Missing\\\"}},{\\\"id\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\",\\\"enabled\\\":true,\\\"type\\\":\\\"sum\\\",\\\"schema\\\":\\\"metric\\\",\\\"params\\\":{\\\"field\\\":\\\"aws.billing.UnblendedCost.amount\\\",\\\"missing\\\":0}}]\" | lens_rename_columns idMap=\"{\\\"col-0-a1f5b3b8-41da-452b-8683-7a9ca6b6267f\\\":{\\\"label\\\":\\\"Top Users\\\",\\\"dataType\\\":\\\"string\\\",\\\"operationType\\\":\\\"terms\\\",\\\"scale\\\":\\\"ordinal\\\",\\\"suggestedPriority\\\":0,\\\"sourceField\\\":\\\"aws.billing.group_by.aws:createdBy\\\",\\\"isBucketed\\\":true,\\\"params\\\":{\\\"size\\\":10,\\\"orderBy\\\":{\\\"type\\\":\\\"column\\\",\\\"columnId\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\"},\\\"orderDirection\\\":\\\"desc\\\"},\\\"customLabel\\\":true,\\\"id\\\":\\\"a1f5b3b8-41da-452b-8683-7a9ca6b6267f\\\"},\\\"col-1-75188758-7734-4fc3-af1d-297c455715f0\\\":{\\\"label\\\":\\\"Total Unblended Cost\\\",\\\"dataType\\\":\\\"number\\\",\\\"operationType\\\":\\\"sum\\\",\\\"sourceField\\\":\\\"aws.billing.UnblendedCost.amount\\\",\\\"isBucketed\\\":false,\\\"scale\\\":\\\"ratio\\\",\\\"customLabel\\\":true,\\\"id\\\":\\\"75188758-7734-4fc3-af1d-297c455715f0\\\"}}\"}\n| lens_xy_chart xTitle=\"Top Users\" yTitle=\"Total Unblended Cost\" legend={lens_xy_legendConfig isVisible=true position=\"right\"} fittingFunction=\"None\" \n layers={lens_xy_layer layerId=\"cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3\" hide=false xAccessor=\"a1f5b3b8-41da-452b-8683-7a9ca6b6267f\" yScaleType=\"linear\" xScaleType=\"ordinal\" isHistogram=false seriesType=\"bar_horizontal\" accessors=\"75188758-7734-4fc3-af1d-297c455715f0\" columnToLabel=\"{\\\"75188758-7734-4fc3-af1d-297c455715f0\\\":\\\"Total Unblended Cost\\\"}\"}", "state": { - "datasourceMetaData": { - "filterableIndexPatterns": [ - { - "id": "metricbeat-*", - "title": "metricbeat-*" - } - ] - }, "datasourceStates": { "indexpattern": { - "currentIndexPatternId": "metricbeat-*", "layers": { "cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3": { "columnOrder": [ @@ -705,11 +714,9 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "aws.billing.group_by.aws:createdBy", - "suggestedPriority": 0 + "sourceField": "aws.billing.group_by.aws:createdBy" } - }, - "indexPatternId": "metricbeat-*" + } } } } @@ -741,34 +748,35 @@ "title": "High Spenders [Metricbeat AWS]", "visualizationType": "lnsXY" }, + "coreMigrationVersion": "7.13.2", "id": "d7b399c0-e6f1-11ea-a5b5-d5a0accaec95", "migrationVersion": { - "lens": "7.8.0" + "lens": "7.13.1" }, "namespaces": [ "default" ], - "references": [], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3", + "type": "index-pattern" + } + ], "type": "lens", - "updated_at": "2020-09-14T04:03:51.696Z", - "version": "WzY0NzMsOF0=" + "updated_at": "2021-06-16T18:25:55.172Z", + "version": "WzgwLDFd" }, { "attributes": { - "description": "", - "expression": "kibana\n| kibana_context query=\"{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"kuery\\\"}\" filters=\"[]\"\n| lens_merge_tables layerIds=\"dc597043-d867-4f94-ae90-f31ffc0c2674\" \n tables={esaggs index=\"metricbeat-*\" metricsAtAllLevels=true partialRows=true includeFormatHints=true timeFields=\"@timestamp\" aggConfigs=\"[{\\\"id\\\":\\\"ea87bf3d-0a35-424b-b00b-3614c431b135\\\",\\\"enabled\\\":true,\\\"type\\\":\\\"terms\\\",\\\"schema\\\":\\\"segment\\\",\\\"params\\\":{\\\"field\\\":\\\"aws.billing.ServiceName\\\",\\\"orderBy\\\":\\\"d54f4e58-d8dd-4404-8da9-12b667dd7910\\\",\\\"order\\\":\\\"desc\\\",\\\"size\\\":10,\\\"otherBucket\\\":false,\\\"otherBucketLabel\\\":\\\"Other\\\",\\\"missingBucket\\\":false,\\\"missingBucketLabel\\\":\\\"Missing\\\"}},{\\\"id\\\":\\\"faa5dba4-1fab-4f88-b67f-28bafa26a32d\\\",\\\"enabled\\\":true,\\\"type\\\":\\\"date_histogram\\\",\\\"schema\\\":\\\"segment\\\",\\\"params\\\":{\\\"field\\\":\\\"@timestamp\\\",\\\"useNormalizedEsInterval\\\":true,\\\"interval\\\":\\\"1d\\\",\\\"drop_partials\\\":false,\\\"min_doc_count\\\":0,\\\"extended_bounds\\\":{}}},{\\\"id\\\":\\\"d54f4e58-d8dd-4404-8da9-12b667dd7910\\\",\\\"enabled\\\":true,\\\"type\\\":\\\"avg\\\",\\\"schema\\\":\\\"metric\\\",\\\"params\\\":{\\\"field\\\":\\\"aws.billing.EstimatedCharges\\\",\\\"missing\\\":0}}]\" | lens_rename_columns idMap=\"{\\\"col-0-ea87bf3d-0a35-424b-b00b-3614c431b135\\\":{\\\"label\\\":\\\"Service Names\\\",\\\"dataType\\\":\\\"string\\\",\\\"operationType\\\":\\\"terms\\\",\\\"scale\\\":\\\"ordinal\\\",\\\"suggestedPriority\\\":0,\\\"sourceField\\\":\\\"aws.billing.ServiceName\\\",\\\"isBucketed\\\":true,\\\"params\\\":{\\\"size\\\":10,\\\"orderBy\\\":{\\\"type\\\":\\\"column\\\",\\\"columnId\\\":\\\"d54f4e58-d8dd-4404-8da9-12b667dd7910\\\"},\\\"orderDirection\\\":\\\"desc\\\"},\\\"customLabel\\\":true,\\\"id\\\":\\\"ea87bf3d-0a35-424b-b00b-3614c431b135\\\"},\\\"col-2-faa5dba4-1fab-4f88-b67f-28bafa26a32d\\\":{\\\"label\\\":\\\"@timestamp\\\",\\\"dataType\\\":\\\"date\\\",\\\"operationType\\\":\\\"date_histogram\\\",\\\"sourceField\\\":\\\"@timestamp\\\",\\\"isBucketed\\\":true,\\\"scale\\\":\\\"interval\\\",\\\"params\\\":{\\\"interval\\\":\\\"1d\\\"},\\\"id\\\":\\\"faa5dba4-1fab-4f88-b67f-28bafa26a32d\\\"},\\\"col-3-d54f4e58-d8dd-4404-8da9-12b667dd7910\\\":{\\\"label\\\":\\\"Estimated Charges\\\",\\\"dataType\\\":\\\"number\\\",\\\"operationType\\\":\\\"avg\\\",\\\"sourceField\\\":\\\"aws.billing.EstimatedCharges\\\",\\\"isBucketed\\\":false,\\\"scale\\\":\\\"ratio\\\",\\\"customLabel\\\":true,\\\"id\\\":\\\"d54f4e58-d8dd-4404-8da9-12b667dd7910\\\"}}\"}\n| lens_xy_chart xTitle=\"@timestamp\" yTitle=\"Estimated Charges\" legend={lens_xy_legendConfig isVisible=true position=\"right\"} fittingFunction=\"None\" \n layers={lens_xy_layer layerId=\"dc597043-d867-4f94-ae90-f31ffc0c2674\" hide=false xAccessor=\"faa5dba4-1fab-4f88-b67f-28bafa26a32d\" yScaleType=\"linear\" xScaleType=\"time\" isHistogram=true splitAccessor=\"ea87bf3d-0a35-424b-b00b-3614c431b135\" seriesType=\"line\" accessors=\"d54f4e58-d8dd-4404-8da9-12b667dd7910\" columnToLabel=\"{\\\"d54f4e58-d8dd-4404-8da9-12b667dd7910\\\":\\\"Estimated Charges\\\",\\\"ea87bf3d-0a35-424b-b00b-3614c431b135\\\":\\\"Service Names\\\"}\"}", "state": { - "datasourceMetaData": { - "filterableIndexPatterns": [ - { - "id": "metricbeat-*", - "title": "metricbeat-*" - } - ] - }, "datasourceStates": { "indexpattern": { - "currentIndexPatternId": "metricbeat-*", "layers": { "dc597043-d867-4f94-ae90-f31ffc0c2674": { "columnOrder": [ @@ -782,7 +790,7 @@ "dataType": "number", "isBucketed": false, "label": "Estimated Charges", - "operationType": "avg", + "operationType": "average", "scale": "ratio", "sourceField": "aws.billing.EstimatedCharges" }, @@ -801,8 +809,7 @@ "size": 10 }, "scale": "ordinal", - "sourceField": "aws.billing.ServiceName", - "suggestedPriority": 0 + "sourceField": "aws.billing.ServiceName" }, "faa5dba4-1fab-4f88-b67f-28bafa26a32d": { "dataType": "date", @@ -815,8 +822,7 @@ "scale": "interval", "sourceField": "@timestamp" } - }, - "indexPatternId": "metricbeat-*" + } } } } @@ -851,29 +857,35 @@ "title": "Top 10 Estimated Charges per Service Name [Metricbeat AWS]", "visualizationType": "lnsXY" }, + "coreMigrationVersion": "7.13.2", "id": "cde34840-e6f2-11ea-a5b5-d5a0accaec95", "migrationVersion": { - "lens": "7.8.0" + "lens": "7.13.1" }, "namespaces": [ "default" ], - "references": [], + "references": [ + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "metricbeat-*", + "name": "indexpattern-datasource-layer-dc597043-d867-4f94-ae90-f31ffc0c2674", + "type": "index-pattern" + } + ], "type": "lens", - "updated_at": "2020-09-14T04:03:51.696Z", - "version": "WzY0NzQsOF0=" + "updated_at": "2021-06-16T18:25:55.172Z", + "version": "WzgxLDFd" }, { "attributes": { "description": "", "kibanaSavedObjectMeta": { - "searchSourceJSON": { - "filter": [], - "query": { - "language": "kuery", - "query": "" - } - } + "searchSourceJSON": {} }, "title": "Daily Unblended Cost [Metricbeat AWS]", "uiStateJSON": {}, @@ -884,8 +896,6 @@ "axis_formatter": "number", "axis_position": "left", "axis_scale": "normal", - "default_index_pattern": "metricbeat-*", - "default_timefield": "@timestamp", "drop_last_bucket": 0, "filter": { "language": "kuery", @@ -929,24 +939,26 @@ "show_legend": 1, "time_field": "@timestamp", "tooltip_mode": "show_all", - "type": "timeseries" + "type": "timeseries", + "use_kibana_indexes": false }, "title": "Daily Unblended Cost [Metricbeat AWS]", "type": "metrics" } }, + "coreMigrationVersion": "7.13.2", "id": "3e091620-e64b-11ea-a838-3f4a45f85600", "migrationVersion": { - "visualization": "7.8.0" + "visualization": "7.13.1" }, "namespaces": [ "default" ], "references": [], "type": "visualization", - "updated_at": "2020-09-14T04:03:51.696Z", - "version": "WzY0NzUsOF0=" + "updated_at": "2021-06-16T18:25:55.172Z", + "version": "WzgyLDFd" } ], - "version": "7.9.0" + "version": "7.13.2" } diff --git a/x-pack/metricbeat/module/aws/billing/_meta/data.json b/x-pack/metricbeat/module/aws/billing/_meta/data.json index 46b66885830..cd237710702 100644 --- a/x-pack/metricbeat/module/aws/billing/_meta/data.json +++ b/x-pack/metricbeat/module/aws/billing/_meta/data.json @@ -2,35 +2,9 @@ "@timestamp": "2017-10-12T08:05:34.853Z", "aws": { "billing": { - "AmortizedCost": { - "amount": 0.6949203833, - "unit": "USD" - }, - "BlendedCost": { - "amount": 0.6949203833, - "unit": "USD" - }, - "NormalizedUsageAmount": { - "amount": 12, - "unit": "N/A" - }, - "UnblendedCost": { - "amount": 0.6949203833, - "unit": "USD" - }, - "UsageQuantity": { - "amount": 312.7086043154, - "unit": "N/A" - }, - "end_date": "2020-08-24", - "group_by": { - "AZ": "eu-central-1" - }, - "group_definition": { - "key": "AZ", - "type": "DIMENSION" - }, - "start_date": "2020-08-23" + "Currency": "USD", + "EstimatedCharges": 39.26, + "ServiceName": "AmazonEKS" } }, "cloud": { diff --git a/x-pack/metricbeat/module/aws/billing/_meta/data_cloudwatch.json b/x-pack/metricbeat/module/aws/billing/_meta/data_cloudwatch.json index 4ee0ef22520..cd237710702 100644 --- a/x-pack/metricbeat/module/aws/billing/_meta/data_cloudwatch.json +++ b/x-pack/metricbeat/module/aws/billing/_meta/data_cloudwatch.json @@ -3,8 +3,8 @@ "aws": { "billing": { "Currency": "USD", - "EstimatedCharges": 0, - "ServiceName": "AmazonDynamoDB" + "EstimatedCharges": 39.26, + "ServiceName": "AmazonEKS" } }, "cloud": { diff --git a/x-pack/metricbeat/module/aws/billing/_meta/data_group_by_instance_type.json b/x-pack/metricbeat/module/aws/billing/_meta/data_group_by_instance_type.json index a5109dd8e54..c1b2ea33e53 100644 --- a/x-pack/metricbeat/module/aws/billing/_meta/data_group_by_instance_type.json +++ b/x-pack/metricbeat/module/aws/billing/_meta/data_group_by_instance_type.json @@ -3,26 +3,26 @@ "aws": { "billing": { "AmortizedCost": { - "amount": 44.64, + "amount": 51.6, "unit": "USD" }, "BlendedCost": { - "amount": 44.64, + "amount": 51.6, "unit": "USD" }, "NormalizedUsageAmount": { - "amount": 576, + "amount": 672, "unit": "N/A" }, "UnblendedCost": { - "amount": 44.64, + "amount": 51.6, "unit": "USD" }, "UsageQuantity": { - "amount": 144, + "amount": 168, "unit": "N/A" }, - "end_date": "2020-08-24", + "end_date": "2021-06-22", "group_by": { "INSTANCE_TYPE": "db.r5.large" }, @@ -30,7 +30,7 @@ "key": "INSTANCE_TYPE", "type": "DIMENSION" }, - "start_date": "2020-08-23" + "start_date": "2021-06-21" } }, "cloud": { diff --git a/x-pack/metricbeat/module/aws/billing/_meta/data_group_by_linked_account.json b/x-pack/metricbeat/module/aws/billing/_meta/data_group_by_linked_account.json new file mode 100644 index 00000000000..55beaf05c8e --- /dev/null +++ b/x-pack/metricbeat/module/aws/billing/_meta/data_group_by_linked_account.json @@ -0,0 +1,55 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "aws": { + "billing": { + "AmortizedCost": { + "amount": 86.0273421729, + "unit": "USD" + }, + "BlendedCost": { + "amount": 86.003330576, + "unit": "USD" + }, + "NormalizedUsageAmount": { + "amount": 1896, + "unit": "N/A" + }, + "UnblendedCost": { + "amount": 86.0273421729, + "unit": "USD" + }, + "UsageQuantity": { + "amount": 1813824.6596604364, + "unit": "N/A" + }, + "end_date": "2021-06-22", + "group_by": { + "LINKED_ACCOUNT": "428152502467" + }, + "group_definition": { + "key": "LINKED_ACCOUNT", + "type": "DIMENSION" + }, + "start_date": "2021-06-21" + } + }, + "cloud": { + "account": { + "id": "428152502467", + "name": "elastic-beats" + }, + "provider": "aws" + }, + "event": { + "dataset": "aws.billing", + "duration": 115000, + "module": "aws" + }, + "metricset": { + "name": "billing", + "period": 10000 + }, + "service": { + "type": "aws" + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/aws/billing/_meta/docs.asciidoc b/x-pack/metricbeat/module/aws/billing/_meta/docs.asciidoc index 17a16cb7c4f..ebdabfd7bc3 100644 --- a/x-pack/metricbeat/module/aws/billing/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/aws/billing/_meta/docs.asciidoc @@ -15,6 +15,7 @@ tag:getResources sts:GetCallerIdentity iam:ListAccountAliases ce:GetCostAndUsage +organizations:ListAccounts ---- [float] diff --git a/x-pack/metricbeat/module/aws/billing/billing.go b/x-pack/metricbeat/module/aws/billing/billing.go index 39d600983d0..c1c66ac0529 100644 --- a/x-pack/metricbeat/module/aws/billing/billing.go +++ b/x-pack/metricbeat/module/aws/billing/billing.go @@ -18,6 +18,8 @@ import ( "github.com/aws/aws-sdk-go-v2/service/cloudwatch/cloudwatchiface" "github.com/aws/aws-sdk-go-v2/service/costexplorer" "github.com/aws/aws-sdk-go-v2/service/costexplorer/costexploreriface" + "github.com/aws/aws-sdk-go-v2/service/organizations" + "github.com/aws/aws-sdk-go-v2/service/organizations/organizationsiface" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" @@ -208,6 +210,15 @@ func (m *MetricSet) getCloudWatchBillingMetrics( func (m *MetricSet) getCostGroupBy(svcCostExplorer costexploreriface.ClientAPI, groupByDimKeys []string, groupByTags []string, timePeriod costexplorer.DateInterval, startDate string, endDate string) []mb.Event { var events []mb.Event + // get linked account IDs and names + accounts := map[string]string{} + if ok, _ := aws.StringInSlice("LINKED_ACCOUNT", groupByDimKeys); ok { + awsConfig := m.MetricSet.AwsConfig.Copy() + svcOrg := organizations.New(awscommon.EnrichAWSConfigWithEndpoint( + m.Endpoint, "organizations", regionName, awsConfig)) + accounts = m.getAccountName(svcOrg) + } + groupBys := getGroupBys(groupByTags, groupByDimKeys) for _, groupBy := range groupBys { var groupDefs []costexplorer.GroupDefinition @@ -256,6 +267,12 @@ func (m *MetricSet) getCostGroupBy(svcCostExplorer costexploreriface.ClientAPI, // key value like db.t2.micro or Amazon Simple Queue Service belongs to dimension if !strings.Contains(key, "$") { event.MetricSetFields.Put("group_by."+groupBy.dimension, key) + if groupBy.dimension == "LINKED_ACCOUNT" { + if name, ok := accounts[key]; ok { + event.RootFields.Put("aws.linked_account.id", key) + event.RootFields.Put("aws.linked_account.name", name) + } + } continue } @@ -407,3 +424,23 @@ func generateEventID(eventID string) string { prefix := hex.EncodeToString(h.Sum(nil)) return prefix[:20] } + +func (m *MetricSet) getAccountName(svc organizationsiface.ClientAPI) map[string]string { + // construct ListAccountsInput + ListAccountsInput := &organizations.ListAccountsInput{} + req := svc.ListAccountsRequest(ListAccountsInput) + p := organizations.NewListAccountsPaginator(req) + + accounts := map[string]string{} + for p.Next(context.TODO()) { + page := p.CurrentPage() + for _, a := range page.Accounts { + accounts[*a.Id] = *a.Name + } + } + + if err := p.Err(); err != nil { + m.logger.Warnf("failed ListAccountsRequest", err) + } + return accounts +} diff --git a/x-pack/metricbeat/module/aws/billing/billing_integration_test.go b/x-pack/metricbeat/module/aws/billing/billing_integration_test.go index af603626ffb..ca1d8dd7a16 100644 --- a/x-pack/metricbeat/module/aws/billing/billing_integration_test.go +++ b/x-pack/metricbeat/module/aws/billing/billing_integration_test.go @@ -12,12 +12,28 @@ import ( "strconv" "testing" + "github.com/stretchr/testify/assert" + "github.com/elastic/beats/v7/libbeat/common" + _ "github.com/elastic/beats/v7/libbeat/processors/actions" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws" "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws/mtest" ) +func TestFetch(t *testing.T) { + config := mtest.GetConfigForTest(t, "billing", "24h") + + metricSet := mbtest.NewReportingMetricSetV2Error(t, config) + events, errs := mbtest.ReportingFetchV2Error(metricSet) + if len(errs) > 0 { + t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs) + } + + assert.NotEmpty(t, events) + mbtest.TestMetricsetFieldsDocumented(t, metricSet, events) +} + func TestData(t *testing.T) { resultTypeIs := func(resultType string) func(e common.MapStr) bool { return func(e common.MapStr) bool { @@ -42,6 +58,7 @@ func TestData(t *testing.T) { }{ {"AZ", "./_meta/data.json"}, {"INSTANCE_TYPE", "./_meta/data_group_by_instance_type.json"}, + {"LINKED_ACCOUNT", "./_meta/data_group_by_linked_account.json"}, {"true", "./_meta/data_cloudwatch.json"}, } @@ -49,6 +66,7 @@ func TestData(t *testing.T) { config = addCostExplorerToConfig(config) for _, df := range dataFiles { metricSet := mbtest.NewFetcher(t, config) + metricSet.WriteEvents(t, "/") t.Run(fmt.Sprintf("result type: %s", df.resultType), func(t *testing.T) { metricSet.WriteEventsCond(t, df.path, resultTypeIs(df.resultType)) }) @@ -57,7 +75,7 @@ func TestData(t *testing.T) { func addCostExplorerToConfig(config map[string]interface{}) map[string]interface{} { costExplorerConfig := map[string]interface{}{} - costExplorerConfig["group_by_dimension_keys"] = []string{"AZ", "INSTANCE_TYPE"} + costExplorerConfig["group_by_dimension_keys"] = []string{"AZ", "INSTANCE_TYPE", "LINKED_ACCOUNT"} config["cost_explorer_config"] = costExplorerConfig return config } diff --git a/x-pack/metricbeat/module/aws/fields.go b/x-pack/metricbeat/module/aws/fields.go index 8c40517bb58..a06ed77cfae 100644 --- a/x-pack/metricbeat/module/aws/fields.go +++ b/x-pack/metricbeat/module/aws/fields.go @@ -19,5 +19,5 @@ func init() { // AssetAws returns asset data. // This is the base64 encoded gzipped contents of module/aws. func AssetAws() string { - return "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" + return "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" } diff --git a/x-pack/metricbeat/module/aws/mtest/integration.go b/x-pack/metricbeat/module/aws/mtest/integration.go index fba6b9fe3b2..243d783e365 100644 --- a/x-pack/metricbeat/module/aws/mtest/integration.go +++ b/x-pack/metricbeat/module/aws/mtest/integration.go @@ -8,10 +8,6 @@ import ( "errors" "os" "testing" - - "github.com/stretchr/testify/assert" - - "github.com/elastic/beats/v7/metricbeat/mb" ) // GetConfigForTest function gets aws credentials for integration tests. @@ -51,33 +47,6 @@ func GetConfigForTest(t *testing.T, metricSetName string, period string) map[str return config } -// CheckEventField function checks a given field type and compares it with the expected type for integration tests. -func CheckEventField(metricName string, expectedType string, event mb.Event, t *testing.T) { - t.Helper() - - ok1, err1 := event.MetricSetFields.HasKey(metricName) - ok2, err2 := event.RootFields.HasKey(metricName) - if ok1 || ok2 { - if ok1 { - assert.NoError(t, err1) - metricValue, err := event.MetricSetFields.GetValue(metricName) - assert.NoError(t, err) - err = compareType(metricValue, expectedType, metricName) - assert.NoError(t, err) - t.Log("Succeed: Field " + metricName + " matches type " + expectedType) - } else if ok2 { - assert.NoError(t, err2) - rootValue, err := event.RootFields.GetValue(metricName) - assert.NoError(t, err) - err = compareType(rootValue, expectedType, metricName) - assert.NoError(t, err) - t.Log("Succeed: Field " + metricName + " matches type " + expectedType) - } - } else { - t.Log("Field " + metricName + " does not exist in metric set fields") - } -} - func compareType(metricValue interface{}, expectedType string, metricName string) (err error) { switch metricValue.(type) { case float64: diff --git a/x-pack/metricbeat/modules.d/aws.yml.disabled b/x-pack/metricbeat/modules.d/aws.yml.disabled index ffcf68887ec..32fc0debd0a 100644 --- a/x-pack/metricbeat/modules.d/aws.yml.disabled +++ b/x-pack/metricbeat/modules.d/aws.yml.disabled @@ -41,8 +41,9 @@ - "AZ" - "INSTANCE_TYPE" - "SERVICE" -# group_by_tag_keys: -# - "aws:createdBy" + - "LINKED_ACCOUNT" + group_by_tag_keys: + - "aws:createdBy" - module: aws period: 24h metricsets: