From a9f0d3e4bde35d039849284695b35ca84d7420a6 Mon Sep 17 00:00:00 2001 From: Himanshu Singh Date: Wed, 25 Feb 2026 19:11:41 +0530 Subject: [PATCH 1/2] [receiver/sqlserver] Fix host.name attribute with datasource config Fixes #42355 When using the datasource configuration option, the host.name resource attribute is now correctly extracted from the datasource connection string using the existing parseDataSource method. --- ...rverreceiver-hostname-with-datasource.yaml | 29 ++++++++ receiver/sqlserverreceiver/scraper.go | 22 +++++- receiver/sqlserverreceiver/scraper_test.go | 74 +++++++++++++++++++ 3 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 .chloggen/fix-sqlserverreceiver-hostname-with-datasource.yaml diff --git a/.chloggen/fix-sqlserverreceiver-hostname-with-datasource.yaml b/.chloggen/fix-sqlserverreceiver-hostname-with-datasource.yaml new file mode 100644 index 0000000000000..ee804d9d4f1ce --- /dev/null +++ b/.chloggen/fix-sqlserverreceiver-hostname-with-datasource.yaml @@ -0,0 +1,29 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog) +component: receiver/sqlserver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Fixed `host.name` resource attribute to be correctly extracted from `datasource` configuration when `server` is not set" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [42355] + +# (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: | + When using the `datasource` configuration option, the `host.name` resource attribute will now be + properly parsed from the datasource connection string instead of being left empty or using an incorrect value. + +# 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: [user] diff --git a/receiver/sqlserverreceiver/scraper.go b/receiver/sqlserverreceiver/scraper.go index c37320f1c9ec6..7eb6a4cd39c70 100644 --- a/receiver/sqlserverreceiver/scraper.go +++ b/receiver/sqlserverreceiver/scraper.go @@ -174,12 +174,28 @@ func (s *sqlServerScraperHelper) setupResourceBuilder(row sqlquery.StringMap) *m rb := s.mb.NewResourceBuilder() rb.SetSqlserverComputerName(row[computerNameKey]) rb.SetSqlserverInstanceName(row[instanceNameKey]) - rb.SetHostName(s.config.Server) + + hostName := s.config.Server + serverAddress := s.config.Server + serverPort := int64(s.config.Port) + + if s.config.DataSource != "" { + host, port, err := parseDataSource(s.config.DataSource) + if err != nil { + s.logger.Warn("Failed to parse datasource for host.name attribute, using fallback", zap.Error(err)) + } else { + hostName = host + serverAddress = host + serverPort = int64(port) + } + } + + rb.SetHostName(hostName) rb.SetServiceInstanceID(s.serviceInstanceID) if !removeServerResourceAttributeFeatureGate.IsEnabled() { - rb.SetServerAddress(s.config.Server) - rb.SetServerPort(int64(s.config.Port)) + rb.SetServerAddress(serverAddress) + rb.SetServerPort(serverPort) } return rb diff --git a/receiver/sqlserverreceiver/scraper_test.go b/receiver/sqlserverreceiver/scraper_test.go index 8b80d467fb928..083a321e39ea4 100644 --- a/receiver/sqlserverreceiver/scraper_test.go +++ b/receiver/sqlserverreceiver/scraper_test.go @@ -5,6 +5,7 @@ package sqlserverreceiver import ( "context" + "database/sql" "encoding/hex" "encoding/json" "errors" @@ -18,6 +19,7 @@ import ( "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/receiver/receivertest" + "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/common/testutil" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" @@ -631,3 +633,75 @@ func TestRecordDatabaseSampleQuery(t *testing.T) { }) } } + +func TestSetupResourceBuilder(t *testing.T) { + tests := []struct { + name string + config *Config + expectedHostName string + }{ + { + name: "with server configuration", + config: func() *Config { + cfg := createDefaultConfig().(*Config) + cfg.Server = "testserver.example.com" + cfg.Port = 1433 + cfg.MetricsBuilderConfig.ResourceAttributes.HostName.Enabled = true + return cfg + }(), + expectedHostName: "testserver.example.com", + }, + { + name: "with datasource configuration", + config: func() *Config { + cfg := createDefaultConfig().(*Config) + cfg.DataSource = "sqlserver://testuser:testpass@datasource-host.example.com:1434?database=testdb" + cfg.MetricsBuilderConfig.ResourceAttributes.HostName.Enabled = true + return cfg + }(), + expectedHostName: "datasource-host.example.com", + }, + { + name: "with datasource default port", + config: func() *Config { + cfg := createDefaultConfig().(*Config) + cfg.DataSource = "sqlserver://testuser:testpass@datasource-host2.example.com?database=testdb" + cfg.MetricsBuilderConfig.ResourceAttributes.HostName.Enabled = true + return cfg + }(), + expectedHostName: "datasource-host2.example.com", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + settings := receivertest.NewNopSettings(metadata.Type) + scraper := newSQLServerScraper( + settings.ID, + "SELECT 1", + sqlquery.TelemetryConfig{}, + func() (*sql.DB, error) { return nil, nil }, + func(db sqlquery.Db, sql string, logger *zap.Logger, telemetry sqlquery.TelemetryConfig) sqlquery.DbClient { + return nil + }, + settings, + tt.config, + nil, + ) + + scraper.mb = metadata.NewMetricsBuilder(tt.config.MetricsBuilderConfig, settings) + + row := sqlquery.StringMap{ + computerNameKey: "test-computer", + instanceNameKey: "test-instance", + } + + rb := scraper.setupResourceBuilder(row) + resource := rb.Emit() + + hostName, exists := resource.Attributes().Get("host.name") + assert.True(t, exists) + assert.Equal(t, tt.expectedHostName, hostName.AsString()) + }) + } +} From 53b0c13b6c3da429a2250ac9f49c2efb7a769f19 Mon Sep 17 00:00:00 2001 From: Himanshu Singh Date: Fri, 27 Feb 2026 18:33:43 +0530 Subject: [PATCH 2/2] fix: rename unused parameters to _ in scraper_test.go --- receiver/sqlserverreceiver/scraper_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/receiver/sqlserverreceiver/scraper_test.go b/receiver/sqlserverreceiver/scraper_test.go index 083a321e39ea4..69c402b38ca92 100644 --- a/receiver/sqlserverreceiver/scraper_test.go +++ b/receiver/sqlserverreceiver/scraper_test.go @@ -681,14 +681,13 @@ func TestSetupResourceBuilder(t *testing.T) { "SELECT 1", sqlquery.TelemetryConfig{}, func() (*sql.DB, error) { return nil, nil }, - func(db sqlquery.Db, sql string, logger *zap.Logger, telemetry sqlquery.TelemetryConfig) sqlquery.DbClient { + func(_ sqlquery.Db, _ string, _ *zap.Logger, _ sqlquery.TelemetryConfig) sqlquery.DbClient { return nil }, settings, tt.config, nil, ) - scraper.mb = metadata.NewMetricsBuilder(tt.config.MetricsBuilderConfig, settings) row := sqlquery.StringMap{