Skip to content

Commit 7181996

Browse files
[8.14](backport #40135) [aws] Fix missing metrics bug when include_linked_accounts set to false (#40137)
* [aws] Fix missing metrics bug when include_linked_accounts set to false (#40135) (cherry picked from commit 8da898f) * Update CHANGELOG.next.asciidoc --------- Co-authored-by: kaiyan-sheng <[email protected]>
1 parent 779ae7b commit 7181996

File tree

3 files changed

+62
-8
lines changed

3 files changed

+62
-8
lines changed

CHANGELOG.next.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff]
103103
- Normalize AWS RDS CPU Utilization values before making the metadata API call. {pull}39664[39664]
104104
- Fix behavior of pagetypeinfo metrics {pull}39985[39985]
105105
- Fix query logic for temp and non-temp tablespaces in Oracle module. {issue}38051[38051] {pull}39787[39787]
106+
- Fix missing metrics from CloudWatch when include_linked_accounts set to false. {issue}40071[40071] {pull}40135[40135]
106107

107108
*Osquerybeat*
108109

x-pack/metricbeat/module/aws/utils.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,12 @@ func GetListMetricsOutput(namespace string, regionName string, period time.Durat
8181
}
8282

8383
// when IncludeLinkedAccounts is set to false, ListMetrics API does not return any OwningAccounts
84-
if page.OwningAccounts == nil {
85-
for _, metric := range page.Metrics {
86-
metricWithAccountID = append(metricWithAccountID, MetricWithID{metric, monitoringAccountID})
87-
}
88-
return metricWithAccountID, nil
89-
}
90-
9184
for i, metric := range page.Metrics {
92-
metricWithAccountID = append(metricWithAccountID, MetricWithID{metric, page.OwningAccounts[i]})
85+
owningAccount := monitoringAccountID
86+
if page.OwningAccounts != nil {
87+
owningAccount = page.OwningAccounts[i]
88+
}
89+
metricWithAccountID = append(metricWithAccountID, MetricWithID{metric, owningAccount})
9390
}
9491
}
9592
return metricWithAccountID, nil

x-pack/metricbeat/module/aws/utils_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package aws
66

77
import (
88
"context"
9+
"strconv"
910
"testing"
1011
"time"
1112

@@ -49,6 +50,9 @@ type MockCloudWatchClient struct{}
4950
// MockCloudwatchClientCrossAccounts struct is used for unit tests.
5051
type MockCloudwatchClientCrossAccounts struct{}
5152

53+
// MockCloudwatchClientMultiplePages struct is used for unit tests.
54+
type MockCloudwatchClientMultiplePages struct{}
55+
5256
// GetMetricData implements cloudwatch.GetMetricDataAPIClient interface
5357
func (m *MockCloudWatchClient) GetMetricData(context.Context, *cloudwatch.GetMetricDataInput, ...func(*cloudwatch.Options)) (*cloudwatch.GetMetricDataOutput, error) {
5458
emptyString := ""
@@ -158,6 +162,51 @@ func (m *MockCloudwatchClientCrossAccounts) ListMetrics(context.Context, *cloudw
158162
}, nil
159163
}
160164

165+
func (m *MockCloudwatchClientMultiplePages) ListMetrics(ctx context.Context, input *cloudwatch.ListMetricsInput, opts ...func(*cloudwatch.Options)) (*cloudwatch.ListMetricsOutput, error) {
166+
var allMetrics = []cloudwatchtypes.Metric{
167+
{
168+
MetricName: &metricName,
169+
Namespace: &namespace,
170+
Dimensions: []cloudwatchtypes.Dimension{
171+
{Name: &dimName, Value: &instanceID1},
172+
},
173+
},
174+
{
175+
MetricName: awssdk.String("NetworkIn"),
176+
Namespace: &namespace,
177+
Dimensions: []cloudwatchtypes.Dimension{
178+
{Name: &dimName, Value: &instanceID1},
179+
},
180+
},
181+
}
182+
183+
pageSize := 1 // Change this to control the number of metrics per page
184+
startIndex := 0
185+
186+
if input.NextToken != nil {
187+
index, err := strconv.Atoi(*input.NextToken)
188+
if err != nil {
189+
return nil, err
190+
}
191+
startIndex = index
192+
}
193+
194+
endIndex := startIndex + pageSize
195+
if endIndex > len(allMetrics) {
196+
endIndex = len(allMetrics)
197+
}
198+
199+
nextToken := ""
200+
if endIndex < len(allMetrics) {
201+
nextToken = strconv.Itoa(endIndex)
202+
}
203+
204+
return &cloudwatch.ListMetricsOutput{
205+
Metrics: allMetrics[startIndex:endIndex],
206+
NextToken: awssdk.String(nextToken),
207+
}, nil
208+
}
209+
161210
// MockResourceGroupsTaggingClient is used for unit tests.
162211
type MockResourceGroupsTaggingClient struct{}
163212

@@ -221,6 +270,13 @@ func TestGetListMetricsCrossAccountsOutput(t *testing.T) {
221270
assert.Equal(t, instanceID2, *listMetricsOutput[1].Metric.Dimensions[0].Value)
222271
}
223272

273+
func TestGetListMetricsOutputWithMultiplePages(t *testing.T) {
274+
svcCloudwatch := &MockCloudwatchClientMultiplePages{}
275+
listMetricsOutput, err := GetListMetricsOutput("AWS/EC2", "us-west-1", time.Minute*5, false, "123", svcCloudwatch)
276+
assert.NoError(t, err)
277+
assert.Equal(t, 2, len(listMetricsOutput))
278+
}
279+
224280
func TestGetListMetricsOutputWithWildcard(t *testing.T) {
225281
svcCloudwatch := &MockCloudWatchClient{}
226282
listMetricsOutput, err := GetListMetricsOutput("*", "us-west-1", time.Minute*5, false, "123", svcCloudwatch)

0 commit comments

Comments
 (0)