From 017e67cb05df4122867d6fe6245b236034c1ae5a Mon Sep 17 00:00:00 2001 From: Cristian Greco Date: Wed, 14 Jan 2026 16:19:46 +0100 Subject: [PATCH] fix: Database_observability: reuse cloud provider regexes Consolidate the regexes in a common package and make sure to support Azure privatelink parsing. --- .../component/database_observability/cloud_provider.go | 8 ++++++++ .../database_observability/mysql/cloud_provider.go | 10 ++-------- .../mysql/collector/connection_info.go | 10 ++-------- .../database_observability/postgres/cloud_provider.go | 10 ++-------- .../postgres/collector/connection_info.go | 9 ++------- 5 files changed, 16 insertions(+), 31 deletions(-) diff --git a/internal/component/database_observability/cloud_provider.go b/internal/component/database_observability/cloud_provider.go index 60b162d09ab..8a5ff1a7f29 100644 --- a/internal/component/database_observability/cloud_provider.go +++ b/internal/component/database_observability/cloud_provider.go @@ -1,9 +1,17 @@ package database_observability import ( + "regexp" + "github.com/aws/aws-sdk-go-v2/aws/arn" ) +var ( + RdsRegex = regexp.MustCompile(`(?P[^\.]+)\.([^\.]+)\.(?P[^\.]+)\.rds\.amazonaws\.com`) + AzureMySQLRegex = regexp.MustCompile(`(?P[^\.]+)\.(?:privatelink\.)?mysql\.database\.azure\.com`) + AzurePostgreSQLRegex = regexp.MustCompile(`(?P[^\.]+)\.(?:privatelink\.)?postgres\.database\.azure\.com`) +) + type CloudProvider struct { AWS *AWSCloudProviderInfo Azure *AzureCloudProviderInfo diff --git a/internal/component/database_observability/mysql/cloud_provider.go b/internal/component/database_observability/mysql/cloud_provider.go index e5a0925eaea..becbd96f5c4 100644 --- a/internal/component/database_observability/mysql/cloud_provider.go +++ b/internal/component/database_observability/mysql/cloud_provider.go @@ -3,7 +3,6 @@ package mysql import ( "fmt" "net" - "regexp" "strings" "github.com/aws/aws-sdk-go-v2/aws/arn" @@ -11,11 +10,6 @@ import ( "github.com/grafana/alloy/internal/component/database_observability" ) -var ( - rdsRegex = regexp.MustCompile(`(?P[^\.]+)\.([^\.]+)\.(?P[^\.]+)\.rds\.amazonaws\.com`) - azureRegex = regexp.MustCompile(`(?P[^\.]+)\.mysql\.database\.azure\.com`) -) - func populateCloudProviderFromConfig(config *CloudProvider) (*database_observability.CloudProvider, error) { var cloudProvider database_observability.CloudProvider if config.AWS != nil { @@ -41,7 +35,7 @@ func populateCloudProviderFromDSN(dsn string) (*database_observability.CloudProv host, _, err := net.SplitHostPort(cfg.Addr) if err == nil && host != "" { if strings.HasSuffix(host, "rds.amazonaws.com") { - if matches := rdsRegex.FindStringSubmatch(host); len(matches) >= 4 { + if matches := database_observability.RdsRegex.FindStringSubmatch(host); len(matches) >= 4 { cloudProvider.AWS = &database_observability.AWSCloudProviderInfo{ ARN: arn.ARN{ Resource: fmt.Sprintf("db:%s", matches[1]), @@ -51,7 +45,7 @@ func populateCloudProviderFromDSN(dsn string) (*database_observability.CloudProv } } } else if strings.HasSuffix(host, "mysql.database.azure.com") { - if matches := azureRegex.FindStringSubmatch(host); len(matches) >= 2 { + if matches := database_observability.AzureMySQLRegex.FindStringSubmatch(host); len(matches) >= 2 { cloudProvider.Azure = &database_observability.AzureCloudProviderInfo{ Resource: matches[1], } diff --git a/internal/component/database_observability/mysql/collector/connection_info.go b/internal/component/database_observability/mysql/collector/connection_info.go index 0e7f286e003..3ae75a6ff61 100644 --- a/internal/component/database_observability/mysql/collector/connection_info.go +++ b/internal/component/database_observability/mysql/collector/connection_info.go @@ -3,7 +3,6 @@ package collector import ( "context" "net" - "regexp" "strings" "github.com/go-sql-driver/mysql" @@ -14,11 +13,6 @@ import ( const ConnectionInfoName = "connection_info" -var ( - rdsRegex = regexp.MustCompile(`(?P[^\.]+)\.([^\.]+)\.(?P[^\.]+)\.rds\.amazonaws\.com`) - azureRegex = regexp.MustCompile(`(?P[^\.]+)\.(?:privatelink\.)?mysql\.database\.azure\.com`) -) - type ConnectionInfoArguments struct { DSN string Registry *prometheus.Registry @@ -93,14 +87,14 @@ func (c *ConnectionInfo) Start(ctx context.Context) error { if err == nil && host != "" { if strings.HasSuffix(host, "rds.amazonaws.com") { providerName = "aws" - matches := rdsRegex.FindStringSubmatch(host) + matches := database_observability.RdsRegex.FindStringSubmatch(host) if len(matches) > 3 { dbInstanceIdentifier = matches[1] providerRegion = matches[3] } } else if strings.HasSuffix(host, "mysql.database.azure.com") { providerName = "azure" - matches := azureRegex.FindStringSubmatch(host) + matches := database_observability.AzureMySQLRegex.FindStringSubmatch(host) if len(matches) > 1 { dbInstanceIdentifier = matches[1] } diff --git a/internal/component/database_observability/postgres/cloud_provider.go b/internal/component/database_observability/postgres/cloud_provider.go index a32a78c5433..ba794086313 100644 --- a/internal/component/database_observability/postgres/cloud_provider.go +++ b/internal/component/database_observability/postgres/cloud_provider.go @@ -2,7 +2,6 @@ package postgres import ( "fmt" - "regexp" "strings" "github.com/aws/aws-sdk-go-v2/aws/arn" @@ -10,11 +9,6 @@ import ( "github.com/grafana/alloy/internal/component/database_observability/postgres/collector" ) -var ( - rdsRegex = regexp.MustCompile(`(?P[^\.]+)\.([^\.]+)\.(?P[^\.]+)\.rds\.amazonaws\.com`) - azureRegex = regexp.MustCompile(`(?P[^\.]+)\.postgres\.database\.azure\.com`) -) - func populateCloudProviderFromConfig(config *CloudProvider) (*database_observability.CloudProvider, error) { var cloudProvider database_observability.CloudProvider if config.AWS != nil { @@ -39,7 +33,7 @@ func populateCloudProviderFromDSN(dsn string) (*database_observability.CloudProv if host, ok := parts["host"]; ok { if strings.HasSuffix(host, "rds.amazonaws.com") { - matches := rdsRegex.FindStringSubmatch(host) + matches := database_observability.RdsRegex.FindStringSubmatch(host) cloudProvider.AWS = &database_observability.AWSCloudProviderInfo{ ARN: arn.ARN{ Resource: fmt.Sprintf("db:%s", matches[1]), @@ -48,7 +42,7 @@ func populateCloudProviderFromDSN(dsn string) (*database_observability.CloudProv }, } } else if strings.HasSuffix(host, "postgres.database.azure.com") { - matches := azureRegex.FindStringSubmatch(host) + matches := database_observability.AzurePostgreSQLRegex.FindStringSubmatch(host) if len(matches) > 1 { cloudProvider.Azure = &database_observability.AzureCloudProviderInfo{ Resource: matches[1], diff --git a/internal/component/database_observability/postgres/collector/connection_info.go b/internal/component/database_observability/postgres/collector/connection_info.go index f23b078b6bc..51acc5fe60b 100644 --- a/internal/component/database_observability/postgres/collector/connection_info.go +++ b/internal/component/database_observability/postgres/collector/connection_info.go @@ -12,11 +12,6 @@ import ( const ConnectionInfoName = "connection_info" -var ( - rdsRegex = regexp.MustCompile(`(?P[^\.]+)\.([^\.]+)\.(?P[^\.]+)\.rds\.amazonaws\.com`) - azureRegex = regexp.MustCompile(`(?P[^\.]+)\.(?:privatelink\.)?postgres\.database\.azure\.com`) -) - var engineVersionRegex = regexp.MustCompile(`(?P^[1-9]+\.[1-9]+)(?P.*)?$`) type ConnectionInfoArguments struct { @@ -92,14 +87,14 @@ func (c *ConnectionInfo) Start(ctx context.Context) error { if host, ok := parts["host"]; ok { if strings.HasSuffix(host, "rds.amazonaws.com") { providerName = "aws" - matches := rdsRegex.FindStringSubmatch(host) + matches := database_observability.RdsRegex.FindStringSubmatch(host) if len(matches) > 3 { dbInstanceIdentifier = matches[1] providerRegion = matches[3] } } else if strings.HasSuffix(host, "postgres.database.azure.com") { providerName = "azure" - matches := azureRegex.FindStringSubmatch(host) + matches := database_observability.AzurePostgreSQLRegex.FindStringSubmatch(host) if len(matches) > 1 { dbInstanceIdentifier = matches[1] }