Skip to content

Commit

Permalink
[receiver/azuremonitorreceiver] feat: multi subscriptions support and…
Browse files Browse the repository at this point in the history
… automatic discovery

Signed-off-by: Célian Garcia <[email protected]>
  • Loading branch information
celian-garcia committed Dec 2, 2024
1 parent 3acc90c commit b99931a
Show file tree
Hide file tree
Showing 11 changed files with 603 additions and 334 deletions.
27 changes: 27 additions & 0 deletions .chloggen/feat_discovery.yaml
Original file line number Diff line number Diff line change
@@ -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: "multi subscriptions support and automatic discovery"

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [36467]

# (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: []
4 changes: 3 additions & 1 deletion receiver/azuremonitorreceiver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ This receiver scrapes Azure Monitor API for resources metrics.

The following settings are required:

- `subscription_id`
- `subscription_ids`: list of subscriptions on which the resource's metrics are collected
- or `subscriptions_id`: same as `subscription_ids` but not a list
- or `discover_subscriptions`: (default = `false`) If set to true, will collect metrics from all subscriptions in the tenant.

The following settings are optional:

Expand Down
18 changes: 10 additions & 8 deletions receiver/azuremonitorreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ const (

var (
// Predefined error responses for configuration validation failures
errMissingTenantID = errors.New(`TenantID" is not specified in config`)
errMissingSubscriptionID = errors.New(`SubscriptionID" is not specified in config`)
errMissingClientID = errors.New(`ClientID" is not specified in config`)
errMissingClientSecret = errors.New(`ClientSecret" is not specified in config`)
errMissingFedTokenFile = errors.New(`FederatedTokenFile is not specified in config`)
errInvalidCloud = errors.New(`Cloud" is invalid`)
errMissingTenantID = errors.New(`"TenantID" is not specified in config`)
errMissingSubscriptionIDs = errors.New(`neither "SubscriptionID" nor "SubscriptionIDs" nor "DiscoverSubscription" is specified in the config`)
errMissingClientID = errors.New(`"ClientID" is not specified in config`)
errMissingClientSecret = errors.New(`"ClientSecret" is not specified in config`)
errMissingFedTokenFile = errors.New(`"FederatedTokenFile"" is not specified in config`)
errInvalidCloud = errors.New(`"Cloud" is invalid`)

monitorServices = []string{
"Microsoft.EventGrid/eventSubscriptions",
Expand Down Expand Up @@ -234,6 +234,8 @@ type Config struct {
MetricsBuilderConfig metadata.MetricsBuilderConfig `mapstructure:",squash"`
Cloud string `mapstructure:"cloud"`
SubscriptionID string `mapstructure:"subscription_id"`
SubscriptionIDs []string `mapstructure:"subscription_ids"`
DiscoverSubscriptions bool `mapstructure:"discover_subscriptions"`
Authentication string `mapstructure:"auth"`
TenantID string `mapstructure:"tenant_id"`
ClientID string `mapstructure:"client_id"`
Expand All @@ -257,8 +259,8 @@ const (

// Validate validates the configuration by checking for missing or invalid fields
func (c Config) Validate() (err error) {
if c.SubscriptionID == "" {
err = multierr.Append(err, errMissingSubscriptionID)
if c.SubscriptionID == "" && len(c.SubscriptionIDs) == 0 && !c.DiscoverSubscriptions {
err = multierr.Append(err, errMissingSubscriptionIDs)
}

switch c.Authentication {
Expand Down
1 change: 1 addition & 0 deletions receiver/azuremonitorreceiver/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.11.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0
github.com/google/go-cmp v0.6.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.114.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.114.0
Expand Down
2 changes: 2 additions & 0 deletions receiver/azuremonitorreceiver/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 10 additions & 13 deletions receiver/azuremonitorreceiver/internal/metadata/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,7 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) {
// ResourceMetricsOption applies changes to provided resource metrics.
type ResourceMetricsOption func(ResourceAttributesSettings, pmetric.ResourceMetrics)

// WithAzureMonitorSubscriptionID sets provided value as "azuremonitor.subscription_id" attribute for current resource.
func WithAzureMonitorSubscriptionID(val string) ResourceMetricsOption {
return func(ras ResourceAttributesSettings, rm pmetric.ResourceMetrics) {
if ras.AzureMonitorSubscriptionID.Enabled {
rm.Resource().Attributes().PutStr("azuremonitor.subscription_id", val)
}
}
}

// WithAzuremonitorTenantID sets provided value as "azuremonitor.tenant_id" attribute for current resource.
// WithAzureMonitorTenantID sets provided value as "azuremonitor.tenant_id" attribute for current resource.
func WithAzureMonitorTenantID(val string) ResourceMetricsOption {
return func(ras ResourceAttributesSettings, rm pmetric.ResourceMetrics) {
if ras.AzureMonitorTenantID.Enabled {
Expand Down Expand Up @@ -209,6 +200,7 @@ func (mb *MetricsBuilder) addMetric(resourceMetricID, logicalMetricID, unit stri
}

func (mb *MetricsBuilder) AddDataPoint(
subscriptionID,
resourceID,
metric,
aggregation,
Expand All @@ -218,7 +210,7 @@ func (mb *MetricsBuilder) AddDataPoint(
val float64,
) {
logicalMetricID := getLogicalMetricID(metric, aggregation)
resourceMetricID := getLogicalResourceMetricID(resourceID, logicalMetricID)
resourceMetricID := getLogicalResourceMetricID(subscriptionID, resourceID, logicalMetricID)

m, exists := mb.getMetric(resourceMetricID)
if !exists {
Expand All @@ -232,6 +224,11 @@ func (mb *MetricsBuilder) AddDataPoint(
dp.SetStartTimestamp(mb.startTime)
dp.SetTimestamp(ts)
dp.SetDoubleValue(val)

if mb.resourceAttributesSettings.AzureMonitorSubscriptionID.Enabled {
dp.Attributes().PutStr("azuremonitor.subscription_id", subscriptionID)
}

dp.Attributes().PutStr("azuremonitor.resource_id", resourceID)
for key, value := range attributes {
dp.Attributes().PutStr(key, *value)
Expand All @@ -242,8 +239,8 @@ func getLogicalMetricID(metric, aggregation string) string {
return strings.ToLower(fmt.Sprintf("%s%s_%s", metricsPrefix, strings.ReplaceAll(metric, " ", "_"), aggregation))
}

func getLogicalResourceMetricID(resourceID, logicalMetricID string) string {
return fmt.Sprintf("%s/%s", strings.ToLower(resourceID), logicalMetricID)
func getLogicalResourceMetricID(subscriptionID, resourceID, logicalMetricID string) string {
return fmt.Sprintf("%s/%s/%s", strings.ToLower(subscriptionID), strings.ToLower(resourceID), logicalMetricID)
}

func (mb *MetricsBuilder) EmitAllMetrics(ils pmetric.ScopeMetrics) {
Expand Down
27 changes: 11 additions & 16 deletions receiver/azuremonitorreceiver/internal/metadata/metrics_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b99931a

Please sign in to comment.