Skip to content

Commit 5c3822a

Browse files
authored
[chore] [receiver/sqlserver] Streamline obfuscate usage (open-telemetry#41214)
Don't use sync.Once, maintain the instance explicitly as part of the scraper
1 parent 485fda8 commit 5c3822a

File tree

3 files changed

+38
-43
lines changed

3 files changed

+38
-43
lines changed

receiver/sqlserverreceiver/obfuscate.go

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,43 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
// source(Apache 2.0): https://github.com/DataDog/datadog-agent/blob/main/pkg/collector/python/datadog_agent.go
5-
6-
// Unless explicitly stated otherwise all files in this repository are licensed
7-
// under the Apache License Version 2.0.
8-
// This product includes software developed at Datadog (https://www.datadoghq.com/).
9-
// Copyright 2016-present Datadog, Inc.
10-
114
package sqlserverreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlserverreceiver"
125

136
import (
147
"bytes"
158
"encoding/xml"
169
"fmt"
1710
"strings"
18-
"sync"
1911

2012
"github.com/DataDog/datadog-agent/pkg/obfuscate"
2113
)
2214

2315
var (
24-
obfuscator *obfuscate.Obfuscator
25-
obfuscatorLoader sync.Once
16+
xmlPlanObfuscationAttrs = []string{
17+
"StatementText",
18+
"ConstValue",
19+
"ScalarString",
20+
"ParameterCompiledValue",
21+
}
22+
obfuscateSQLConfig = obfuscate.SQLConfig{DBMS: "mssql"}
2623
)
2724

28-
// lazyInitObfuscator initializes the obfuscator the first time it is used.
29-
func lazyInitObfuscator() *obfuscate.Obfuscator {
30-
obfuscatorLoader.Do(func() { obfuscator = obfuscate.NewObfuscator(obfuscate.Config{}) })
31-
return obfuscator
25+
type obfuscator obfuscate.Obfuscator
26+
27+
func newObfuscator() *obfuscator {
28+
return (*obfuscator)(obfuscate.NewObfuscator(obfuscate.Config{}))
3229
}
3330

34-
// ObfuscateSQL obfuscates & normalizes the provided SQL query, writing the error into errResult if the operation fails.
35-
func obfuscateSQL(rawQuery string) (string, error) {
36-
obfuscatedQuery, err := lazyInitObfuscator().ObfuscateSQLStringWithOptions(rawQuery, &obfuscate.SQLConfig{DBMS: "mssql"})
31+
func (o *obfuscator) obfuscateSQLString(sql string) (string, error) {
32+
obfuscatedQuery, err := (*obfuscate.Obfuscator)(o).ObfuscateSQLStringWithOptions(sql, &obfuscateSQLConfig)
3733
if err != nil {
3834
return "", err
3935
}
40-
4136
return obfuscatedQuery.Query, nil
4237
}
4338

44-
// Ending source(Apache 2.0): https://github.com/DataDog/datadog-agent/blob/main/pkg/collector/python/datadog_agent.go
45-
46-
var xmlPlanObfuscationAttrs = []string{
47-
"StatementText",
48-
"ConstValue",
49-
"ScalarString",
50-
"ParameterCompiledValue",
51-
}
52-
5339
// obfuscateXMLPlan obfuscates SQL text & parameters from the provided SQL Server XML Plan
54-
func obfuscateXMLPlan(rawPlan string) (string, error) {
40+
func (o *obfuscator) obfuscateXMLPlan(rawPlan string) (string, error) {
5541
decoder := xml.NewDecoder(strings.NewReader(rawPlan))
5642
var buffer bytes.Buffer
5743
encoder := xml.NewEncoder(&buffer)
@@ -73,7 +59,7 @@ func obfuscateXMLPlan(rawPlan string) (string, error) {
7359
if elem.Attr[i].Value == "" {
7460
continue
7561
}
76-
val, err := obfuscateSQL(elem.Attr[i].Value)
62+
val, err := o.obfuscateSQLString(elem.Attr[i].Value)
7763
if err != nil {
7864
fmt.Println("Unable to obfuscate SQL statement in query plan, skipping: " + elem.Attr[i].Value)
7965
return "", nil

receiver/sqlserverreceiver/obfuscate_test.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,22 @@ func TestObfuscateSQL(t *testing.T) {
2020
input, err := os.ReadFile(filepath.Join("testdata", "inputSQL.sql"))
2121
assert.NoError(t, err)
2222

23-
result, err := obfuscateSQL(string(input))
23+
result, err := newObfuscator().obfuscateSQLString(string(input))
2424
assert.NoError(t, err)
2525
assert.Equal(t, expectedSQL, result)
2626
}
2727

2828
func TestObfuscateInvalidSQL(t *testing.T) {
29+
obf := newObfuscator()
2930
sql := "SELECT cpu_time AS [CPU Usage (time)"
30-
result, err := obfuscateSQL(sql)
31+
result, err := obf.obfuscateSQLString(sql)
3132

3233
assert.Error(t, err)
3334
assert.Empty(t, result)
3435

3536
sql = "SELECT cpu_time AS [CPU Usage Time]"
3637
expected := "SELECT cpu_time"
37-
result, err = obfuscateSQL(sql)
38+
result, err = obf.obfuscateSQLString(sql)
3839
assert.NoError(t, err)
3940
assert.Equal(t, expected, result)
4041
}
@@ -47,44 +48,48 @@ func TestObfuscateQueryPlan(t *testing.T) {
4748
input, err := os.ReadFile(filepath.Join("testdata", "inputQueryPlan.xml"))
4849
assert.NoError(t, err)
4950

50-
result, err := obfuscateXMLPlan(string(input))
51+
result, err := newObfuscator().obfuscateXMLPlan(string(input))
5152
assert.NoError(t, err)
5253
assert.Equal(t, expectedQueryPlan, result)
5354
}
5455

5556
func TestInvalidQueryPlans(t *testing.T) {
57+
obf := newObfuscator()
58+
5659
plan := `<ShowPlanXml</ShowPlanXML>`
57-
result, err := obfuscateXMLPlan(plan)
60+
result, err := obf.obfuscateXMLPlan(plan)
5861
assert.Empty(t, result)
5962
assert.Error(t, err)
6063

6164
plan = `<ShowPlanXML></ShowPlanXML`
62-
result, err = obfuscateXMLPlan(plan)
65+
result, err = obf.obfuscateXMLPlan(plan)
6366
assert.Empty(t, result)
6467
assert.Error(t, err)
6568

6669
plan = `<ShowPlanXML></ShowPlan>`
67-
result, err = obfuscateXMLPlan(plan)
70+
result, err = obf.obfuscateXMLPlan(plan)
6871
assert.Empty(t, result)
6972
assert.Error(t, err)
7073

7174
// obfuscate failure, return empty string
7275
plan = `<ShowPlanXML StatementText="[msdb].[dbo].[sysjobhistory].[run_duration] as [sjh].[run_duration]/(10000)*(3600)+[msdb].[dbo].[sysjobhistory].[run_duration] as [sjh].[run_duration]%(10000)/(100)*(60)+[msdb].[dbo].[sysjobhistory].[run_duration] as [sjh].[run_duration]%(100)"></ShowPlanXML>`
73-
result, err = obfuscateXMLPlan(plan)
76+
result, err = obf.obfuscateXMLPlan(plan)
7477
assert.Empty(t, result)
7578
assert.NoError(t, err)
7679
}
7780

7881
func TestValidQueryPlans(t *testing.T) {
82+
obf := newObfuscator()
83+
7984
plan := `<ShowPlanXML value="abc"></ShowPlanXML>`
80-
_, err := obfuscateXMLPlan(plan)
85+
_, err := obf.obfuscateXMLPlan(plan)
8186
assert.NoError(t, err)
8287

8388
plan = `<ShowPlanXML StatementText=""></ShowPlanXML>`
84-
_, err = obfuscateXMLPlan(plan)
89+
_, err = obf.obfuscateXMLPlan(plan)
8590
assert.NoError(t, err)
8691

8792
plan = `<ShowPlanXML StatementText="SELECT * FROM table"><!-- comment --></ShowPlanXML>`
88-
_, err = obfuscateXMLPlan(plan)
93+
_, err = obf.obfuscateXMLPlan(plan)
8994
assert.NoError(t, err)
9095
}

receiver/sqlserverreceiver/scraper.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type sqlServerScraperHelper struct {
6363
lb *metadata.LogsBuilder
6464
cache *lru.Cache[string, int64]
6565
lastExecutionTimestamp time.Time
66+
obfuscator *obfuscator
6667
}
6768

6869
var (
@@ -91,6 +92,7 @@ func newSQLServerScraper(id component.ID,
9192
lb: metadata.NewLogsBuilder(cfg.LogsBuilderConfig, params),
9293
cache: cache,
9394
lastExecutionTimestamp: time.Unix(0, 0),
95+
obfuscator: newObfuscator(),
9496
}
9597
}
9698

@@ -698,7 +700,7 @@ func (s *sqlServerScraperHelper) recordDatabaseQueryTextAndPlan(ctx context.Cont
698700

699701
queryTextVal := s.retrieveValue(row, queryText, &errs, func(row sqlquery.StringMap, columnName string) (any, error) {
700702
statement := row[columnName]
701-
obfuscated, err := obfuscateSQL(statement)
703+
obfuscated, err := s.obfuscator.obfuscateSQLString(statement)
702704
if err != nil {
703705
s.logger.Error(fmt.Sprintf("failed to obfuscate SQL statement: %v", statement))
704706
return "", nil
@@ -731,7 +733,9 @@ func (s *sqlServerScraperHelper) recordDatabaseQueryTextAndPlan(ctx context.Cont
731733
physicalReadsVal = int64(0)
732734
}
733735

734-
queryPlanVal := s.retrieveValue(row, queryPlan, &errs, func(row sqlquery.StringMap, columnName string) (any, error) { return obfuscateXMLPlan(row[columnName]) })
736+
queryPlanVal := s.retrieveValue(row, queryPlan, &errs, func(row sqlquery.StringMap, columnName string) (any, error) {
737+
return s.obfuscator.obfuscateXMLPlan(row[columnName])
738+
})
735739

736740
rowsReturnedVal := s.retrieveValue(row, rowsReturned, &errs, retrieveInt)
737741
cached, rowsReturnedVal = s.cacheAndDiff(queryHashVal, queryPlanHashVal, rowsReturned, rowsReturnedVal.(int64))
@@ -994,7 +998,7 @@ func (s *sqlServerScraperHelper) recordDatabaseSampleQuery(ctx context.Context)
994998
dbNamespaceVal := row[dbName]
995999
queryTextVal := s.retrieveValue(row, statementText, &errs, func(row sqlquery.StringMap, columnName string) (any, error) {
9961000
statement := row[columnName]
997-
obfuscated, err := obfuscateSQL(statement)
1001+
obfuscated, err := s.obfuscator.obfuscateSQLString(statement)
9981002
if err != nil {
9991003
s.logger.Error(fmt.Sprintf("failed to obfuscate SQL statement: %v", statement))
10001004
return "", nil

0 commit comments

Comments
 (0)