Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 26 additions & 1 deletion .github/workflows/resolve-build-deps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ jobs:
- name: Install management dependencies
run: pip install -r .builders/deps/host_dependencies.txt

- name: Ensure Docker is running
run: bash .github/actions/setup-test-target-scripts/src/ensure-docker.sh

- name: Log in to GitHub Packages
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
Expand Down Expand Up @@ -276,6 +279,7 @@ jobs:
permissions:
contents: read
id-token: write
pull-requests: read

steps:
- name: Checkout code
Expand Down Expand Up @@ -321,6 +325,27 @@ jobs:
private-key: ${{ secrets.DD_AGENT_INTEGRATIONS_BOT_PRIVATE_KEY }}
repositories: integrations-core

- name: Find triggering PR
id: find-pr
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ steps.token-generator.outputs.token }}
script: |
const { data: commit } = await github.rest.repos.getCommit({
owner: context.repo.owner,
repo: context.repo.repo,
ref: context.sha,
});
const message = commit.commit.message;
const match = message.match(/#(\d+)/);
const prs = match ? [{ number: parseInt(match[1]), html_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/pull/${match[1]}` }] : [];
if (prs.length > 0) {
const pr = prs[0];
core.setOutput('pr_ref', `[#${pr.number}](${pr.html_url})`);
} else {
core.setOutput('pr_ref', '');
}

- name: Create pull request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
with:
Expand All @@ -334,7 +359,7 @@ jobs:
body: |-
### Motivation

Direct dependencies were updated in ${{ github.sha }}.
Direct dependencies were updated in ${{ github.sha }}${{ steps.find-pr.outputs.pr_ref != '' && format(' (triggered by PR {0})', steps.find-pr.outputs.pr_ref) || '' }}.

### Additional Notes

Expand Down
1 change: 0 additions & 1 deletion postgres/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ def dd_environment(e2e_instance, skip_env):
"POSTGRES_LOCALE": POSTGRES_LOCALE,
"PGDATA": "/var/lib/postgresql/$PG_MAJOR/docker",
},
capture=True,
):
yield e2e_instance, E2E_METADATA

Expand Down
1 change: 1 addition & 0 deletions sqlserver/changelog.d/22731.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix `procedure_name` tag missing from query metrics when the `CONNECT` permission hasn't been granted to the datadog user.
6 changes: 3 additions & 3 deletions sqlserver/datadog_checks/sqlserver/statements.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,8 @@ def _normalize_queries(self, rows):
procedure_signature = None
procedure_content = None
row['is_proc'] = bool(row.get('procedure_name'))
if (row['is_proc'] and row['text']) or self.disable_secondary_tags:
has_sproc_context = row['is_proc'] or bool(row.get('sproc_object_id'))
if (has_sproc_context and row['text']) or self.disable_secondary_tags:
try:
procedure_statement = obfuscate_sql_with_metadata(
row['text'], self._config.obfuscator_options, replace_null_character=True
Expand All @@ -431,8 +432,7 @@ def _normalize_queries(self, rows):
procedure_comments = procedure_statement['metadata'].get('comments', [])
if procedure_comments:
comments = list(set(comments + procedure_comments))
if self.disable_secondary_tags and not row.get('procedure_name'):
# Extract procedure name from the statement text when disable_secondary_tags is enabled
if not row.get('procedure_name'):
procedures = procedure_statement['metadata'].get('procedures')
if procedures:
row['procedure_name'] = procedures[0].lower()
Expand Down
93 changes: 93 additions & 0 deletions sqlserver/tests/test_statements.py
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,99 @@ def test_metrics_lookback_window_config(instance_docker):
mock_cursor.execute.assert_called_with(ANY, (86400,))


@pytest.mark.unit
@pytest.mark.parametrize(
"procedure_name,sproc_object_id,expected_is_proc,expected_procedure_name",
[
pytest.param(
None,
12345,
True,
"myproc",
id="no_procedure_name_with_sproc_object_id_extracts_from_metadata",
),
pytest.param(
"myproc",
12345,
True,
"dbo.myproc",
id="procedure_name_present_with_sproc_object_id_uses_original",
),
pytest.param(
None,
None,
False,
None,
id="no_procedure_name_no_sproc_object_id_not_a_proc",
),
pytest.param(
None,
0,
False,
None,
id="no_procedure_name_zero_sproc_object_id_not_a_proc",
),
],
)
def test_normalize_queries_procedure_name_fallback(
instance_docker, datadog_agent, procedure_name, sproc_object_id, expected_is_proc, expected_procedure_name
):
"""Test that _normalize_queries extracts procedure_name from obfuscator metadata
when OBJECT_NAME() returns NULL (procedure_name is None) but sproc_object_id is set,
which happens when the monitoring user lacks CONNECT on the user database."""
instance_docker['dbm'] = True
instance_docker['query_metrics'] = {'enabled': True, 'run_sync': True, 'collection_interval': 0.1}
check = SQLServer(CHECK_NAME, {}, [instance_docker])

statement_text = "SELECT * FROM ϑings WHERE id = @P1"
procedure_text = "CREATE PROCEDURE dbo.myProc AS BEGIN SELECT * FROM ϑings WHERE id = @P1 END;"

def _obfuscate_sql(sql_query, options=None):
return json.dumps(
{
'query': sql_query,
'metadata': {
'tables_csv': 'ϑings',
'commands': ['SELECT'],
'comments': [],
'procedures': ['myProc'],
},
}
)

row = {
'statement_text': statement_text,
'text': procedure_text,
'procedure_name': procedure_name,
'schema_name': 'dbo' if procedure_name else None,
'sproc_object_id': sproc_object_id,
'query_hash': b'\x01\x02\x03\x04',
'query_plan_hash': b'\x05\x06\x07\x08',
'plan_handle': b'\x09\x0a\x0b\x0c',
'execution_count': 1,
'total_worker_time': 100,
}

with mock.patch.object(datadog_agent, 'obfuscate_sql', passthrough=True) as mock_agent:
mock_agent.side_effect = _obfuscate_sql
result = check.statement_metrics._normalize_queries([row])

assert len(result) == 1
result_row = result[0]
assert result_row['is_proc'] is expected_is_proc
if expected_procedure_name:
assert result_row['procedure_name'] == expected_procedure_name
else:
assert not result_row.get('procedure_name')

if expected_is_proc:
assert result_row.get('procedure_signature'), "should have a procedure signature"
assert result_row.get('procedure_text'), "should have obfuscated procedure text"
else:
assert not result_row.get('procedure_signature')
assert not result_row.get('procedure_text')


@pytest.mark.flaky
@pytest.mark.integration
@pytest.mark.usefixtures('dd_environment')
Expand Down
2 changes: 1 addition & 1 deletion temporal_cloud/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Overview

<div class="alert alert-warning">This legacy integration is no longer maintained. Migrate to the new <a href="https://docs.datadoghq.com/integrations/temporal-cloud-openmetrics/">Temporal Cloud OpenMetrics integration</a> for expanded metrics and improved monitoring.</div>
<div class="alert alert-info">To take advantage of expanded metrics and improved monitoring, Datadog encourages migrating to the newer <a href="https://docs.datadoghq.com/integrations/temporal-cloud-openmetrics/">Temporal Cloud OpenMetrics integration</a>.</div>

[Temporal Cloud][1] is a scalable platform for orchestrating complex workflows which enables developers to focus on building applications, without worrying about fault tolerance and consistency.

Expand Down
Loading