From efc124d24b960a2c67fe5a01b0dbc95a69b5f1fa Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Fri, 30 Aug 2019 15:22:23 -0600 Subject: [PATCH 1/3] Ignore empty events when reporting from cloudwatch metricset --- x-pack/metricbeat/module/aws/_meta/config.yml | 2 +- .../module/aws/cloudwatch/cloudwatch.go | 19 +++++++++++++++++-- x-pack/metricbeat/modules.d/aws.yml.disabled | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/x-pack/metricbeat/module/aws/_meta/config.yml b/x-pack/metricbeat/module/aws/_meta/config.yml index 90dc6dc1af3..89f188ed260 100644 --- a/x-pack/metricbeat/module/aws/_meta/config.yml +++ b/x-pack/metricbeat/module/aws/_meta/config.yml @@ -11,7 +11,7 @@ metrics: - namespace: AWS/EC2 name: ["CPUUtilization", "DiskWriteOps"] - tags.resource_type_filter: ec2:intance + tags.resource_type_filter: ec2:instance #dimensions: # - name: InstanceId # value: i-0686946e22cf9494a diff --git a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go index b4d5afc4c9f..eed2647c43d 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go @@ -456,8 +456,23 @@ func (m *MetricSet) createEvents(svcCloudwatch cloudwatchiface.ClientAPI, svcRes } for _, event := range events { - if reported := report.Event(event); !reported { - return nil + metrics, err := event.RootFields.GetValue("aws.metrics") + if err != nil { + m.Logger().Warn(errors.Wrap(err, "failed to get root field aws.metrics")) + continue + } + + dims, err := event.RootFields.GetValue("aws.cloudwatch.dimensions") + if err != nil { + m.Logger().Warn(errors.Wrap(err, "failed to get root field aws.cloudwatch.dimensions")) + continue + } + + // if metrics and dims are both nil, means this event is empty. Only report non-empty events. + if metrics != nil || dims != nil { + if reported := report.Event(event); !reported { + return nil + } } } diff --git a/x-pack/metricbeat/modules.d/aws.yml.disabled b/x-pack/metricbeat/modules.d/aws.yml.disabled index 5a3241631b5..61ad2bb049e 100644 --- a/x-pack/metricbeat/modules.d/aws.yml.disabled +++ b/x-pack/metricbeat/modules.d/aws.yml.disabled @@ -14,7 +14,7 @@ metrics: - namespace: AWS/EC2 name: ["CPUUtilization", "DiskWriteOps"] - tags.resource_type_filter: ec2:intance + tags.resource_type_filter: ec2:instance #dimensions: # - name: InstanceId # value: i-0686946e22cf9494a From bf816a9881fdc190bdd75f3882305783c9cd7607 Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Mon, 2 Sep 2019 07:55:21 -0600 Subject: [PATCH 2/3] remove getIdentifiers function --- .../module/aws/cloudwatch/cloudwatch.go | 65 +++---------------- .../module/aws/cloudwatch/cloudwatch_test.go | 6 -- 2 files changed, 8 insertions(+), 63 deletions(-) diff --git a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go index eed2647c43d..7c826bb37a3 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go @@ -323,39 +323,6 @@ func constructLabel(metric cloudwatch.Metric, statistic string) string { return label } -func getIdentifiers(metricsWithStatsTotal []metricsWithStatistics) map[string][]string { - if len(metricsWithStatsTotal) == 0 { - return nil - } - - identifiers := map[string][]string{} - for _, metricsWithStats := range metricsWithStatsTotal { - identifierName := "" - identifierValue := "" - if len(metricsWithStats.cloudwatchMetric.Dimensions) == 0 { - continue - } - - for i, dim := range metricsWithStats.cloudwatchMetric.Dimensions { - identifierName += *dim.Name - identifierValue += *dim.Value - if i != len(metricsWithStats.cloudwatchMetric.Dimensions)-1 { - identifierName += "," - identifierValue += "," - } - } - - if identifiers[identifierName] != nil { - if !aws.StringInSlice(identifierValue, identifiers[identifierName]) { - identifiers[identifierName] = append(identifiers[identifierName], identifierValue) - } - } else { - identifiers[identifierName] = []string{identifierValue} - } - } - return identifiers -} - func statisticLookup(stat string) (string, bool) { statisticLookupTable := map[string]string{ "Average": "avg", @@ -405,14 +372,9 @@ func (m *MetricSet) createEvents(svcCloudwatch cloudwatchiface.ClientAPI, svcRes m.Logger().Info(errors.Wrap(err, "getResourcesTags failed, skipping region "+regionName)) } - identifiers := getIdentifiers(listMetricWithStatsTotal) - // Initialize events map per region, which stores one event per identifierValue + // Initialize events for each identifier. events := map[string]mb.Event{} - for _, values := range identifiers { - for _, v := range values { - events[v] = aws.InitEvent(regionName) - } - } + // Initialize events for the ones without identifiers. var eventsNoIdentifier []mb.Event @@ -441,6 +403,10 @@ func (m *MetricSet) createEvents(svcCloudwatch cloudwatchiface.ClientAPI, svcRes labels := strings.Split(*output.Label, labelSeperator) if len(labels) == 5 { identifierValue := labels[identifierValueIdx] + if _, ok := events[identifierValue]; !ok { + events[identifierValue] = aws.InitEvent(regionName) + } + events[identifierValue] = insertRootFields(events[identifierValue], output.Values[timestampIdx], labels) tags := resourceTagMap[identifierValue] for _, tag := range tags { @@ -456,23 +422,8 @@ func (m *MetricSet) createEvents(svcCloudwatch cloudwatchiface.ClientAPI, svcRes } for _, event := range events { - metrics, err := event.RootFields.GetValue("aws.metrics") - if err != nil { - m.Logger().Warn(errors.Wrap(err, "failed to get root field aws.metrics")) - continue - } - - dims, err := event.RootFields.GetValue("aws.cloudwatch.dimensions") - if err != nil { - m.Logger().Warn(errors.Wrap(err, "failed to get root field aws.cloudwatch.dimensions")) - continue - } - - // if metrics and dims are both nil, means this event is empty. Only report non-empty events. - if metrics != nil || dims != nil { - if reported := report.Event(event); !reported { - return nil - } + if reported := report.Event(event); !reported { + return nil } } diff --git a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch_test.go b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch_test.go index 3da40da1545..4d08bd0280b 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch_test.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch_test.go @@ -167,12 +167,6 @@ var ( } ) -func TestGetIdentifiers(t *testing.T) { - listMetricDetailTotal := []metricsWithStatistics{metricsWithStat1, metricsWithStat2, metricsWithStat3, metricsWithStat4} - identifiers := getIdentifiers(listMetricDetailTotal) - assert.Equal(t, []string{instanceID1, instanceID2}, identifiers["InstanceId"]) -} - func TestConstructLabel(t *testing.T) { cases := []struct { listMetricDetail cloudwatch.Metric From 1692d6e68bae7b5f486e0073d589ccb2c5d5a9ad Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Mon, 2 Sep 2019 08:14:30 -0600 Subject: [PATCH 3/3] Update changelog --- CHANGELOG.next.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index ded948031dd..30b872950a6 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -186,6 +186,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix issue with aws cloudwatch module where dimensions and/or namespaces that contain space are not being parsed correctly {pull}13389[13389] - Fix panic in Redis Key metricset when collecting information from a removed key. {pull}13426[13426] - Fix module-level fields in Kubernetes metricsets. {pull}13433[13433] +- Fix reporting empty events in cloudwatch metricset. {pull}13458[13458] *Packetbeat*