Skip to content

Commit a7f3568

Browse files
authored
Merge branch 'main' into mike/towncrier
2 parents f30f560 + 85a51e6 commit a7f3568

18 files changed

Lines changed: 429 additions & 95 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
136136
- `opentelemetry-instrumentation-boto`: Remove instrumentation
137137
([#4303](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4303))
138138

139+
### Added
140+
141+
- `opentelemetry-instrumentation-dbapi`: implement new semantic convention opt-in migration
142+
([#4109](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4109))
143+
139144
## Version 1.40.0/0.61b0 (2026-03-04)
140145

141146
### Added

instrumentation/README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
| [opentelemetry-instrumentation-celery](./opentelemetry-instrumentation-celery) | celery >= 4.0, < 6.0 | No | development
1818
| [opentelemetry-instrumentation-click](./opentelemetry-instrumentation-click) | click >= 8.1.3, < 9.0.0 | No | development
1919
| [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, < 3.0.0 | No | development
20-
| [opentelemetry-instrumentation-dbapi](./opentelemetry-instrumentation-dbapi) | dbapi | No | development
20+
| [opentelemetry-instrumentation-dbapi](./opentelemetry-instrumentation-dbapi) | dbapi | No | migration
2121
| [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 2.0 | Yes | development
2222
| [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | development
2323
| [opentelemetry-instrumentation-falcon](./opentelemetry-instrumentation-falcon) | falcon >= 1.4.1, < 5.0.0 | Yes | migration
@@ -28,21 +28,21 @@
2828
| [opentelemetry-instrumentation-jinja2](./opentelemetry-instrumentation-jinja2) | jinja2 >= 2.7, < 4.0 | No | development
2929
| [opentelemetry-instrumentation-kafka-python](./opentelemetry-instrumentation-kafka-python) | kafka-python >= 2.0, < 3.0,kafka-python-ng >= 2.0, < 3.0 | No | development
3030
| [opentelemetry-instrumentation-logging](./opentelemetry-instrumentation-logging) | logging | No | development
31-
| [opentelemetry-instrumentation-mysql](./opentelemetry-instrumentation-mysql) | mysql-connector-python >= 8.0, < 10.0 | No | development
32-
| [opentelemetry-instrumentation-mysqlclient](./opentelemetry-instrumentation-mysqlclient) | mysqlclient < 3 | No | development
31+
| [opentelemetry-instrumentation-mysql](./opentelemetry-instrumentation-mysql) | mysql-connector-python >= 8.0, < 10.0 | No | migration
32+
| [opentelemetry-instrumentation-mysqlclient](./opentelemetry-instrumentation-mysqlclient) | mysqlclient < 3 | No | migration
3333
| [opentelemetry-instrumentation-pika](./opentelemetry-instrumentation-pika) | pika >= 0.12.0 | No | development
34-
| [opentelemetry-instrumentation-psycopg](./opentelemetry-instrumentation-psycopg) | psycopg >= 3.1.0 | No | development
35-
| [opentelemetry-instrumentation-psycopg2](./opentelemetry-instrumentation-psycopg2) | psycopg2 >= 2.7.3.1,psycopg2-binary >= 2.7.3.1 | No | development
34+
| [opentelemetry-instrumentation-psycopg](./opentelemetry-instrumentation-psycopg) | psycopg >= 3.1.0 | No | migration
35+
| [opentelemetry-instrumentation-psycopg2](./opentelemetry-instrumentation-psycopg2) | psycopg2 >= 2.7.3.1,psycopg2-binary >= 2.7.3.1 | No | migration
3636
| [opentelemetry-instrumentation-pymemcache](./opentelemetry-instrumentation-pymemcache) | pymemcache >= 1.3.5, < 5 | No | development
3737
| [opentelemetry-instrumentation-pymongo](./opentelemetry-instrumentation-pymongo) | pymongo >= 3.1, < 5.0 | No | development
38-
| [opentelemetry-instrumentation-pymssql](./opentelemetry-instrumentation-pymssql) | pymssql >= 2.1.5, < 3 | No | development
39-
| [opentelemetry-instrumentation-pymysql](./opentelemetry-instrumentation-pymysql) | PyMySQL < 2 | No | development
38+
| [opentelemetry-instrumentation-pymssql](./opentelemetry-instrumentation-pymssql) | pymssql >= 2.1.5, < 3 | No | migration
39+
| [opentelemetry-instrumentation-pymysql](./opentelemetry-instrumentation-pymysql) | PyMySQL < 2 | No | migration
4040
| [opentelemetry-instrumentation-pyramid](./opentelemetry-instrumentation-pyramid) | pyramid >= 1.7 | Yes | migration
4141
| [opentelemetry-instrumentation-redis](./opentelemetry-instrumentation-redis) | redis >= 2.6 | No | migration
4242
| [opentelemetry-instrumentation-remoulade](./opentelemetry-instrumentation-remoulade) | remoulade >= 0.50 | No | development
4343
| [opentelemetry-instrumentation-requests](./opentelemetry-instrumentation-requests) | requests ~= 2.0 | Yes | migration
4444
| [opentelemetry-instrumentation-sqlalchemy](./opentelemetry-instrumentation-sqlalchemy) | sqlalchemy >= 1.0.0, < 2.1.0 | Yes | migration
45-
| [opentelemetry-instrumentation-sqlite3](./opentelemetry-instrumentation-sqlite3) | sqlite3 | No | development
45+
| [opentelemetry-instrumentation-sqlite3](./opentelemetry-instrumentation-sqlite3) | sqlite3 | No | migration
4646
| [opentelemetry-instrumentation-starlette](./opentelemetry-instrumentation-starlette) | starlette >= 0.13 | Yes | development
4747
| [opentelemetry-instrumentation-system-metrics](./opentelemetry-instrumentation-system-metrics) | psutil >= 5 | No | development
4848
| [opentelemetry-instrumentation-threading](./opentelemetry-instrumentation-threading) | threading | No | development

instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@
128128
SQLComment in span attribute
129129
****************************
130130
If sqlcommenter is enabled, you can opt into the inclusion of sqlcomment in
131-
the query span ``db.statement`` attribute for your needs. If ``commenter_options``
132-
have been set, the span attribute comment will also be configured by this
133-
setting.
131+
the query span ``db.statement`` and/or ``db.query.text`` attribute for your
132+
needs. If ``commenter_options`` have been set, the span attribute comment
133+
will also be configured by this setting.
134134
135135
.. code:: python
136136
@@ -140,7 +140,7 @@
140140
141141
142142
# Opts into sqlcomment for MySQL trace integration.
143-
# Opts into sqlcomment for `db.statement` span attribute.
143+
# Opts into sqlcomment for `db.statement` and/or `db.query.text` span attribute.
144144
wrap_connect(
145145
__name__,
146146
mysql.connector,
@@ -175,23 +175,24 @@
175175
from wrapt import ObjectProxy as BaseObjectProxy
176176

177177
from opentelemetry import trace as trace_api
178+
from opentelemetry.instrumentation._semconv import (
179+
_get_schema_url_for_signal_types,
180+
_OpenTelemetrySemanticConventionStability,
181+
_OpenTelemetryStabilitySignalType,
182+
_set_db_name,
183+
_set_db_statement,
184+
_set_db_system,
185+
_set_db_user,
186+
_set_http_net_peer_name_client,
187+
_set_http_peer_port_client,
188+
)
178189
from opentelemetry.instrumentation.dbapi.version import __version__
179190
from opentelemetry.instrumentation.sqlcommenter_utils import _add_sql_comment
180191
from opentelemetry.instrumentation.utils import (
181192
_get_opentelemetry_values,
182193
is_instrumentation_enabled,
183194
unwrap,
184195
)
185-
from opentelemetry.semconv._incubating.attributes.db_attributes import (
186-
DB_NAME,
187-
DB_STATEMENT,
188-
DB_SYSTEM,
189-
DB_USER,
190-
)
191-
from opentelemetry.semconv._incubating.attributes.net_attributes import (
192-
NET_PEER_NAME,
193-
NET_PEER_PORT,
194-
)
195196
from opentelemetry.trace import SpanKind, TracerProvider, get_tracer
196197
from opentelemetry.util._importlib_metadata import version as util_version
197198

@@ -233,7 +234,7 @@ def trace_integration(
233234
enable_commenter: Flag to enable/disable sqlcommenter.
234235
db_api_integration_factory: The `DatabaseApiIntegration` to use. If none is passed the
235236
default one is used.
236-
enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` span attribute. Only available if enable_commenter=True.
237+
enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` and/or `db.query.text` span attribute. Only available if enable_commenter=True.
237238
commenter_options: Configurations for tags to be appended at the sql query.
238239
"""
239240
wrap_connect(
@@ -283,7 +284,7 @@ def wrap_connect(
283284
db_api_integration_factory: The `DatabaseApiIntegration` to use. If none is passed the
284285
default one is used.
285286
commenter_options: Configurations for tags to be appended at the sql query.
286-
enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` span attribute. Only available if enable_commenter=True.
287+
enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` and/or `db.query.text` span attribute. Only available if enable_commenter=True.
287288
288289
"""
289290
db_api_integration_factory = (
@@ -361,7 +362,7 @@ def instrument_connection(
361362
enable_commenter: Flag to enable/disable sqlcommenter.
362363
commenter_options: Configurations for tags to be appended at the sql query.
363364
connect_module: Module name where connect method is available.
364-
enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` span attribute. Only available if enable_commenter=True.
365+
enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` and/or `db.query.text` span attribute. Only available if enable_commenter=True.
365366
db_api_integration_factory: A class or factory function to use as a
366367
replacement for :class:`DatabaseApiIntegration`. Can be used to
367368
obtain connection attributes from the connect method instead of
@@ -426,6 +427,15 @@ def __init__(
426427
connect_module: Callable[..., Any] | None = None,
427428
enable_attribute_commenter: bool = False,
428429
):
430+
# Initialize semantic conventions opt-in if needed
431+
_OpenTelemetrySemanticConventionStability._initialize()
432+
self._sem_conv_opt_in_mode_db = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
433+
_OpenTelemetryStabilitySignalType.DATABASE,
434+
)
435+
self._sem_conv_opt_in_mode_http = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
436+
_OpenTelemetryStabilitySignalType.HTTP,
437+
)
438+
429439
if connection_attributes is None:
430440
self.connection_attributes = {
431441
"database": "database",
@@ -441,7 +451,12 @@ def __init__(
441451
self._name,
442452
instrumenting_library_version=self._version,
443453
tracer_provider=tracer_provider,
444-
schema_url="https://opentelemetry.io/schemas/1.11.0",
454+
schema_url=_get_schema_url_for_signal_types(
455+
[
456+
_OpenTelemetryStabilitySignalType.DATABASE,
457+
_OpenTelemetryStabilitySignalType.HTTP,
458+
]
459+
),
445460
)
446461
self.capture_parameters = capture_parameters
447462
self.enable_commenter = enable_commenter
@@ -554,13 +569,21 @@ def get_connection_attributes(self, connection: object) -> None:
554569
if user and isinstance(user, bytes):
555570
user = user.decode()
556571
if user is not None:
557-
self.span_attributes[DB_USER] = str(user)
572+
_set_db_user(
573+
self.span_attributes, str(user), self._sem_conv_opt_in_mode_db
574+
)
558575
host = self.connection_props.get("host")
559576
if host is not None:
560-
self.span_attributes[NET_PEER_NAME] = host
577+
_set_http_net_peer_name_client(
578+
self.span_attributes,
579+
host,
580+
self._sem_conv_opt_in_mode_http,
581+
)
561582
port = self.connection_props.get("port")
562583
if port is not None:
563-
self.span_attributes[NET_PEER_PORT] = port
584+
_set_http_peer_port_client(
585+
self.span_attributes, port, self._sem_conv_opt_in_mode_http
586+
)
564587

565588

566589
# pylint: disable=abstract-method,no-member
@@ -688,9 +711,23 @@ def _populate_span(
688711
if not span.is_recording():
689712
return
690713
statement = self.get_statement(cursor, args)
691-
span.set_attribute(DB_SYSTEM, self._db_api_integration.database_system)
692-
span.set_attribute(DB_NAME, self._db_api_integration.database)
693-
span.set_attribute(DB_STATEMENT, statement)
714+
sem_conv_mode = self._db_api_integration._sem_conv_opt_in_mode_db
715+
span_attrs = {}
716+
717+
_set_db_system(
718+
span_attrs,
719+
self._db_api_integration.database_system,
720+
sem_conv_mode,
721+
)
722+
_set_db_name(
723+
span_attrs,
724+
self._db_api_integration.database,
725+
sem_conv_mode,
726+
)
727+
_set_db_statement(span_attrs, statement, sem_conv_mode)
728+
729+
# Set all collected attributes
730+
span.set_attributes(span_attrs)
694731

695732
for (
696733
attribute_key,
@@ -741,14 +778,14 @@ def traced_execution(
741778
if span.is_recording():
742779
if args and self._commenter_enabled:
743780
if self._enable_attribute_commenter:
744-
# sqlcomment is added to executed query and db.statement span attribute
781+
# sqlcomment is added to executed query and db.statement and/or db.query.text span attribute
745782
args = self._update_args_with_added_sql_comment(
746783
args, cursor
747784
)
748785
self._populate_span(span, cursor, *args)
749786
else:
750787
# sqlcomment is only added to executed query
751-
# so db.statement is set before add_sql_comment
788+
# so db.statement and/or db.query.text are set before add_sql_comment
752789
self._populate_span(span, cursor, *args)
753790
args = self._update_args_with_added_sql_comment(
754791
args, cursor
@@ -779,14 +816,14 @@ async def traced_execution_async(
779816
if span.is_recording():
780817
if args and self._commenter_enabled:
781818
if self._enable_attribute_commenter:
782-
# sqlcomment is added to executed query and db.statement span attribute
819+
# sqlcomment is added to executed query and db.statement and/or db.query.text span attribute
783820
args = self._update_args_with_added_sql_comment(
784821
args, cursor
785822
)
786823
self._populate_span(span, cursor, *args)
787824
else:
788825
# sqlcomment is only added to executed query
789-
# so db.statement is set before add_sql_comment
826+
# so db.statement and/or db.query.text are set before add_sql_comment
790827
self._populate_span(span, cursor, *args)
791828
args = self._update_args_with_added_sql_comment(
792829
args, cursor

instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/package.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33

44

55
_instruments = tuple()
6+
7+
_semconv_status = "migration"

0 commit comments

Comments
 (0)