Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding sqlalchemy native tags in sqlalchemy commenter #1206

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,49 @@

.. _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
Expand Down Expand Up @@ -115,6 +158,7 @@ def _instrument(self, **kwargs):
_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
Expand All @@ -124,6 +168,7 @@ def _instrument(self, **kwargs):
_get_tracer(tracer_provider),
engine,
kwargs.get("enable_commenter", False),
kwargs.get("commenter_options", {}),
)
for engine in kwargs.get("engines")
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,14 @@ def _wrap_connect_internal(func, module, args, kwargs):


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
Expand Down Expand Up @@ -141,8 +144,22 @@ def _before_cur_exec(
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ def test_sqlcommenter_enabled(self):
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}'\*/;",
)