Skip to content

Commit

Permalink
[AWS] Add tags to events based on parsed identifier (#33472)
Browse files Browse the repository at this point in the history
  • Loading branch information
kaiyan-sheng committed Nov 1, 2022
1 parent ce799a1 commit 50c6ae5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ https://github.com/elastic/beats/compare/v8.2.0\...main[Check the HEAD diff]
- Add GCP CloudSQL region filter {pull}32943[32943]
- Fix logstash cgroup mappings {pull}33131[33131]
- Remove unused `elasticsearch.node_stats.indices.bulk.avg_time.bytes` mapping {pull}33263[33263]
- Add tags to events based on parsed identifier. {pull}33472[33472]

*Packetbeat*

Expand Down
63 changes: 31 additions & 32 deletions x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,19 +565,26 @@ func (m *MetricSet) createEvents(svcCloudwatch cloudwatch.GetMetricDataAPIClient

identifierValue := labels[identifierValueIdx]
uniqueIdentifierValue := *output.Label + fmt.Sprint("-", valI)
if _, ok := events[uniqueIdentifierValue]; !ok {
// when tagsFilter is not empty but no entry in
// resourceTagMap for this identifier, do not initialize
// an event for this identifier.
if len(tagsFilter) != 0 && resourceTagMap[identifierValue] == nil {
continue
}
events[uniqueIdentifierValue] = aws.InitEvent(regionName, m.AccountName, m.AccountID, output.Timestamps[valI])
}
events[uniqueIdentifierValue] = insertRootFields(events[uniqueIdentifierValue], metricDataResultValue, labels)

// add tags to event based on identifierValue
insertTags(events, uniqueIdentifierValue, identifierValue, resourceTagMap)
// Check if identifier includes dimensionSeparator (comma in this case),
// split the identifier and check for each sub-identifier.
// For example, identifier might be [storageType, s3BucketName].
// And tags are only store under s3BucketName in resourceTagMap.
subIdentifiers := strings.Split(identifierValue, dimensionSeparator)
for _, subIdentifier := range subIdentifiers {
if _, ok := events[uniqueIdentifierValue]; !ok {
// when tagsFilter is not empty but no entry in
// resourceTagMap for this identifier, do not initialize
// an event for this identifier.
if len(tagsFilter) != 0 && resourceTagMap[subIdentifier] == nil {
continue
}
events[uniqueIdentifierValue] = aws.InitEvent(regionName, m.AccountName, m.AccountID, output.Timestamps[valI])
}
events[uniqueIdentifierValue] = insertRootFields(events[uniqueIdentifierValue], metricDataResultValue, labels)
insertTags(events, uniqueIdentifierValue, subIdentifier, resourceTagMap)
}
}
}
}
Expand Down Expand Up @@ -617,28 +624,20 @@ func compareAWSDimensions(dim1 []types.Dimension, dim2 []types.Dimension) bool {
return reflect.DeepEqual(dim1NameToValue, dim2NameToValue)
}

func insertTags(events map[string]mb.Event, uniqueIdentifierValue string, identifier string, resourceTagMap map[string][]resourcegroupstaggingapitypes.Tag) {
// Check if identifier includes dimensionSeparator (comma in this case),
// split the identifier and check for each sub-identifier.
// For example, identifier might be [storageType, s3BucketName].
// And tags are only store under s3BucketName in resourceTagMap.
subIdentifiers := strings.Split(identifier, dimensionSeparator)
for _, v := range subIdentifiers {
tags := resourceTagMap[v]
// some metric dimension values are arn format, eg: AWS/DDOS namespace metric
if len(tags) == 0 && strings.HasPrefix(v, "arn:") {
resourceID, err := aws.FindShortIdentifierFromARN(v)
if err == nil {
tags = resourceTagMap[resourceID]
}
func insertTags(events map[string]mb.Event, uniqueIdentifierValue string, subIdentifier string, resourceTagMap map[string][]resourcegroupstaggingapitypes.Tag) {
tags := resourceTagMap[subIdentifier]
// some metric dimension values are arn format, eg: AWS/DDOS namespace metric
if len(tags) == 0 && strings.HasPrefix(subIdentifier, "arn:") {
resourceID, err := aws.FindShortIdentifierFromARN(subIdentifier)
if err == nil {
tags = resourceTagMap[resourceID]
}
if len(tags) != 0 {
// By default, replace dot "." using underscore "_" for tag keys.
// Note: tag values are not dedotted.
for _, tag := range tags {
_, _ = events[uniqueIdentifierValue].RootFields.Put("aws.tags."+common.DeDot(*tag.Key), *tag.Value)
}
continue
}
if len(tags) != 0 {
// By default, replace dot "." using underscore "_" for tag keys.
// Note: tag values are not dedotted.
for _, tag := range tags {
_, _ = events[uniqueIdentifierValue].RootFields.Put("aws.tags."+common.DeDot(*tag.Key), *tag.Value)
}
}
}
6 changes: 5 additions & 1 deletion x-pack/metricbeat/module/aws/cloudwatch/cloudwatch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package cloudwatch
import (
"context"
"errors"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -1646,7 +1647,10 @@ func TestInsertTags(t *testing.T) {

for _, c := range cases {
t.Run(c.title, func(t *testing.T) {
insertTags(events, c.identifier, c.identifier, resourceTagMap)
subIdentifiers := strings.Split(c.identifier, dimensionSeparator)
for _, subIdentifier := range subIdentifiers {
insertTags(events, c.identifier, subIdentifier, resourceTagMap)
}
value, err := events[c.identifier].RootFields.GetValue(c.expectedTagKey)
assert.NoError(t, err)
assert.Equal(t, c.expectedTagValue, value)
Expand Down

0 comments on commit 50c6ae5

Please sign in to comment.