Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c3000ca
feat(dbi): add SQL Server receiver translator with 50 metrics
Klarsen04 Jul 26, 2026
b22f81c
feat(dbi): configure SQL Server DBI pipeline and connectors
Klarsen04 Jul 26, 2026
d8c2f4b
feat(dbi): register SQL Server components
Klarsen04 Jul 26, 2026
350dbec
feat(dbi): update sample configs and dependencies for SQL Server
Klarsen04 Jul 26, 2026
06d91e7
feat(detector): add SQL Server detector for workload discovery
Klarsen04 Jul 26, 2026
1a8207f
feat(dbi): integrate SQL Server with workload discovery
Klarsen04 Jul 26, 2026
cc2cbeb
feat(dbi): add SQL Server application.name attribute support Add supp…
Klarsen04 Jul 29, 2026
ddc16d7
Merge branch 'larkirs/mysql' into larkirs/dbi-sqlserver
Klarsen04 Jul 30, 2026
7f75913
chore(dbi): tune SQL Server query sample limits
Klarsen04 Jul 31, 2026
d8e127a
chore(dbi): tune MySQL query sample limits
Klarsen04 Jul 31, 2026
8e35863
Merge branch 'larkirs/mysql-pipeline-translator' into larkirs/mysql
Klarsen04 Jul 31, 2026
4ec95cd
Merge branch 'larkirs/mysql' into larkirs/dbi-sqlserver
Klarsen04 Jul 31, 2026
0724728
Merge branch 'main' into larkirs/dbi-sqlserver
Klarsen04 Jul 31, 2026
9e310e2
Merge branch 'main' into larkirs/mysql
Klarsen04 Jul 31, 2026
52659b2
fix(workload-discovery): Resolve named instance ports on Windows via …
Klarsen04 Aug 5, 2026
effecd9
fix(dbi): Decode SQL Server ERRORLOG as UTF-16LE on Windows
Klarsen04 Aug 5, 2026
b7e259f
chore(dbi): update mysqlreceiver to latest dbi-mysql branch (83b5027c…
Klarsen04 Aug 6, 2026
6b99654
Merge branch 'larkirs/mysql' into larkirs/dbi-sqlserver
Klarsen04 Aug 6, 2026
fa3daed
Merge branch 'feature/dbi-sqlserver' into larkirs/dbi-sqlserver
Klarsen04 Aug 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ replace (
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awsekshyperpodreceiver => github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/awsekshyperpodreceiver v0.0.0-20260717191209-ee093fbfffbd
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awsxrayreceiver => github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/awsxrayreceiver v0.0.0-20260717191209-ee093fbfffbd
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jmxreceiver => github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/jmxreceiver v0.0.0-20260717191209-ee093fbfffbd
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver => github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/mysqlreceiver v0.0.0-20260728131824-bed4560687ee
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver => github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/mysqlreceiver v0.0.0-20260730161852-83b5027c386b
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/postgresqlreceiver => github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/postgresqlreceiver v0.0.0-20260717191209-ee093fbfffbd
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver => github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.0.0-20260717191209-ee093fbfffbd
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlserverreceiver => github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/sqlserverreceiver v0.0.0-20260729175257-2c50db1bb14e
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/awsxrayr
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/awsxrayreceiver v0.0.0-20260717191209-ee093fbfffbd/go.mod h1:gNDpUc9eYHKy9YqGYK8toPIo3QZKdYQFLnaVQDA32A0=
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/jmxreceiver v0.0.0-20260717191209-ee093fbfffbd h1:AF4G2iJwaLeBivwjWMppWYbmfObc+foQws5fetLUWxk=
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/jmxreceiver v0.0.0-20260717191209-ee093fbfffbd/go.mod h1:wQV77sHJJdUMIvbJna8LjlNb0omEdiVSrwQnoVAlTMM=
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/mysqlreceiver v0.0.0-20260728131824-bed4560687ee h1:XELS9NH+v8xvMQS49SckY5HWDfqrYNzUPQT62NT4QgY=
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/mysqlreceiver v0.0.0-20260728131824-bed4560687ee/go.mod h1:NAyuB/xYR3FsPuegcRvVeStWW83y5oUQhekzT856urI=
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/mysqlreceiver v0.0.0-20260730161852-83b5027c386b h1:AHEwT0RHOaEDz0t5WrH7OkQH93I2zoFaM90qR01oLII=
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/mysqlreceiver v0.0.0-20260730161852-83b5027c386b/go.mod h1:NAyuB/xYR3FsPuegcRvVeStWW83y5oUQhekzT856urI=
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/postgresqlreceiver v0.0.0-20260717191209-ee093fbfffbd h1:Q0XNkIPZEiIlknoP0X0PxoKVmlKR0itxyHQjZUkFTsg=
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/postgresqlreceiver v0.0.0-20260717191209-ee093fbfffbd/go.mod h1:DdKZOg4y/ac/f/ENvYWWg6e6r+INsAkx6DqRXzps1TU=
github.com/amazon-contributing/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.0.0-20260717191209-ee093fbfffbd h1:gguRr06gAfXYB1kxUZH7VaZobUauXRX+uNWGA0hsGx4=
Expand Down
13 changes: 6 additions & 7 deletions internal/detector/sqlserver/extract/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ type portExtractor struct {
subExtractors []detector.PortExtractor
}

// NewPortExtractor creates a port extractor that attempts to find the SQL Server port
// from command line arguments (-p flag) or environment variables (MSSQL_TCP_PORT).
// Falls back to the default SQL Server port 1433.
// NewPortExtractor creates a port extractor that attempts to find the SQL Server port.
// On Windows, it first checks the registry to resolve named instance ports.
// Then it tries command line arguments (-p flag) and environment variables (MSSQL_TCP_PORT).
// Falls back to the default SQL Server port 1433 if all sources fail.
func NewPortExtractor() detector.PortExtractor {
extractors := append(platformPortExtractors(), &cmdlinePortExtractor{}, &envPortExtractor{})
return &portExtractor{
subExtractors: []detector.PortExtractor{
&cmdlinePortExtractor{},
&envPortExtractor{},
},
subExtractors: extractors,
}
}

Expand Down
14 changes: 14 additions & 0 deletions internal/detector/sqlserver/extract/port_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

//go:build !windows

package extract

import "github.com/aws/amazon-cloudwatch-agent/internal/detector"

// platformPortExtractors returns an empty slice on non-Windows platforms.
// Linux SQL Server uses -p flag or MSSQL_TCP_PORT which are handled by the common extractors.
func platformPortExtractors() []detector.PortExtractor {
return nil
}
126 changes: 126 additions & 0 deletions internal/detector/sqlserver/extract/port_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

//go:build windows

package extract

import (
"context"
"fmt"
"strconv"
"strings"

"golang.org/x/sys/windows/registry"

"github.com/aws/amazon-cloudwatch-agent/internal/detector"
"github.com/aws/amazon-cloudwatch-agent/internal/detector/util"
)

const (
instanceNameFlag = "-s"
defaultInstanceName = "MSSQLSERVER"
sqlServerRegBasePath = `SOFTWARE\Microsoft\Microsoft SQL Server`
)

// platformPortExtractors returns Windows-specific port extractors.
// The registry extractor correctly resolves ports for named instances.
func platformPortExtractors() []detector.PortExtractor {
return []detector.PortExtractor{&registryPortExtractor{}}
}

// registryPortExtractor reads the TCP port from the Windows registry for a SQL Server instance.
// Each instance stores its port in:
// HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\<InstanceID>\MSSQLServer\SuperSocketNetLib\Tcp\IPAll
type registryPortExtractor struct{}

func (e *registryPortExtractor) Extract(ctx context.Context, process detector.Process) (int, error) {
instanceName := extractInstanceName(ctx, process)

instanceID, err := resolveInstanceID(instanceName)
if err != nil {
return 0, err
}

return readPortFromRegistry(instanceID)
}

// extractInstanceName gets the SQL Server instance name from the process command line.
// Named instances are started with -s INSTANCENAME flag. Default instance uses MSSQLSERVER.
func extractInstanceName(ctx context.Context, process detector.Process) string {
args, err := process.CmdlineSliceWithContext(ctx)
if err != nil {
return defaultInstanceName
}

for i, arg := range args {
lower := strings.ToLower(arg)
if lower == instanceNameFlag && i+1 < len(args) {
return strings.ToUpper(args[i+1])
}
if strings.HasPrefix(lower, instanceNameFlag) && len(arg) > len(instanceNameFlag) {
return strings.ToUpper(arg[len(instanceNameFlag):])
}
}

return defaultInstanceName
}

// resolveInstanceID maps an instance name (e.g., "MSSQLSERVER" or "YOURDBINSTANCE2")
// to its registry ID (e.g., "MSSQL17.MSSQLSERVER") by reading
// HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL
func resolveInstanceID(instanceName string) (string, error) {
keyPath := sqlServerRegBasePath + `\Instance Names\SQL`
key, err := registry.OpenKey(registry.LOCAL_MACHINE, keyPath, registry.QUERY_VALUE)
if err != nil {
return "", fmt.Errorf("failed to open registry key %s: %w", keyPath, err)
}
defer key.Close()

instanceID, _, err := key.GetStringValue(instanceName)
if err != nil {
return "", fmt.Errorf("failed to read instance %s from registry: %w", instanceName, err)
}

return instanceID, nil
}

// readPortFromRegistry reads the TCP port for a given instance ID.
// Checks TcpPort (static) first, then TcpDynamicPorts (dynamic).
func readPortFromRegistry(instanceID string) (int, error) {
keyPath := fmt.Sprintf(`%s\%s\MSSQLServer\SuperSocketNetLib\Tcp\IPAll`, sqlServerRegBasePath, instanceID)
key, err := registry.OpenKey(registry.LOCAL_MACHINE, keyPath, registry.QUERY_VALUE)
if err != nil {
return 0, fmt.Errorf("failed to open registry key %s: %w", keyPath, err)
}
defer key.Close()

if port, err := readPortValue(key, "TcpPort"); err == nil {
return port, nil
}

if port, err := readPortValue(key, "TcpDynamicPorts"); err == nil {
return port, nil
}

return 0, detector.ErrExtractPort
}

func readPortValue(key registry.Key, valueName string) (int, error) {
val, _, err := key.GetStringValue(valueName)
if err != nil {
return 0, err
}
val = strings.TrimSpace(val)
if val == "" {
return 0, detector.ErrExtractPort
}
port, err := strconv.Atoi(val)
if err != nil {
return 0, err
}
if !util.IsValidPort(port) {
return 0, detector.ErrInvalidPort
}
return port, nil
}
65 changes: 65 additions & 0 deletions internal/detector/sqlserver/extract/port_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

//go:build windows

package extract

import (
"context"
"testing"

"github.com/stretchr/testify/assert"

"github.com/aws/amazon-cloudwatch-agent/internal/detector/detectortest"
)

func TestExtractInstanceName(t *testing.T) {
ctx := context.Background()

tests := map[string]struct {
cmdline []string
cmdlineErr error
wantInstance string
}{
"DefaultInstance/NoCmdlineFlag": {
cmdline: []string{"sqlservr"},
wantInstance: "MSSQLSERVER",
},
"DefaultInstance/CmdlineError": {
cmdlineErr: assert.AnError,
wantInstance: "MSSQLSERVER",
},
"NamedInstance/SeparateArg": {
cmdline: []string{"sqlservr", "-s", "YOURDBINSTANCE2"},
wantInstance: "YOURDBINSTANCE2",
},
"NamedInstance/AttachedArg": {
cmdline: []string{"sqlservr", "-sYOURDBINSTANCE2"},
wantInstance: "YOURDBINSTANCE2",
},
"NamedInstance/LowercaseFlag": {
cmdline: []string{"sqlservr", "-s", "myinstance"},
wantInstance: "MYINSTANCE",
},
"NamedInstance/WithOtherFlags": {
cmdline: []string{"sqlservr", "-f", "-s", "INST2", "-T", "3608"},
wantInstance: "INST2",
},
}

for name, tt := range tests {
t.Run(name, func(t *testing.T) {
mp := new(detectortest.MockProcess)
if tt.cmdlineErr != nil {
mp.On("CmdlineSliceWithContext", ctx).Return(nil, tt.cmdlineErr)
} else {
mp.On("CmdlineSliceWithContext", ctx).Return(tt.cmdline, nil)
}

got := extractInstanceName(ctx, mp)
assert.Equal(t, tt.wantInstance, got)
mp.AssertExpectations(t)
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package databaseinsights

import (
"fmt"
"runtime"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -283,6 +284,10 @@ func (t *dbiTranslator) serverLogReceiver() common.ComponentTranslator {
filelog.WithSeverityPattern(buildSqlServerSeverityPattern()),
filelog.WithSeverityMapping(sqlserverLogSeverityMapping),
)
// Windows SQL Server writes ERRORLOG in UTF-16LE encoding.
if runtime.GOOS == "windows" {
opts = append(opts, filelog.WithEncoding("utf-16le"))
}
}
return filelog.NewTranslator(opts...)
}
Expand Down
Loading