From aa46e6ef3b6f623a9393a462a4eef49ee70b86e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lian=20Garcia?= Date: Wed, 6 Nov 2024 16:25:36 +0100 Subject: [PATCH] [receiver/azuremonitorreceiver] feat: Allow to not split result by dimension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: CĂ©lian Garcia --- .chloggen/split-dimensions-optout.yaml | 27 +++++++++++++++++++ receiver/azuremonitorreceiver/README.md | 1 + receiver/azuremonitorreceiver/config.go | 1 + receiver/azuremonitorreceiver/factory.go | 4 +++ receiver/azuremonitorreceiver/factory_test.go | 3 +++ receiver/azuremonitorreceiver/scraper.go | 4 ++- receiver/azuremonitorreceiver/scraper_test.go | 15 ++++++++--- 7 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 .chloggen/split-dimensions-optout.yaml diff --git a/.chloggen/split-dimensions-optout.yaml b/.chloggen/split-dimensions-optout.yaml new file mode 100644 index 000000000000..2edb73ff43dd --- /dev/null +++ b/.chloggen/split-dimensions-optout.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: receiver/azuremonitorreceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add split_by_dimensions which allows to opt out from automatically split by all the dimensions of the resource type" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [36240] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/receiver/azuremonitorreceiver/README.md b/receiver/azuremonitorreceiver/README.md index 709f73753676..65bf669fe1af 100644 --- a/receiver/azuremonitorreceiver/README.md +++ b/receiver/azuremonitorreceiver/README.md @@ -31,6 +31,7 @@ The following settings are optional: - `maximum_number_of_records_per_resource` (default = 10): Maximum number of records to fetch per resource. - `initial_delay` (default = `1s`): defines how long this receiver waits before starting. - `cloud` (default = `AzureCloud`): defines which Azure cloud to use. Valid values: `AzureCloud`, `AzureUSGovernment`, `AzureChinaCloud`. +- `split_by_dimensions` (default = `true`): allows to opt out from automatically split by all the dimensions of the resource type. Authenticating using service principal requires following additional settings: diff --git a/receiver/azuremonitorreceiver/config.go b/receiver/azuremonitorreceiver/config.go index 6e835003e781..2f2e0475252f 100644 --- a/receiver/azuremonitorreceiver/config.go +++ b/receiver/azuremonitorreceiver/config.go @@ -246,6 +246,7 @@ type Config struct { MaximumNumberOfMetricsInACall int `mapstructure:"maximum_number_of_metrics_in_a_call"` MaximumNumberOfRecordsPerResource int32 `mapstructure:"maximum_number_of_records_per_resource"` AppendTagsAsAttributes bool `mapstructure:"append_tags_as_attributes"` + SplitByDimensions *bool `mapstructure:"split_by_dimensions"` } const ( diff --git a/receiver/azuremonitorreceiver/factory.go b/receiver/azuremonitorreceiver/factory.go index 5e05fbec078a..d33f7d97e82f 100644 --- a/receiver/azuremonitorreceiver/factory.go +++ b/receiver/azuremonitorreceiver/factory.go @@ -8,6 +8,8 @@ import ( "errors" "time" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver" @@ -19,6 +21,7 @@ import ( const ( defaultCollectionInterval = 10 * time.Second defaultCloud = azureCloud + defaultSplitByDimensions = true ) var errConfigNotAzureMonitor = errors.New("Config was not a Azure Monitor receiver config") @@ -45,6 +48,7 @@ func createDefaultConfig() component.Config { Services: monitorServices, Authentication: servicePrincipal, Cloud: defaultCloud, + SplitByDimensions: to.Ptr(defaultSplitByDimensions), } } diff --git a/receiver/azuremonitorreceiver/factory_test.go b/receiver/azuremonitorreceiver/factory_test.go index 1ddd3408c96b..b0ce48139032 100644 --- a/receiver/azuremonitorreceiver/factory_test.go +++ b/receiver/azuremonitorreceiver/factory_test.go @@ -8,6 +8,8 @@ import ( "testing" "time" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer/consumertest" @@ -47,6 +49,7 @@ func TestNewFactory(t *testing.T) { MaximumNumberOfRecordsPerResource: 10, Authentication: servicePrincipal, Cloud: defaultCloud, + SplitByDimensions: to.Ptr(defaultSplitByDimensions), } require.Equal(t, expectedCfg, factory.CreateDefaultConfig()) diff --git a/receiver/azuremonitorreceiver/scraper.go b/receiver/azuremonitorreceiver/scraper.go index 3e86b5608b88..fd54c0d77612 100644 --- a/receiver/azuremonitorreceiver/scraper.go +++ b/receiver/azuremonitorreceiver/scraper.go @@ -391,6 +391,7 @@ func (s *azureScraper) getResourceMetricsValues(ctx context.Context, resourceID start, end, s.cfg.MaximumNumberOfRecordsPerResource, + *s.cfg.SplitByDimensions, ) start = end @@ -438,6 +439,7 @@ func getResourceMetricsValuesRequestOptions( start int, end int, top int32, + splitByDimensions bool, ) armmonitor.MetricsClientListOptions { resType := strings.Join(metrics[start:end], ",") filter := armmonitor.MetricsClientListOptions{ @@ -448,7 +450,7 @@ func getResourceMetricsValuesRequestOptions( Top: to.Ptr(top), } - if len(dimensionsStr) > 0 { + if splitByDimensions && len(dimensionsStr) > 0 { var dimensionsFilter bytes.Buffer dimensions := strings.Split(dimensionsStr, ",") for i, dimension := range dimensions { diff --git a/receiver/azuremonitorreceiver/scraper_test.go b/receiver/azuremonitorreceiver/scraper_test.go index cd53f3abf940..1f6df7d585f4 100644 --- a/receiver/azuremonitorreceiver/scraper_test.go +++ b/receiver/azuremonitorreceiver/scraper_test.go @@ -11,6 +11,8 @@ import ( "sync" "testing" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" @@ -101,6 +103,7 @@ func TestAzureScraperStart(t *testing.T) { MaximumNumberOfMetricsInACall: 20, Services: monitorServices, Authentication: servicePrincipal, + SplitByDimensions: to.Ptr(defaultSplitByDimensions), } s := &azureScraper{ cfg: customCfg, @@ -129,6 +132,7 @@ func TestAzureScraperStart(t *testing.T) { MaximumNumberOfMetricsInACall: 20, Services: monitorServices, Authentication: workloadIdentity, + SplitByDimensions: to.Ptr(defaultSplitByDimensions), } s := &azureScraper{ cfg: customCfg, @@ -157,6 +161,7 @@ func TestAzureScraperStart(t *testing.T) { MaximumNumberOfMetricsInACall: 20, Services: monitorServices, Authentication: managedIdentity, + SplitByDimensions: to.Ptr(defaultSplitByDimensions), } s := &azureScraper{ cfg: customCfg, @@ -185,6 +190,7 @@ func TestAzureScraperStart(t *testing.T) { MaximumNumberOfMetricsInACall: 20, Services: monitorServices, Authentication: defaultCredentials, + SplitByDimensions: to.Ptr(defaultSplitByDimensions), } s := &azureScraper{ cfg: customCfg, @@ -736,7 +742,8 @@ func TestAzureScraperClientOptions(t *testing.T) { name: "AzureCloud_options", fields: fields{ cfg: &Config{ - Cloud: azureCloud, + Cloud: azureCloud, + SplitByDimensions: to.Ptr(defaultSplitByDimensions), }, }, want: &arm.ClientOptions{ @@ -749,7 +756,8 @@ func TestAzureScraperClientOptions(t *testing.T) { name: "AzureGovernmentCloud_options", fields: fields{ cfg: &Config{ - Cloud: azureGovernmentCloud, + Cloud: azureGovernmentCloud, + SplitByDimensions: to.Ptr(defaultSplitByDimensions), }, }, want: &arm.ClientOptions{ @@ -762,7 +770,8 @@ func TestAzureScraperClientOptions(t *testing.T) { name: "AzureChinaCloud_options", fields: fields{ cfg: &Config{ - Cloud: azureChinaCloud, + Cloud: azureChinaCloud, + SplitByDimensions: to.Ptr(defaultSplitByDimensions), }, }, want: &arm.ClientOptions{