diff --git a/CHANGELOG.md b/CHANGELOG.md index f252ee533..69e5f9c26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1187](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1187)) - SQLCommenter semicolon bug fix ([#1200](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1200/files)) +- Adding sqlalchemy native tags in sqlalchemy commenter + ([#1206](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1206)) - Add psycopg2 native tags to sqlcommenter ([#1203](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1203)) diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py index bc438c609..e56485ca7 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/__init__.py @@ -22,6 +22,49 @@ instrumentation via the following code: .. _sqlalchemy: https://pypi.org/project/sqlalchemy/ +SQLCOMMENTER +**************************************** +You can optionally configure SQLAlchemy instrumentation to enable sqlcommenter which enriches +the query with contextual information. + +Usage +----- + +.. code:: python + + from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor + + SQLAlchemyInstrumentor().instrument(enable_commenter=True, commenter_options={}) + + +For example, +:: + + Invoking engine.execute("select * from auth_users") will lead to sql query "select * from auth_users" but when SQLCommenter is enabled + the query will get appended with some configurable tags like "select * from auth_users /*tag=value*/;" + +SQLCommenter Configurations +*************************** +We can configure the tags to be appended to the sqlquery log by adding configuration inside commenter_options(default:{}) keyword + +db_driver = True(Default) or False + +For example, +:: +Enabling this flag will add any underlying driver like psycopg2 /*db_driver='psycopg2'*/ + +db_framework = True(Default) or False + +For example, +:: +Enabling this flag will add db_framework and it's version /*db_framework='sqlalchemy:0.41b0'*/ + +opentelemetry_values = True(Default) or False + +For example, +:: +Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/ + Usage ----- .. code:: python @@ -115,6 +158,7 @@ class SQLAlchemyInstrumentor(BaseInstrumentor): _get_tracer(tracer_provider), kwargs.get("engine"), kwargs.get("enable_commenter", False), + kwargs.get("commenter_options", {}), ) if kwargs.get("engines") is not None and isinstance( kwargs.get("engines"), Sequence @@ -124,6 +168,7 @@ class SQLAlchemyInstrumentor(BaseInstrumentor): _get_tracer(tracer_provider), engine, kwargs.get("enable_commenter", False), + kwargs.get("commenter_options", {}), ) for engine in kwargs.get("engines") ] diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py index 25e8791dc..7441c0aa0 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py @@ -94,11 +94,14 @@ def _wrap_connect(tracer_provider=None): class EngineTracer: - def __init__(self, tracer, engine, enable_commenter=False): + def __init__( + self, tracer, engine, enable_commenter=True, commenter_options=None + ): self.tracer = tracer self.engine = engine self.vendor = _normalize_vendor(engine.name) self.enable_commenter = enable_commenter + self.commenter_options = commenter_options if commenter_options else {} listen( engine, "before_cursor_execute", self._before_cur_exec, retval=True @@ -141,8 +144,22 @@ class EngineTracer: for key, value in attrs.items(): span.set_attribute(key, value) if self.enable_commenter: - commenter_data = {} - commenter_data.update(_get_opentelemetry_values()) + commenter_data = dict( + db_driver=conn.engine.driver, + # Driver/framework centric information. + db_framework=f"sqlalchemy:{__version__}", + ) + + if self.commenter_options.get("opentelemetry_values", True): + commenter_data.update(**_get_opentelemetry_values()) + + # Filter down to just the requested attributes. + commenter_data = { + k: v + for k, v in commenter_data.items() + if self.commenter_options.get(k, True) + } + statement = _add_sql_comment(statement, **commenter_data) context._otel_span = span diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py index 8245d990f..616388f5e 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py @@ -46,10 +46,11 @@ class TestSqlalchemyInstrumentationWithSQLCommenter(TestBase): engine=engine, tracer_provider=self.tracer_provider, enable_commenter=True, + commenter_options={"db_framework": False}, ) cnx = engine.connect() cnx.execute("SELECT 1;").fetchall() self.assertRegex( self.caplog.records[-2].getMessage(), - r"SELECT 1 /\*traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", + r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;", )