Skip to content

feat(otel): system-tests for DB (postgres) OpenTelemetry semantic conventions#7166

Draft
khanayan123 wants to merge 4 commits into
ayan.khan/otel-http-semantics-system-testsfrom
ayan.khan/otel-db-semantics-system-tests
Draft

feat(otel): system-tests for DB (postgres) OpenTelemetry semantic conventions#7166
khanayan123 wants to merge 4 commits into
ayan.khan/otel-http-semantics-system-testsfrom
ayan.khan/otel-db-semantics-system-tests

Conversation

@khanayan123

@khanayan123 khanayan123 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

What

The database extension of the HTTP OTel-semantics work (#7139) — system-tests asserting that postgres SQL spans honor the OpenTelemetry database semantic conventions when DD_TRACE_OTEL_SEMANTICS_ENABLED=true.

Spec: https://opentelemetry.io/docs/specs/semconv/db/database-spans/

Stacked on #7139 (ayan.khan/otel-http-semantics-system-tests) — this PR shows only the DB diff. Rebase onto main once the HTTP PR merges.

Changes

  • OTEL_SEMANTICS_DB scenario — postgres container + DD_TRACE_OTEL_SEMANTICS_ENABLED=true.
  • tests/integrations/test_otel_db_semantics.pyTest_PostgresOtelSemantics, reusing the proven BaseDbIntegrationsTestClass / /db / sql-span pattern. 7 tests covering every Datadog→OTel rename in the spec.

Renamed-attribute coverage (Datadog → OTel)

Datadog OTel Level
db.type / db.system db.system.name ("postgresql") Required
db.name / db.instance db.namespace (database) Cond.
db.operation db.operation.name Cond.
db.statement db.query.text Recommended
db.sql.table db.collection.name Cond.
out.host server.address Recommended
out.port server.port (int) Cond.

Each test asserts the OTel name is present/correct and the legacy Datadog name is absent (mutually exclusive, as for HTTP).

Why rename-tests only

The scenario is gated missing_feature everywhere (no tracer implements DB OTel yet), so a test must fail when the feature is off to xfail correctly. Rename tests do (the OTel name is absent / the legacy name is present). Unchanged/shared attributes (span.kind=client, error.type) would pass regardless → xpass, so they aren't in this gated class; they belong to the OTLP-typed variant / when-active coverage.

Status: forward-looking spec contract

No tracer implements DB OTel semantics yetDD_TRACE_OTEL_SEMANTICS_ENABLED covers HTTP only (confirmed in dd-trace-dotnet#8791 / dd-trace-java#11652 / dd-trace-js#8933; dotnet has DB test scaffolding but its production flag gates HTTP only). So the tests encode the target contract, gated missing_feature for every language, and activate per-tracer as DB support lands. Not e2e-verified until then (unlike the HTTP work, validated against dd-trace-js#8933).

Open question for the tracer teams

db.system.name (stable spec) vs db.system (experimental/Datadog; existing DD tests already assert db.system == "postgresql"). Asserted the stable name per the authoritative-harness principle, with db.system asserted absent — to be reconciled with whatever the tracers emit.

Follow-ups

  • OTLP-typed DB variant (like OTEL_SEMANTICS_OTLP) — asserts the integer types (server.port, db.response.status_code, db.operation.batch.size) the agent protocol can't represent, plus the unchanged/shared attributes.
  • db.query.text sanitization (literals → ?), db.query.summary, network.peer.*, and the DB span-name rule ({db.operation.name} {target}, low-cardinality).

Verification

  • ruff clean; Manifest.validate() (format + key-order + nodeid existence) passes; test_the_test meta-tests pass; 7 tests collect under OTEL_SEMANTICS_DB.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

CODEOWNERS have been resolved as:

tests/integrations/test_otel_db_semantics.py                            @DataDog/system-tests-core
manifests/dotnet.yml                                                    @DataDog/apm-dotnet @DataDog/asm-dotnet
manifests/golang.yml                                                    @DataDog/dd-trace-go-guild
manifests/java.yml                                                      @DataDog/asm-java @DataDog/apm-java
manifests/php.yml                                                       @DataDog/apm-php @DataDog/asm-php
manifests/python.yml                                                    @DataDog/apm-python @DataDog/asm-python
manifests/ruby.yml                                                      @DataDog/ruby-guild @DataDog/asm-ruby
manifests/rust.yml                                                      @DataDog/apm-rust
utils/_context/_scenarios/__init__.py                                   @DataDog/system-tests-core
utils/_context/_scenarios/integrations.py                               @DataDog/system-tests-core

@datadog-prod-us1-5

datadog-prod-us1-5 Bot commented Jun 17, 2026

Copy link
Copy Markdown

Pipelines  Tests

Fix all issues with BitsAI

⚠️ Warnings

🚦 4 Pipeline jobs failed

DataDog/system-tests | ruby-app-deployment-mode.amd64.DOA9: [public.ecr.aws/lts/ubuntu:22.04, linux/amd64, 3.1.7]   View in Datadog   GitLab

DataDog/system-tests | ruby-app-deployment-mode.arm64.DOA9: [public.ecr.aws/lts/ubuntu:22.04, linux/arm64, 3.1.7]   View in Datadog   GitLab

DataDog/system-tests | ruby-app-deployment-mode.arm64.DOC: [public.ecr.aws/lts/ubuntu:22.04, linux/arm64, 3.1.7]   View in Datadog   GitLab

View all 4 failed jobs.

🧪 1 Test failed in 1 job

Testing the test | main   GitHub Actions

tests.debugger.test_debugger_symdb.Test_Debugger_SymDb.test_symdb_upload[chi] from system_tests_suite   View in Datadog
AssertionError: No symbol files were found
assert 0 > 0
 +  where 0 = len([])
 +    where [] = <tests.debugger.test_debugger_symdb.Test_Debugger_SymDb object at 0x7fd4100eda90>.symbols

self = <tests.debugger.test_debugger_symdb.Test_Debugger_SymDb object at 0x7fd4100eda90>

    def test_symdb_upload(self):
>       self._assert()

...

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: f91efe9 | Docs | Datadog PR Page | Give us feedback!

khanayan123 and others added 4 commits June 17, 2026 13:40
…vention tests

The database counterpart to the HTTP OTel-semantics work. Adds an OTEL_SEMANTICS_DB
scenario (postgres container + DD_TRACE_OTEL_SEMANTICS_ENABLED=true) and
tests/integrations/test_otel_db_semantics.py asserting that postgres SQL spans emit the
OpenTelemetry database semantic-convention attribute names instead of the Datadog ones:

  db.type/db.system -> db.system.name (= "postgresql")
  db.name/db.instance -> db.namespace
  db.operation -> db.operation.name
  db.statement -> db.query.text
  out.host -> server.address

Reuses the proven BaseDbIntegrationsTestClass / /db endpoint / sql-span pattern.

No tracer implements DB OTel semantics yet (DD_TRACE_OTEL_SEMANTICS_ENABLED currently
covers HTTP only — confirmed in dd-trace-dotnet#8791/java#11652/js#8933), so the tests are
gated missing_feature for every language. They encode the target contract and activate
per-tracer as DB support lands; not e2e-verifiable until then.

Open question (asserted to the stable spec for now): the stable spec name is
`db.system.name`, but the experimental/Datadog name is `db.system` — flagged for the
tracer teams.

Spec: https://opentelemetry.io/docs/specs/semconv/db/database-spans/

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lection.name, server.port)

Add the two remaining renamed-attribute tests so the DB suite covers the full set of
Datadog->OTel renames per the spec:
  db.sql.table -> db.collection.name
  out.port     -> server.port (validated as int when present)

The suite now has 7 rename tests (db.system.name, db.namespace, db.operation.name,
db.query.text, db.collection.name, server.address, server.port). Only rename tests are
included because the scenario is gated missing_feature everywhere (no tracer implements DB
OTel yet) — unchanged/shared attributes like span.kind and error.type would xpass, so they
belong in the OTLP-typed variant / when-active coverage instead.

ruff + Manifest.validate() + meta-tests green; 7 tests collect under OTEL_SEMANTICS_DB.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…or-metrics)

Running OTEL_SEMANTICS_DB against dd-trace-js master revealed test_server_port xpassed:
the previous version only checked `out.port` absent, but dd-trace-js puts the port in
`metrics[network.destination.port]` (=5433), so "out.port absent" was trivially true and
the test passed even though no OTel rename occurred.

Fix: require server.port present (the postgres port is non-default, so the spec expects it),
read it from meta OR metrics, and assert both legacy port names (out.port,
network.destination.port) are absent. Now all 7 rename tests xfail correctly when the
feature is unimplemented.

Finding: dd-trace-js master does NOT implement OTel DB semantics — its postgres SQL span
emits Datadog names (db.name, db.type=postgres, out.host, network.destination.port) and none
of the OTel names. Confirms the suite's all-gated (missing_feature) status.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dd-trace-js#8961 (stacked on the HTTP semantics PR) implements DB OTel
semantic conventions, so Test_PostgresOtelSemantics now passes for nodejs.
Drop the missing_feature gate.

Verified by replay against the tracer build: OTEL_SEMANTICS_DB 9 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@khanayan123 khanayan123 force-pushed the ayan.khan/otel-db-semantics-system-tests branch from 13dd2ee to f91efe9 Compare June 17, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant