Skip to content

Commit 9311b89

Browse files
jasonmp85claude
andauthored
[SDBM-2635] postgres: include dbms=postgresql in SQL obfuscation options (DataDog#23926)
* [SDBM-2635] postgres: include dbms=postgresql in SQL obfuscation options Both statement_samples.py and statements.py construct an obfuscate_options dict from ObfuscatorOptions.model_dump() and patch in key renames (table_names, dollar_quoted_func, return_json_metadata). The dbms field was never included, so the Go obfuscator received DBMS="" instead of "postgresql". While no PostgreSQL-specific tokenizer branches exist today, explicitly setting dbms ensures parity with dbm-logs-processor and protects against future PostgreSQL-specific lexer paths being added in go-sqllexer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * [SDBM-2635] postgres: add changelog entry for dbms obfuscation option fix Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * [SDBM-2635] postgres: test that obfuscate_sql receives dbms=postgresql option Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * [SDBM-2635] postgres: strengthen obfuscation options test and fix changelog - Assert directly on _obfuscate_options attributes of both classes to unconditionally cover both code paths regardless of DB query activity - Also assert return_json_metadata=True alongside dbms=postgresql - Fix changelog entry missing trailing period Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * [SDBM-2635] postgres: fix line length in test_obfuscate_sql_options Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3cc9ebc commit 9311b89

4 files changed

Lines changed: 35 additions & 0 deletions

File tree

postgres/changelog.d/23926.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Set dbms=postgresql in obfuscation options to align query_signature with dbm-logs-processor.

postgres/datadog_checks/postgres/statement_samples.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ def __init__(self, check: PostgreSql, config: InstanceConfig):
176176
obfuscate_options['table_names'] = self._config.obfuscator_options.collect_tables
177177
obfuscate_options['dollar_quoted_func'] = self._config.obfuscator_options.keep_dollar_quoted_func
178178
obfuscate_options['return_json_metadata'] = self._config.obfuscator_options.collect_metadata
179+
obfuscate_options['dbms'] = 'postgresql'
179180
self._obfuscate_options = to_native_string(json.dumps(obfuscate_options))
180181

181182
self._collect_raw_query_statement = config.collect_raw_query_statement.enabled

postgres/datadog_checks/postgres/statements.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ def __init__(self, check, config: InstanceConfig):
195195
obfuscate_options['table_names'] = self._config.obfuscator_options.collect_tables
196196
obfuscate_options['dollar_quoted_func'] = self._config.obfuscator_options.keep_dollar_quoted_func
197197
obfuscate_options['return_json_metadata'] = self._config.obfuscator_options.collect_metadata
198+
obfuscate_options['dbms'] = 'postgresql'
198199
self._obfuscate_options = to_native_string(json.dumps(obfuscate_options))
199200
# full_statement_text_cache: limit the ingestion rate of full statement text events per query_signature
200201
self._full_statement_text_cache = TTLCache(

postgres/tests/test_statements.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,38 @@ def obfuscate_sql(query, options=None):
415415
assert row['calls'] == 2
416416

417417

418+
def test_obfuscate_sql_options(aggregator, integration_check, dbm_instance, datadog_agent):
419+
"""Verify obfuscate_sql is called with dbms=postgresql for both metrics and samples."""
420+
dbm_instance['collect_schemas'] = {'enabled': False}
421+
422+
check = integration_check(dbm_instance)
423+
check._connect()
424+
425+
# Unconditionally verify both classes have the correct options set at init time,
426+
# independent of whether the DB produces any queries to obfuscate.
427+
for name, obj in [('statement_metrics', check.statement_metrics), ('statement_samples', check.statement_samples)]:
428+
opts = json.loads(obj._obfuscate_options)
429+
assert opts.get('dbms') == 'postgresql', f"{name}: missing dbms=postgresql in obfuscation options"
430+
assert opts.get('return_json_metadata') is True, (
431+
f"{name}: missing return_json_metadata=True in obfuscation options"
432+
)
433+
434+
captured_options = []
435+
436+
def obfuscate_sql(query, options=None):
437+
if options is not None:
438+
captured_options.append(json.loads(options))
439+
return json.dumps({'query': query, 'metadata': {}})
440+
441+
with mock.patch.object(datadog_agent, 'obfuscate_sql', passthrough=True) as mock_agent:
442+
mock_agent.side_effect = obfuscate_sql
443+
run_one_check(check, cancel=False)
444+
445+
assert captured_options, "obfuscate_sql was never called with options"
446+
for opts in captured_options:
447+
assert opts.get('dbms') == 'postgresql', f"missing dbms=postgresql in obfuscation options: {opts}"
448+
449+
418450
@pytest.fixture
419451
def bob_conn():
420452
conn = psycopg.connect(host=HOST, dbname=DB_NAME, user="bob", password="bob")

0 commit comments

Comments
 (0)