diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 0ea45e376b2..f0bb604771e 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -765,6 +765,7 @@ field. You can revert this change by configuring tags for the module and omittin - Add state_daemonset metricset for Kubernetes Metricbeat module {pull}20649[20649] - Add host inventory metrics to googlecloud compute metricset. {pull}20391[20391] - Add host inventory metrics to azure compute_vm metricset. {pull}20641[20641] +- Add billing data collection from Cost Explorer into aws billing metricset. {pull}20527[20527] {issue}20103[20103] - Migrate `compute_vm` metricset to a light one, map `cloud.instance.id` field. {pull}20889[20889] - Request prometheus endpoints to be gzipped by default {pull}20766[20766] - Add billing metricset into googlecloud module. {pull}20812[20812] {issue}20738[20738] diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index be2602cd95a..18244016e80 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -1569,8 +1569,7 @@ type: object - -*`aws.billing.metrics.EstimatedCharges.max`*:: +*`aws.billing.EstimatedCharges`*:: + -- Maximum estimated charges for AWS acccount. @@ -1579,6 +1578,166 @@ type: long -- +*`aws.billing.Currency`*:: ++ +-- +Estimated charges currency unit. + +type: keyword + +-- + +*`aws.billing.ServiceName`*:: ++ +-- +Service name for the maximum estimated charges. + +type: keyword + +-- + + +*`aws.billing.AmortizedCost.amount`*:: ++ +-- +Amortized cost amount + +type: double + +-- + +*`aws.billing.AmortizedCost.unit`*:: ++ +-- +Amortized cost unit + +type: keyword + +-- + + +*`aws.billing.BlendedCost.amount`*:: ++ +-- +Blended cost amount + +type: double + +-- + +*`aws.billing.BlendedCost.unit`*:: ++ +-- +Blended cost unit + +type: keyword + +-- + + +*`aws.billing.NormalizedUsageAmount.amount`*:: ++ +-- +Normalized usage amount + +type: double + +-- + +*`aws.billing.NormalizedUsageAmount.unit`*:: ++ +-- +Normalized usage amount unit + +type: keyword + +-- + + +*`aws.billing.UnblendedCost.amount`*:: ++ +-- +Unblended cost amount + +type: double + +-- + +*`aws.billing.UnblendedCost.unit`*:: ++ +-- +Unblended cost unit + +type: keyword + +-- + + +*`aws.billing.UsageQuantity.amount`*:: ++ +-- +Usage quantity amount + +type: double + +-- + +*`aws.billing.UsageQuantity.unit`*:: ++ +-- +Usage quantity unit + +type: keyword + +-- + +*`aws.billing.start_date`*:: ++ +-- +Start date for retrieving AWS costs + +type: keyword + +-- + +*`aws.billing.end_date`*:: ++ +-- +End date for retrieving AWS costs + +type: keyword + +-- + + +*`aws.billing.group_definition.key`*:: ++ +-- +The string that represents a key for a specified group + +type: keyword + +-- + +*`aws.billing.group_definition.type`*:: ++ +-- +The string that represents the type of group + +type: keyword + +-- + +*`aws.billing.group_by.*`*:: ++ +-- +Cost explorer group by key values + + +type: object + +-- + [float] === cloudwatch diff --git a/metricbeat/docs/images/metricbeat-aws-billing-overview.png b/metricbeat/docs/images/metricbeat-aws-billing-overview.png index 9544b1fa8a8..283f2398f99 100644 Binary files a/metricbeat/docs/images/metricbeat-aws-billing-overview.png and b/metricbeat/docs/images/metricbeat-aws-billing-overview.png differ diff --git a/x-pack/metricbeat/include/list.go b/x-pack/metricbeat/include/list.go index ea6ab5697b0..6fdb2a7f7ab 100644 --- a/x-pack/metricbeat/include/list.go +++ b/x-pack/metricbeat/include/list.go @@ -12,6 +12,7 @@ import ( _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/appsearch" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/appsearch/stats" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws" + _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws/billing" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws/cloudwatch" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws/ec2" _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws/rds" diff --git a/x-pack/metricbeat/module/aws/_meta/config.yml b/x-pack/metricbeat/module/aws/_meta/config.yml index 34d2d9f5c55..618ed4cd854 100644 --- a/x-pack/metricbeat/module/aws/_meta/config.yml +++ b/x-pack/metricbeat/module/aws/_meta/config.yml @@ -30,11 +30,16 @@ - sns - sqs - module: aws - period: 12h + period: 24h metricsets: - billing - regions: - - us-east-1 + cost_explorer_config: + group_by_dimension_keys: + - "AZ" + - "INSTANCE_TYPE" + - "SERVICE" +# group_by_tag_keys: +# - "aws:createdBy" - module: aws period: 24h metricsets: 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 2f0b054ebe7..6a601bc7471 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 @@ -25,62 +25,126 @@ "gridData": { "h": 5, "i": "89dccfe8-a25e-44ea-afdb-ff01ab1f05d6", - "w": 16, + "w": 9, "x": 0, "y": 0 }, "panelIndex": "89dccfe8-a25e-44ea-afdb-ff01ab1f05d6", "panelRefName": "panel_0", "title": "AWS Account Filter", - "version": "7.4.0" + "version": "7.9.0" }, { "embeddableConfig": { - "title": "Estimated Billing Chart" + "title": "Current Total Unblended Cost" }, "gridData": { - "h": 16, - "i": "26670498-b079-4447-bbc8-e4ca8215898c", - "w": 32, - "x": 16, + "h": 18, + "i": "f1db16b5-ce0a-4f21-885f-434c16346c26", + "w": 8, + "x": 9, "y": 0 }, - "panelIndex": "26670498-b079-4447-bbc8-e4ca8215898c", + "panelIndex": "f1db16b5-ce0a-4f21-885f-434c16346c26", "panelRefName": "panel_1", - "title": "Estimated Billing Chart", - "version": "7.4.0" + "title": "Current Total Unblended Cost", + "version": "7.9.0" }, { "embeddableConfig": { - "title": "Total Estimated Charges" + "title": "Availability Zone Utilization" }, "gridData": { - "h": 11, + "h": 18, + "i": "57912f48-42ec-4d3e-ba54-bf94757d1eec", + "w": 31, + "x": 17, + "y": 0 + }, + "panelIndex": "57912f48-42ec-4d3e-ba54-bf94757d1eec", + "panelRefName": "panel_2", + "title": "Availability Zone Utilization", + "version": "7.9.0" + }, + { + "embeddableConfig": { + "title": "Total Estimated Charges For This Month" + }, + "gridData": { + "h": 13, "i": "221aab02-2747-4d84-9dde-028ccd51bdce", - "w": 16, + "w": 9, "x": 0, "y": 5 }, "panelIndex": "221aab02-2747-4d84-9dde-028ccd51bdce", - "panelRefName": "panel_2", - "title": "Total Estimated Charges", - "version": "7.4.0" + "panelRefName": "panel_3", + "title": "Total Estimated Charges For This Month", + "version": "7.9.0" }, { "embeddableConfig": { - "title": "Top 10 Estimated Billing Per Service Name" + "title": "Cost Per Service Per User" }, "gridData": { - "h": 15, - "i": "21e91e6b-0ff0-42ba-9132-6f30c5c6bbb7", - "w": 48, + "h": 20, + "i": "376f236b-1365-4e80-8076-eec88c1a67bd", + "w": 24, "x": 0, - "y": 16 + "y": 18 }, - "panelIndex": "21e91e6b-0ff0-42ba-9132-6f30c5c6bbb7", - "panelRefName": "panel_3", - "title": "Top 10 Estimated Billing Per Service Name", - "version": "7.4.0" + "panelIndex": "376f236b-1365-4e80-8076-eec88c1a67bd", + "panelRefName": "panel_4", + "title": "Cost Per Service Per User", + "version": "7.9.0" + }, + { + "embeddableConfig": { + "title": "High Spenders" + }, + "gridData": { + "h": 20, + "i": "dd5220c2-dc8a-4d3e-964b-6137d1e447ad", + "w": 24, + "x": 24, + "y": 18 + }, + "panelIndex": "dd5220c2-dc8a-4d3e-964b-6137d1e447ad", + "panelRefName": "panel_5", + "title": "High Spenders", + "version": "7.9.0" + }, + { + "embeddableConfig": { + "title": "Top 10 Estimated Charges per Service Name" + }, + "gridData": { + "h": 18, + "i": "1de716e2-bad9-4fe3-ba49-0e2ea2a59bb4", + "w": 24, + "x": 0, + "y": 38 + }, + "panelIndex": "1de716e2-bad9-4fe3-ba49-0e2ea2a59bb4", + "panelRefName": "panel_6", + "title": "Top 10 Estimated Charges per Service Name", + "version": "7.9.0" + }, + { + "embeddableConfig": { + "title": "Daily Unblended Cost" + }, + "gridData": { + "h": 18, + "i": "60181fec-fea9-4f99-b5f9-a53ffbc2ac65", + "w": 24, + "x": 24, + "y": 38 + }, + "panelIndex": "60181fec-fea9-4f99-b5f9-a53ffbc2ac65", + "panelRefName": "panel_7", + "title": "Daily Unblended Cost", + "version": "7.9.0" } ], "timeRestore": false, @@ -91,6 +155,9 @@ "migrationVersion": { "dashboard": "7.3.0" }, + "namespaces": [ + "default" + ], "references": [ { "id": "deab0260-2981-11e9-86eb-a3a07a77f530", @@ -98,24 +165,44 @@ "type": "visualization" }, { - "id": "749cd470-1530-11ea-841c-01bf20a6c8ba", + "id": "1731c440-e649-11ea-a838-3f4a45f85600", "name": "panel_1", "type": "visualization" }, { - "id": "83f08eb0-1532-11ea-841c-01bf20a6c8ba", + "id": "a5670a20-e65a-11ea-a838-3f4a45f85600", "name": "panel_2", "type": "visualization" }, { - "id": "31a4ea90-152b-11ea-841c-01bf20a6c8ba", + "id": "83f08eb0-1532-11ea-841c-01bf20a6c8ba", "name": "panel_3", "type": "visualization" + }, + { + "id": "b3da5ac0-e6f1-11ea-a5b5-d5a0accaec95", + "name": "panel_4", + "type": "lens" + }, + { + "id": "d7b399c0-e6f1-11ea-a5b5-d5a0accaec95", + "name": "panel_5", + "type": "lens" + }, + { + "id": "cde34840-e6f2-11ea-a5b5-d5a0accaec95", + "name": "panel_6", + "type": "lens" + }, + { + "id": "3e091620-e64b-11ea-a838-3f4a45f85600", + "name": "panel_7", + "type": "visualization" } ], "type": "dashboard", - "updated_at": "2020-02-04T15:57:47.353Z", - "version": "WzY3NjQsMV0=" + "updated_at": "2020-09-14T04:08:21.260Z", + "version": "WzcyNjksOF0=" }, { "attributes": { @@ -162,8 +249,11 @@ }, "id": "deab0260-2981-11e9-86eb-a3a07a77f530", "migrationVersion": { - "visualization": "7.3.1" + "visualization": "7.8.0" }, + "namespaces": [ + "default" + ], "references": [ { "id": "metricbeat-*", @@ -172,8 +262,8 @@ } ], "type": "visualization", - "updated_at": "2020-01-27T21:33:20.219Z", - "version": "WzQ2OTAsMV0=" + "updated_at": "2020-09-14T04:04:04.990Z", + "version": "WzY2MDYsOF0=" }, { "attributes": { @@ -181,61 +271,132 @@ "kibanaSavedObjectMeta": { "searchSourceJSON": { "filter": [], - "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.index", "query": { "language": "kuery", "query": "" } } }, - "title": "Estimated Billing Pie Chart [Metricbeat AWS]", - "uiStateJSON": { - "vis": { - "colors": { - "16": "#629E51", - "272": "#DEDAF7", - "80": "#E24D42", - "running": "#7EB26D", - "stopped": "#E24D42" + "title": "Total Unblended Cost [Metricbeat AWS]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "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\"" }, - "legendOpen": true + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "metricbeat-*", + "interval": "\u003e=2d", + "isModelInvalid": false, + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "filter": { + "language": "kuery", + "query": "aws.billing.group_definition.key : \"AZ\"" + }, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "Total Unblended Cost", + "line_width": 1, + "metrics": [ + { + "field": "aws.billing.UnblendedCost.amount", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "sum" + } + ], + "override_index_pattern": 1, + "point_size": 1, + "separate_axis": 0, + "series_drop_last_bucket": 0, + "series_index_pattern": "metricbeat-*", + "series_interval": "\u003e=2d", + "series_time_field": "@timestamp", + "split_color_mode": "kibana", + "split_mode": "filter", + "stacked": "none", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "@timestamp", + "time_range_mode": "last_value", + "tooltip_mode": "show_all", + "type": "metric" + }, + "title": "Total Unblended Cost [Metricbeat AWS]", + "type": "metrics" + } + }, + "id": "1731c440-e649-11ea-a838-3f4a45f85600", + "migrationVersion": { + "visualization": "7.8.0" + }, + "namespaces": [ + "default" + ], + "references": [], + "type": "visualization", + "updated_at": "2020-09-14T04:03:51.696Z", + "version": "WzY0NjksOF0=" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.index", + "query": { + "language": "kuery", + "query": "" + } } }, + "title": "Availability Zone Utilization [Metricbeat AWS]", + "uiStateJSON": {}, "version": 1, "visState": { "aggs": [ { "enabled": true, "id": "1", - "params": { - "customLabel": "", - "field": "aws.billing.metrics.EstimatedCharges.max" - }, + "params": {}, "schema": "metric", - "type": "sum" + "type": "count" }, { "enabled": true, "id": "2", "params": { - "customLabel": "", - "field": "aws.dimensions.ServiceName", + "exclude": "NoAZ", + "field": "aws.billing.group_by.AZ", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", - "orderAgg": { - "enabled": true, - "id": "2-orderAgg", - "params": { - "field": "aws.billing.metrics.EstimatedCharges.max" - }, - "schema": "orderAgg", - "type": "avg" - }, - "orderBy": "custom", - "otherBucket": true, + "orderBy": "1", + "otherBucket": false, "otherBucketLabel": "Other", - "size": 10 + "size": 20 }, "schema": "segment", "type": "terms" @@ -244,32 +405,7 @@ "params": { "addLegend": true, "addTooltip": true, - "dimensions": { - "buckets": [ - { - "accessor": 0, - "aggType": "terms", - "format": { - "id": "terms", - "params": { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other" - } - }, - "params": {} - } - ], - "metric": { - "accessor": 1, - "aggType": "sum", - "format": { - "id": "number" - }, - "params": {} - } - }, - "isDonut": false, + "isDonut": true, "labels": { "last_level": true, "show": true, @@ -279,14 +415,17 @@ "legendPosition": "right", "type": "pie" }, - "title": "Estimated Billing Pie Chart [Metricbeat AWS]", + "title": "Availability Zone Utilization [Metricbeat AWS]", "type": "pie" } }, - "id": "749cd470-1530-11ea-841c-01bf20a6c8ba", + "id": "a5670a20-e65a-11ea-a838-3f4a45f85600", "migrationVersion": { - "visualization": "7.3.1" + "visualization": "7.8.0" }, + "namespaces": [ + "default" + ], "references": [ { "id": "metricbeat-*", @@ -295,8 +434,8 @@ } ], "type": "visualization", - "updated_at": "2020-01-27T21:33:08.924Z", - "version": "WzQ1ODAsMV0=" + "updated_at": "2020-09-14T04:03:51.696Z", + "version": "WzY0NzAsOF0=" }, { "attributes": { @@ -332,6 +471,10 @@ "default_index_pattern": "metricbeat-*", "default_timefield": "@timestamp", "drop_last_bucket": 0, + "filter": { + "language": "kuery", + "query": "aws.billing.EstimatedCharges : * and not (aws.billing.ServiceName : * )" + }, "gauge_color_rules": [ { "id": "e8a045e0-1531-11ea-961e-c1db9cc6166e" @@ -342,7 +485,7 @@ "gauge_width": 10, "id": "61ca57f0-469d-11e7-af02-69e470af7417", "index_pattern": "metricbeat-*", - "interval": "12h", + "interval": "\u003e=1d", "isModelInvalid": false, "series": [ { @@ -352,7 +495,7 @@ "fill": 0.5, "filter": { "language": "kuery", - "query": "not aws.dimensions.ServiceName : * " + "query": "aws.billing.EstimatedCharges : * and not (aws.billing.ServiceName : * )" }, "formatter": "number", "id": "61ca57f1-469d-11e7-af02-69e470af7417", @@ -360,16 +503,19 @@ "line_width": 1, "metrics": [ { - "field": "aws.billing.metrics.EstimatedCharges.max", + "field": "aws.billing.EstimatedCharges", "id": "61ca57f2-469d-11e7-af02-69e470af7417", "type": "sum" } ], - "override_index_pattern": 0, + "override_index_pattern": 1, "point_size": 1, "separate_axis": 0, "series_drop_last_bucket": 0, - "series_interval": "12h", + "series_index_pattern": "metricbeat-*", + "series_interval": "\u003e=1d", + "series_time_field": "@timestamp", + "split_color_mode": "gradient", "split_mode": "filter", "stacked": "none", "time_range_mode": "last_value", @@ -379,6 +525,8 @@ "show_grid": 1, "show_legend": 1, "time_field": "@timestamp", + "time_range_mode": "last_value", + "tooltip_mode": "show_all", "type": "metric" }, "title": "Total Estimated Charges [Metricbeat AWS]", @@ -387,12 +535,333 @@ }, "id": "83f08eb0-1532-11ea-841c-01bf20a6c8ba", "migrationVersion": { - "visualization": "7.3.1" + "visualization": "7.8.0" }, + "namespaces": [ + "default" + ], "references": [], "type": "visualization", - "updated_at": "2020-02-03T23:52:07.805Z", - "version": "WzY3NDUsMV0=" + "updated_at": "2020-09-14T04:03:51.696Z", + "version": "WzY0NzEsOF0=" + }, + { + "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": [ + "5d850e8e-f3e0-4ad2-9697-b8c00c03f753", + "a1f5b3b8-41da-452b-8683-7a9ca6b6267f", + "75188758-7734-4fc3-af1d-297c455715f0" + ], + "columns": { + "5d850e8e-f3e0-4ad2-9697-b8c00c03f753": { + "customLabel": true, + "dataType": "string", + "isBucketed": true, + "label": "Service Name", + "operationType": "terms", + "params": { + "orderBy": { + "columnId": "75188758-7734-4fc3-af1d-297c455715f0", + "type": "column" + }, + "orderDirection": "desc", + "size": 5 + }, + "scale": "ordinal", + "sourceField": "aws.billing.group_by.SERVICE" + }, + "75188758-7734-4fc3-af1d-297c455715f0": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "Total Unblended Cost", + "operationType": "sum", + "scale": "ratio", + "sourceField": "aws.billing.UnblendedCost.amount" + }, + "a1f5b3b8-41da-452b-8683-7a9ca6b6267f": { + "dataType": "string", + "isBucketed": true, + "label": "Top values of aws.billing.group_by.aws:createdBy", + "operationType": "terms", + "params": { + "orderBy": { + "columnId": "75188758-7734-4fc3-af1d-297c455715f0", + "type": "column" + }, + "orderDirection": "desc", + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.billing.group_by.aws:createdBy", + "suggestedPriority": 0 + } + }, + "indexPatternId": "metricbeat-*" + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "fittingFunction": "None", + "layers": [ + { + "accessors": [ + "75188758-7734-4fc3-af1d-297c455715f0" + ], + "layerId": "cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3", + "seriesType": "bar_stacked", + "splitAccessor": "a1f5b3b8-41da-452b-8683-7a9ca6b6267f", + "xAccessor": "5d850e8e-f3e0-4ad2-9697-b8c00c03f753" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "bar_stacked" + } + }, + "title": "Cost Per Service Per User [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "id": "b3da5ac0-e6f1-11ea-a5b5-d5a0accaec95", + "migrationVersion": { + "lens": "7.8.0" + }, + "namespaces": [ + "default" + ], + "references": [], + "type": "lens", + "updated_at": "2020-09-14T04:03:51.696Z", + "version": "WzY0NzIsOF0=" + }, + { + "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": [ + "a1f5b3b8-41da-452b-8683-7a9ca6b6267f", + "75188758-7734-4fc3-af1d-297c455715f0" + ], + "columns": { + "75188758-7734-4fc3-af1d-297c455715f0": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "Total Unblended Cost", + "operationType": "sum", + "scale": "ratio", + "sourceField": "aws.billing.UnblendedCost.amount" + }, + "a1f5b3b8-41da-452b-8683-7a9ca6b6267f": { + "customLabel": true, + "dataType": "string", + "isBucketed": true, + "label": "Top Users", + "operationType": "terms", + "params": { + "orderBy": { + "columnId": "75188758-7734-4fc3-af1d-297c455715f0", + "type": "column" + }, + "orderDirection": "desc", + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.billing.group_by.aws:createdBy", + "suggestedPriority": 0 + } + }, + "indexPatternId": "metricbeat-*" + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "fittingFunction": "None", + "layers": [ + { + "accessors": [ + "75188758-7734-4fc3-af1d-297c455715f0" + ], + "layerId": "cbffa0b1-50bb-40fe-bd8d-6a26d2b58fb3", + "seriesType": "bar_horizontal", + "xAccessor": "a1f5b3b8-41da-452b-8683-7a9ca6b6267f" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "bar_horizontal" + } + }, + "title": "High Spenders [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "id": "d7b399c0-e6f1-11ea-a5b5-d5a0accaec95", + "migrationVersion": { + "lens": "7.8.0" + }, + "namespaces": [ + "default" + ], + "references": [], + "type": "lens", + "updated_at": "2020-09-14T04:03:51.696Z", + "version": "WzY0NzMsOF0=" + }, + { + "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": [ + "ea87bf3d-0a35-424b-b00b-3614c431b135", + "faa5dba4-1fab-4f88-b67f-28bafa26a32d", + "d54f4e58-d8dd-4404-8da9-12b667dd7910" + ], + "columns": { + "d54f4e58-d8dd-4404-8da9-12b667dd7910": { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "Estimated Charges", + "operationType": "avg", + "scale": "ratio", + "sourceField": "aws.billing.EstimatedCharges" + }, + "ea87bf3d-0a35-424b-b00b-3614c431b135": { + "customLabel": true, + "dataType": "string", + "isBucketed": true, + "label": "Service Names", + "operationType": "terms", + "params": { + "orderBy": { + "columnId": "d54f4e58-d8dd-4404-8da9-12b667dd7910", + "type": "column" + }, + "orderDirection": "desc", + "size": 10 + }, + "scale": "ordinal", + "sourceField": "aws.billing.ServiceName", + "suggestedPriority": 0 + }, + "faa5dba4-1fab-4f88-b67f-28bafa26a32d": { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": { + "interval": "1d" + }, + "scale": "interval", + "sourceField": "@timestamp" + } + }, + "indexPatternId": "metricbeat-*" + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "fittingFunction": "None", + "layers": [ + { + "accessors": [ + "d54f4e58-d8dd-4404-8da9-12b667dd7910" + ], + "layerId": "dc597043-d867-4f94-ae90-f31ffc0c2674", + "position": "top", + "seriesType": "line", + "showGridlines": false, + "splitAccessor": "ea87bf3d-0a35-424b-b00b-3614c431b135", + "xAccessor": "faa5dba4-1fab-4f88-b67f-28bafa26a32d" + } + ], + "legend": { + "isVisible": true, + "position": "right" + }, + "preferredSeriesType": "line" + } + }, + "title": "Top 10 Estimated Charges per Service Name [Metricbeat AWS]", + "visualizationType": "lnsXY" + }, + "id": "cde34840-e6f2-11ea-a5b5-d5a0accaec95", + "migrationVersion": { + "lens": "7.8.0" + }, + "namespaces": [ + "default" + ], + "references": [], + "type": "lens", + "updated_at": "2020-09-14T04:03:51.696Z", + "version": "WzY0NzQsOF0=" }, { "attributes": { @@ -406,14 +875,13 @@ } } }, - "title": "Top 10 Billing per Service Name [Metricbeat AWS]", + "title": "Daily Unblended Cost [Metricbeat AWS]", "uiStateJSON": {}, "version": 1, "visState": { "aggs": [], "params": { "axis_formatter": "number", - "axis_min": 0, "axis_position": "left", "axis_scale": "normal", "default_index_pattern": "metricbeat-*", @@ -421,67 +889,64 @@ "drop_last_bucket": 0, "filter": { "language": "kuery", - "query": "" + "query": "aws.billing.group_definition.key : \"AZ\"" }, - "id": "729af8b0-152a-11ea-ae8f-79fec1a0d4d3", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", "index_pattern": "metricbeat-*", - "interval": "12h", + "interval": "\u003e=1d", "isModelInvalid": false, "series": [ { "axis_position": "right", - "chart_type": "line", - "color": "#3185FC", - "fill": 0, + "chart_type": "bar", + "color": "rgba(118,208,7,1)", + "fill": "1", "filter": { "language": "kuery", - "query": "" + "query": "aws.billing.group_definition.key : \"AZ\"" }, "formatter": "number", - "id": "729b1fc0-152a-11ea-ae8f-79fec1a0d4d3", - "label": "avg(aws.billing.metrics.EstimatedCharges.max)", - "line_width": 2, + "hide_in_legend": 1, + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "Total Unblended Cost", + "line_width": 1, "metrics": [ { - "field": "aws.billing.metrics.EstimatedCharges.max", - "id": "729b1fc1-152a-11ea-ae8f-79fec1a0d4d3", + "field": "aws.billing.UnblendedCost.amount", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", "type": "sum" } ], - "override_index_pattern": 0, - "point_size": "4", + "point_size": 1, "separate_axis": 0, - "series_drop_last_bucket": 0, - "split_color_mode": "rainbow", - "split_mode": "terms", + "split_color_mode": "kibana", + "split_mode": "filter", "stacked": "none", - "steps": 0, - "terms_field": "aws.dimensions.ServiceName", - "terms_include": "", - "terms_order_by": "729b1fc1-152a-11ea-ae8f-79fec1a0d4d3", - "terms_size": "10", - "type": "timeseries", - "value_template": "${{value}}" + "type": "timeseries" } ], - "show_grid": 1, + "show_grid": 0, "show_legend": 1, "time_field": "@timestamp", + "tooltip_mode": "show_all", "type": "timeseries" }, - "title": "Top 10 Billing per Service Name [Metricbeat AWS]", + "title": "Daily Unblended Cost [Metricbeat AWS]", "type": "metrics" } }, - "id": "31a4ea90-152b-11ea-841c-01bf20a6c8ba", + "id": "3e091620-e64b-11ea-a838-3f4a45f85600", "migrationVersion": { - "visualization": "7.3.1" + "visualization": "7.8.0" }, + "namespaces": [ + "default" + ], "references": [], "type": "visualization", - "updated_at": "2020-02-04T13:56:47.812Z", - "version": "WzY3NjMsMV0=" + "updated_at": "2020-09-14T04:03:51.696Z", + "version": "WzY0NzUsOF0=" } ], - "version": "7.4.0" + "version": "7.9.0" } diff --git a/x-pack/metricbeat/module/aws/billing/_meta/data.json b/x-pack/metricbeat/module/aws/billing/_meta/data.json index df5fece2194..46b66885830 100644 --- a/x-pack/metricbeat/module/aws/billing/_meta/data.json +++ b/x-pack/metricbeat/module/aws/billing/_meta/data.json @@ -2,18 +2,35 @@ "@timestamp": "2017-10-12T08:05:34.853Z", "aws": { "billing": { - "metrics": { - "EstimatedCharges": { - "max": 0 - } - } - }, - "cloudwatch": { - "namespace": "AWS/Billing" - }, - "dimensions": { - "Currency": "USD", - "ServiceName": "AmazonSNS" + "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" } }, "cloud": { @@ -21,8 +38,7 @@ "id": "428152502467", "name": "elastic-beats" }, - "provider": "aws", - "region": "us-east-1" + "provider": "aws" }, "event": { "dataset": "aws.billing", diff --git a/x-pack/metricbeat/module/aws/billing/_meta/data_cloudwatch.json b/x-pack/metricbeat/module/aws/billing/_meta/data_cloudwatch.json new file mode 100644 index 00000000000..4ee0ef22520 --- /dev/null +++ b/x-pack/metricbeat/module/aws/billing/_meta/data_cloudwatch.json @@ -0,0 +1,29 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "aws": { + "billing": { + "Currency": "USD", + "EstimatedCharges": 0, + "ServiceName": "AmazonDynamoDB" + } + }, + "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/data_group_by_instance_type.json b/x-pack/metricbeat/module/aws/billing/_meta/data_group_by_instance_type.json new file mode 100644 index 00000000000..a5109dd8e54 --- /dev/null +++ b/x-pack/metricbeat/module/aws/billing/_meta/data_group_by_instance_type.json @@ -0,0 +1,55 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "aws": { + "billing": { + "AmortizedCost": { + "amount": 44.64, + "unit": "USD" + }, + "BlendedCost": { + "amount": 44.64, + "unit": "USD" + }, + "NormalizedUsageAmount": { + "amount": 576, + "unit": "N/A" + }, + "UnblendedCost": { + "amount": 44.64, + "unit": "USD" + }, + "UsageQuantity": { + "amount": 144, + "unit": "N/A" + }, + "end_date": "2020-08-24", + "group_by": { + "INSTANCE_TYPE": "db.r5.large" + }, + "group_definition": { + "key": "INSTANCE_TYPE", + "type": "DIMENSION" + }, + "start_date": "2020-08-23" + } + }, + "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 0e0b4ffb624..90b8f88da87 100644 --- a/x-pack/metricbeat/module/aws/billing/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/aws/billing/_meta/docs.asciidoc @@ -1,13 +1,8 @@ -You can monitor your estimated AWS charges by using Amazon CloudWatch. When you -enable the monitoring of estimated charges for your AWS account, the estimated -charges are calculated and sent several times daily to CloudWatch as metric data. +You can monitor your estimated AWS charges by using Amazon CloudWatch and Cost +Explorer. -Billing metric data is stored in the US East (N. Virginia) Region and represents -worldwide charges. This data includes the estimated charges for every service in -AWS that you use, in addition to the estimated overall total of your AWS charges. - -This aws `billing` metricset collects these Cloudwatch metrics for monitoring -purposes. +This aws `billing` metricset collects metrics both from Cloudwatch and cost +explorer for monitoring purposes. [float] === AWS Permissions @@ -19,6 +14,7 @@ cloudwatch:ListMetrics tag:getResources sts:GetCallerIdentity iam:ListAccountAliases +ce:GetCostAndUsage ---- [float] @@ -33,18 +29,28 @@ image::./images/metricbeat-aws-billing-overview.png[] [source,yaml] ---- - module: aws - period: 12h + period: 24h metricsets: - billing - # This module uses the aws cloudwatch metricset, all - # the options for this metricset are also available here. + credential_profile_name: elastic-beats + cost_explorer_config: + group_by_dimension_keys: + - "AZ" + - "INSTANCE_TYPE" + - "SERVICE" + group_by_tag_keys: + - "aws:createdBy" ---- [float] -=== Metrics -|=== -|Metric Name|Statistic Method -|EstimatedCharges | Maximum -|=== +=== Metricset-specific configuration notes +When querying AWS Cost Explorer API, you can group AWS costs using up to two +different groups, either dimensions, tag keys, or both. Right now we support +group by type dimension and type tag with separate config parameters: + +* *group_by_dimension_keys*: A list of keys used in Cost Explorer to group by +dimensions. Valid values are AZ, INSTANCE_TYPE, LEGAL_ENTITY_NAME, +LINKED_ACCOUNT, OPERATION, PLATFORM, PURCHASE_TYPE, SERVICE, TAGS, TENANCY, and +USAGE_TYPE. -Supported dimensions for billing metrics: Currency and ServiceName. +* *group_by_tag_keys*: A list of keys used in Cost Explorer to group by tags. diff --git a/x-pack/metricbeat/module/aws/billing/_meta/fields.yml b/x-pack/metricbeat/module/aws/billing/_meta/fields.yml index 2b246415653..0452be75ab4 100644 --- a/x-pack/metricbeat/module/aws/billing/_meta/fields.yml +++ b/x-pack/metricbeat/module/aws/billing/_meta/fields.yml @@ -4,9 +4,78 @@ `billing` contains the estimated charges for your AWS account in Cloudwatch. release: beta fields: - - name: metrics + - name: EstimatedCharges + type: long + description: Maximum estimated charges for AWS acccount. + - name: Currency + type: keyword + description: Estimated charges currency unit. + - name: ServiceName + type: keyword + description: Service name for the maximum estimated charges. + - name: AmortizedCost type: group fields: - - name: EstimatedCharges.max - type: long - description: Maximum estimated charges for AWS acccount. + - name: amount + type: double + description: Amortized cost amount + - name: unit + type: keyword + description: Amortized cost unit + - name: BlendedCost + type: group + fields: + - name: amount + type: double + description: Blended cost amount + - name: unit + type: keyword + description: Blended cost unit + - name: NormalizedUsageAmount + type: group + fields: + - name: amount + type: double + description: Normalized usage amount + - name: unit + type: keyword + description: Normalized usage amount unit + - name: UnblendedCost + type: group + fields: + - name: amount + type: double + description: Unblended cost amount + - name: unit + type: keyword + description: Unblended cost unit + - name: UsageQuantity + type: group + fields: + - name: amount + type: double + description: Usage quantity amount + - name: unit + type: keyword + description: Usage quantity unit + - name: start_date + type: keyword + description: Start date for retrieving AWS costs + - name: end_date + type: keyword + description: End date for retrieving AWS costs + - name: group_definition + type: group + fields: + - name: key + type: keyword + description: The string that represents a key for a specified group + - name: type + type: keyword + description: The string that represents the type of group + - name: group_by.* + type: object + object_type: keyword + object_type_mapping_type: "*" + description: > + Cost explorer group by key values diff --git a/x-pack/metricbeat/module/aws/billing/billing.go b/x-pack/metricbeat/module/aws/billing/billing.go new file mode 100644 index 00000000000..2eb2bd2854a --- /dev/null +++ b/x-pack/metricbeat/module/aws/billing/billing.go @@ -0,0 +1,407 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package billing + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "fmt" + "strconv" + "strings" + "time" + + awssdk "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/cloudwatch" + "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/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/metricbeat/mb" + awscommon "github.com/elastic/beats/v7/x-pack/libbeat/common/aws" + "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws" +) + +var ( + metricsetName = "billing" + regionName = "us-east-1" + labelSeparator = "|" + + // This list is from https://github.com/aws/aws-sdk-go-v2/blob/master/service/costexplorer/api_enums.go#L60-L90 + supportedDimensionKeys = []string{ + "AZ", "INSTANCE_TYPE", "LINKED_ACCOUNT", "OPERATION", "PURCHASE_TYPE", + "REGION", "SERVICE", "USAGE_TYPE", "USAGE_TYPE_GROUP", "RECORD_TYPE", + "OPERATING_SYSTEM", "TENANCY", "SCOPE", "PLATFORM", "SUBSCRIPTION_ID", + "LEGAL_ENTITY_NAME", "DEPLOYMENT_OPTION", "DATABASE_ENGINE", + "CACHE_ENGINE", "INSTANCE_TYPE_FAMILY", "BILLING_ENTITY", + "RESERVATION_ID", + } + + dateLayout = "2006-01-02" +) + +// init registers the MetricSet with the central registry as soon as the program +// starts. The New function will be called later to instantiate an instance of +// the MetricSet for each host defined in the module's configuration. After the +// MetricSet has been created then Fetch will begin to be called periodically. +func init() { + mb.Registry.MustAddMetricSet(aws.ModuleName, metricsetName, New, + mb.DefaultMetricSet(), + ) +} + +// MetricSet holds any configuration or state information. It must implement +// the mb.MetricSet interface. And this is best achieved by embedding +// mb.BaseMetricSet because it implements all of the required mb.MetricSet +// interface methods except for Fetch. +type MetricSet struct { + *aws.MetricSet + logger *logp.Logger + CostExplorerConfig CostExplorerConfig `config:"cost_explorer_config"` +} + +// Config holds a configuration specific for billing metricset. +type CostExplorerConfig struct { + GroupByDimensionKeys []string `config:"group_by_dimension_keys"` + GroupByTagKeys []string `config:"group_by_tag_keys"` +} + +// New creates a new instance of the MetricSet. New is responsible for unpacking +// any MetricSet specific configuration options if there are any. +func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + logger := logp.NewLogger(metricsetName) + metricSet, err := aws.NewMetricSet(base) + if err != nil { + return nil, fmt.Errorf("error creating aws metricset: %w", err) + } + + config := struct { + CostExplorerConfig CostExplorerConfig `config:"cost_explorer_config"` + }{} + + err = base.Module().UnpackConfig(&config) + if err != nil { + return nil, fmt.Errorf("error unpack raw module config using UnpackConfig: %w", err) + } + + logger.Debugf("cost explorer config = %s", config) + + return &MetricSet{ + MetricSet: metricSet, + logger: logger, + CostExplorerConfig: config.CostExplorerConfig, + }, nil +} + +// Validate checks if given dimension keys are supported. +func (c CostExplorerConfig) Validate() error { + for _, key := range c.GroupByDimensionKeys { + supported, _ := aws.StringInSlice(key, supportedDimensionKeys) + if !supported { + return fmt.Errorf("costexplorer GetCostAndUsageRequest does not support dimension key: %s", key) + } + } + return nil +} + +// Fetch methods implements the data gathering and data conversion to the right +// format. It publishes the event which is then forwarded to the output. In case +// of an error set the Error field of mb.Event or simply call report.Error(). +func (m *MetricSet) Fetch(report mb.ReporterV2) error { + // Get startDate and endDate + startDate, endDate := getStartDateEndDate(m.Period) + + // Get startTime and endTime + startTime, endTime := aws.GetStartTimeEndTime(m.Period) + + // get cost metrics from cost explorer + awsConfig := m.MetricSet.AwsConfig.Copy() + svcCostExplorer := costexplorer.New(awscommon.EnrichAWSConfigWithEndpoint( + m.Endpoint, "monitoring", "", awsConfig)) + + awsConfig.Region = regionName + svcCloudwatch := cloudwatch.New(awscommon.EnrichAWSConfigWithEndpoint( + m.Endpoint, "monitoring", regionName, awsConfig)) + + timePeriod := costexplorer.DateInterval{ + Start: awssdk.String(startDate), + End: awssdk.String(endDate), + } + + var events []mb.Event + + // Get estimated charges from CloudWatch + eventsCW := m.getCloudWatchBillingMetrics(svcCloudwatch, startTime, endTime) + events = append(events, eventsCW...) + + // Get total cost from Cost Explorer GetCostAndUsage with group by type "DIMENSION" and "TAG" + eventsCE := m.getCostGroupBy(svcCostExplorer, m.CostExplorerConfig.GroupByDimensionKeys, m.CostExplorerConfig.GroupByTagKeys, timePeriod, startDate, endDate) + events = append(events, eventsCE...) + + // report events + for _, event := range events { + if reported := report.Event(event); !reported { + m.Logger().Debug("Fetch interrupted, failed to emit event") + return nil + } + } + return nil +} + +func (m *MetricSet) getCloudWatchBillingMetrics( + svcCloudwatch cloudwatchiface.ClientAPI, + startTime time.Time, + endTime time.Time) []mb.Event { + var events []mb.Event + namespace := "AWS/Billing" + listMetricsOutput, err := aws.GetListMetricsOutput(namespace, regionName, svcCloudwatch) + if err != nil { + m.Logger().Error(err.Error()) + return nil + } + + if listMetricsOutput == nil || len(listMetricsOutput) == 0 { + return events + } + + metricDataQueriesTotal := constructMetricQueries(listMetricsOutput, m.Period) + metricDataOutput, err := aws.GetMetricDataResults(metricDataQueriesTotal, svcCloudwatch, startTime, endTime) + if err != nil { + err = fmt.Errorf("aws GetMetricDataResults failed with %w, skipping region %s", err, regionName) + m.Logger().Error(err.Error()) + return nil + } + + // Find a timestamp for all metrics in output + timestamp := aws.FindTimestamp(metricDataOutput) + if !timestamp.IsZero() { + for _, output := range metricDataOutput { + if len(output.Values) == 0 { + continue + } + exists, timestampIdx := aws.CheckTimestampInArray(timestamp, output.Timestamps) + if exists { + labels := strings.Split(*output.Label, labelSeparator) + + event := aws.InitEvent("", m.AccountName, m.AccountID) + event.MetricSetFields.Put(labels[0], output.Values[timestampIdx]) + + i := 1 + for i < len(labels)-1 { + event.MetricSetFields.Put(labels[i], labels[i+1]) + i += 2 + } + event.Timestamp = endTime + events = append(events, event) + } + } + } + return events +} + +func (m *MetricSet) getCostGroupBy(svcCostExplorer costexploreriface.ClientAPI, groupByDimKeys []string, groupByTags []string, timePeriod costexplorer.DateInterval, startDate string, endDate string) []mb.Event { + var events []mb.Event + + groupBys := getGroupBys(groupByTags, groupByDimKeys) + for _, groupBy := range groupBys { + var groupDefs []costexplorer.GroupDefinition + + if groupBy.dimension != "" { + groupDefs = append(groupDefs, costexplorer.GroupDefinition{ + Key: awssdk.String(groupBy.dimension), + Type: costexplorer.GroupDefinitionTypeDimension, + }) + } + + if groupBy.tag != "" { + groupDefs = append(groupDefs, costexplorer.GroupDefinition{ + Key: awssdk.String(groupBy.tag), + Type: costexplorer.GroupDefinitionTypeTag, + }) + } + + groupByCostInput := costexplorer.GetCostAndUsageInput{ + Granularity: costexplorer.GranularityDaily, + // no permission for "NetAmortizedCost" and "NetUnblendedCost" + Metrics: []string{"AmortizedCost", "BlendedCost", + "NormalizedUsageAmount", "UnblendedCost", "UsageQuantity"}, + TimePeriod: &timePeriod, + // Only two values for GroupBy are allowed + GroupBy: groupDefs, + } + + groupByCostReq := svcCostExplorer.GetCostAndUsageRequest(&groupByCostInput) + groupByOutput, err := groupByCostReq.Send(context.Background()) + if err != nil { + err = fmt.Errorf("costexplorer GetCostAndUsageRequest failed: %w", err) + m.Logger().Errorf(err.Error()) + return nil + } + + if len(groupByOutput.ResultsByTime) > 0 { + costResultGroups := groupByOutput.ResultsByTime[0].Groups + for _, group := range costResultGroups { + event := m.addCostMetrics(group.Metrics, groupByOutput.GroupDefinitions[0], startDate, endDate) + + // generate unique event ID for each event + eventID := startDate + endDate + *groupByOutput.GroupDefinitions[0].Key + string(groupByOutput.GroupDefinitions[0].Type) + for _, key := range group.Keys { + eventID += key + // 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) + continue + } + + // tag key value is separated by $ + tagKey, tagValue := parseGroupKey(key) + if tagValue != "" { + event.MetricSetFields.Put("group_by."+tagKey, tagValue) + } + } + + t, err := time.Parse(dateLayout, endDate) + if err == nil { + event.Timestamp = t + } + + event.ID = generateEventID(eventID) + events = append(events, event) + } + } + } + return events +} + +func (m *MetricSet) addCostMetrics(metrics map[string]costexplorer.MetricValue, groupDefinition costexplorer.GroupDefinition, startDate string, endDate string) mb.Event { + event := aws.InitEvent("", m.AccountName, m.AccountID) + + // add group definition + event.MetricSetFields.Put("group_definition", common.MapStr{ + "key": *groupDefinition.Key, + "type": groupDefinition.Type, + }) + + for metricName, metricValues := range metrics { + cost := metricValues + costFloat, err := strconv.ParseFloat(*cost.Amount, 64) + if err != nil { + err = fmt.Errorf("strconv ParseFloat failed: %w", err) + m.Logger().Errorf(err.Error()) + continue + } + + value := common.MapStr{ + "amount": costFloat, + "unit": &cost.Unit, + } + + event.MetricSetFields.Put(metricName, value) + event.MetricSetFields.Put("start_date", startDate) + event.MetricSetFields.Put("end_date", endDate) + } + return event +} + +func constructMetricQueries(listMetricsOutput []cloudwatch.Metric, period time.Duration) []cloudwatch.MetricDataQuery { + var metricDataQueries []cloudwatch.MetricDataQuery + metricDataQueryEmpty := cloudwatch.MetricDataQuery{} + for i, listMetric := range listMetricsOutput { + metricDataQuery := createMetricDataQuery(listMetric, i, period) + if metricDataQuery == metricDataQueryEmpty { + continue + } + metricDataQueries = append(metricDataQueries, metricDataQuery) + } + return metricDataQueries +} + +func createMetricDataQuery(metric cloudwatch.Metric, index int, period time.Duration) (metricDataQuery cloudwatch.MetricDataQuery) { + statistic := "Maximum" + periodInSeconds := int64(period.Seconds()) + id := metricsetName + strconv.Itoa(index) + metricDims := metric.Dimensions + metricName := *metric.MetricName + + label := metricName + labelSeparator + for _, dim := range metricDims { + label += *dim.Name + labelSeparator + *dim.Value + labelSeparator + } + + metricDataQuery = cloudwatch.MetricDataQuery{ + Id: &id, + MetricStat: &cloudwatch.MetricStat{ + Period: &periodInSeconds, + Stat: &statistic, + Metric: &metric, + }, + Label: &label, + } + return +} + +func getStartDateEndDate(period time.Duration) (startDate string, endDate string) { + currentTime := time.Now() + startTime := currentTime.Add(period * -1) + startDate = startTime.Format(dateLayout) + endDate = currentTime.Format(dateLayout) + return +} + +func parseGroupKey(groupKey string) (tagKey string, tagValue string) { + keys := strings.Split(groupKey, "$") + if len(keys) == 2 { + tagKey = keys[0] + tagValue = keys[1] + } else if len(keys) > 2 { + tagKey = keys[0] + tagValue = keys[1] + for i := 2; i < len(keys); i++ { + tagValue = tagValue + "$" + keys[i] + } + } else { + tagKey = keys[0] + tagValue = "" + } + return +} + +type groupBy struct { + tag string + dimension string +} + +func getGroupBys(groupByTags []string, groupByDimKeys []string) []groupBy { + var groupBys []groupBy + + if len(groupByTags) == 0 { + groupByTags = []string{""} + } + if len(groupByDimKeys) == 0 { + groupByDimKeys = []string{""} + } + + for _, tagKey := range groupByTags { + for _, dimKey := range groupByDimKeys { + groupBy := groupBy{ + tag: tagKey, + dimension: dimKey, + } + groupBys = append(groupBys, groupBy) + } + } + return groupBys +} + +func generateEventID(eventID string) string { + // create eventID using hash of startDate + endDate + groupDefinitionKey + groupDefinitionType + values + // This will prevent more than one billing metric getting collected in the same day. + h := sha256.New() + h.Write([]byte(eventID)) + prefix := hex.EncodeToString(h.Sum(nil)) + return prefix[:20] +} 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 3d8cbff0598..af603626ffb 100644 --- a/x-pack/metricbeat/module/aws/billing/billing_integration_test.go +++ b/x-pack/metricbeat/module/aws/billing/billing_integration_test.go @@ -8,15 +8,56 @@ package billing import ( + "fmt" + "strconv" "testing" + "github.com/elastic/beats/v7/libbeat/common" 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 TestData(t *testing.T) { - config := mtest.GetConfigForTest(t, "billing", "300s") + resultTypeIs := func(resultType string) func(e common.MapStr) bool { + return func(e common.MapStr) bool { + v, err := e.GetValue("aws.billing.group_definition.key") + if err == nil { + // Check for Cost Explorer billing metrics + k, _ := e.GetValue("aws.billing.group_by." + v.(string)) + exists, _ := aws.StringInSlice(k.(string), []string{"NoAZ", "NoInstanceType"}) + if !exists { + return v == resultType + } + } + // Check for CloudWatch billing metrics + exists, err := e.HasKey("aws.billing.EstimatedCharges") + return err == nil && strconv.FormatBool(exists) == resultType + } + } - metricSet := mbtest.NewFetcher(t, config) - metricSet.WriteEvents(t, "/") + dataFiles := []struct { + resultType string + path string + }{ + {"AZ", "./_meta/data.json"}, + {"INSTANCE_TYPE", "./_meta/data_group_by_instance_type.json"}, + {"true", "./_meta/data_cloudwatch.json"}, + } + + config := mtest.GetConfigForTest(t, "billing", "24h") + config = addCostExplorerToConfig(config) + for _, df := range dataFiles { + metricSet := mbtest.NewFetcher(t, config) + t.Run(fmt.Sprintf("result type: %s", df.resultType), func(t *testing.T) { + metricSet.WriteEventsCond(t, df.path, resultTypeIs(df.resultType)) + }) + } +} + +func addCostExplorerToConfig(config map[string]interface{}) map[string]interface{} { + costExplorerConfig := map[string]interface{}{} + costExplorerConfig["group_by_dimension_keys"] = []string{"AZ", "INSTANCE_TYPE"} + config["cost_explorer_config"] = costExplorerConfig + return config } diff --git a/x-pack/metricbeat/module/aws/billing/billing_test.go b/x-pack/metricbeat/module/aws/billing/billing_test.go index 664eeea5103..2ecd511109d 100644 --- a/x-pack/metricbeat/module/aws/billing/billing_test.go +++ b/x-pack/metricbeat/module/aws/billing/billing_test.go @@ -2,20 +2,104 @@ // or more contributor license agreements. Licensed under the Elastic License; // you may not use this file except in compliance with the Elastic License. +// +build !integration + package billing import ( - "os" - - "github.com/elastic/beats/v7/metricbeat/mb" + "testing" + "time" - // Register input module and metricset - _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws" - _ "github.com/elastic/beats/v7/x-pack/metricbeat/module/aws/cloudwatch" + "github.com/stretchr/testify/assert" ) -func init() { - // To be moved to some kind of helper - os.Setenv("BEAT_STRICT_PERMS", "false") - mb.Registry.SetSecondarySource(mb.NewLightModulesSource("../../../module")) +func TestGetStartDateEndDate(t *testing.T) { + startDate, endDate := getStartDateEndDate(time.Duration(24) * time.Hour) + assert.NotEmpty(t, startDate) + assert.NotEmpty(t, endDate) +} + +func TestParseGroupKey(t *testing.T) { + cases := []struct { + title string + groupKey string + expectedTagKey string + expectedTagValue string + }{ + { + "empty tag value", + "aws:createdBy$", + "aws:createdBy", + "", + }, + { + "with a tag value of assumed role", + "aws:createdBy$AssumedRole:AROAWHL7AXDB:158385", + "aws:createdBy", + "AssumedRole:AROAWHL7AXDB:158385", + }, + { + "with a tag value of IAM user", + "aws:createdBy$IAMUser:AIDAWHL7AXDB:foo@test.com", + "aws:createdBy", + "IAMUser:AIDAWHL7AXDB:foo@test.com", + }, + { + "tag value with $", + "aws:createdBy$IAMUser:AIDAWH$L7AXDB:foo@test.com", + "aws:createdBy", + "IAMUser:AIDAWH$L7AXDB:foo@test.com", + }, + } + + for _, c := range cases { + t.Run(c.title, func(t *testing.T) { + tagKey, tagValue := parseGroupKey(c.groupKey) + assert.Equal(t, c.expectedTagKey, tagKey) + assert.Equal(t, c.expectedTagValue, tagValue) + }) + } +} + +func TestGetGroupBys(t *testing.T) { + cases := []struct { + title string + groupByTags []string + groupByDimKeys []string + expectedGroupBys []groupBy + }{ + { + "test with both tags and dimKeys", + []string{"createdBy"}, + []string{"AZ", "INSTANCE_TYPE"}, + []groupBy{ + {"createdBy", "AZ"}, + {"createdBy", "INSTANCE_TYPE"}, + }, + }, + { + "test with only dimKeys", + []string{}, + []string{"AZ", "INSTANCE_TYPE"}, + []groupBy{ + {"", "AZ"}, + {"", "INSTANCE_TYPE"}, + }, + }, + { + "test with only tags", + []string{"createdBy"}, + []string{}, + []groupBy{ + {"createdBy", ""}, + }, + }, + } + + for _, c := range cases { + t.Run(c.title, func(t *testing.T) { + groupBys := getGroupBys(c.groupByTags, c.groupByDimKeys) + assert.Equal(t, c.expectedGroupBys, groupBys) + }) + } } diff --git a/x-pack/metricbeat/module/aws/billing/manifest.yml b/x-pack/metricbeat/module/aws/billing/manifest.yml deleted file mode 100644 index cca412df649..00000000000 --- a/x-pack/metricbeat/module/aws/billing/manifest.yml +++ /dev/null @@ -1,10 +0,0 @@ -default: true -input: - module: aws - metricset: cloudwatch - defaults: - regions: - - us-east-1 - metrics: - - namespace: AWS/Billing - statistic: ["Maximum"] diff --git a/x-pack/metricbeat/module/aws/fields.go b/x-pack/metricbeat/module/aws/fields.go index 6124034a43a..12efc5c0cf9 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/modules.d/aws.yml.disabled b/x-pack/metricbeat/modules.d/aws.yml.disabled index f245fc10928..a2b3b272e3c 100644 --- a/x-pack/metricbeat/modules.d/aws.yml.disabled +++ b/x-pack/metricbeat/modules.d/aws.yml.disabled @@ -33,11 +33,16 @@ - sns - sqs - module: aws - period: 12h + period: 24h metricsets: - billing - regions: - - us-east-1 + cost_explorer_config: + group_by_dimension_keys: + - "AZ" + - "INSTANCE_TYPE" + - "SERVICE" +# group_by_tag_keys: +# - "aws:createdBy" - module: aws period: 24h metricsets: