Skip to content

Commit 14077a9

Browse files
authored
Adding sqlalchemy native tags in sqlalchemy commenter (#1206)
1 parent 04f4fe5 commit 14077a9

File tree

4 files changed

+69
-4
lines changed

4 files changed

+69
-4
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
([#1187](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1187))
1111
- SQLCommenter semicolon bug fix
1212
([#1200](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1200/files))
13+
- Adding sqlalchemy native tags in sqlalchemy commenter
14+
([#1206](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1206))
1315
- Add psycopg2 native tags to sqlcommenter
1416
([#1203](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1203))
1517

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

+45
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,49 @@
2222
2323
.. _sqlalchemy: https://pypi.org/project/sqlalchemy/
2424
25+
SQLCOMMENTER
26+
****************************************
27+
You can optionally configure SQLAlchemy instrumentation to enable sqlcommenter which enriches
28+
the query with contextual information.
29+
30+
Usage
31+
-----
32+
33+
.. code:: python
34+
35+
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
36+
37+
SQLAlchemyInstrumentor().instrument(enable_commenter=True, commenter_options={})
38+
39+
40+
For example,
41+
::
42+
43+
Invoking engine.execute("select * from auth_users") will lead to sql query "select * from auth_users" but when SQLCommenter is enabled
44+
the query will get appended with some configurable tags like "select * from auth_users /*tag=value*/;"
45+
46+
SQLCommenter Configurations
47+
***************************
48+
We can configure the tags to be appended to the sqlquery log by adding configuration inside commenter_options(default:{}) keyword
49+
50+
db_driver = True(Default) or False
51+
52+
For example,
53+
::
54+
Enabling this flag will add any underlying driver like psycopg2 /*db_driver='psycopg2'*/
55+
56+
db_framework = True(Default) or False
57+
58+
For example,
59+
::
60+
Enabling this flag will add db_framework and it's version /*db_framework='sqlalchemy:0.41b0'*/
61+
62+
opentelemetry_values = True(Default) or False
63+
64+
For example,
65+
::
66+
Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/
67+
2568
Usage
2669
-----
2770
.. code:: python
@@ -115,6 +158,7 @@ def _instrument(self, **kwargs):
115158
_get_tracer(tracer_provider),
116159
kwargs.get("engine"),
117160
kwargs.get("enable_commenter", False),
161+
kwargs.get("commenter_options", {}),
118162
)
119163
if kwargs.get("engines") is not None and isinstance(
120164
kwargs.get("engines"), Sequence
@@ -124,6 +168,7 @@ def _instrument(self, **kwargs):
124168
_get_tracer(tracer_provider),
125169
engine,
126170
kwargs.get("enable_commenter", False),
171+
kwargs.get("commenter_options", {}),
127172
)
128173
for engine in kwargs.get("engines")
129174
]

instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py

+20-3
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,14 @@ def _wrap_connect_internal(func, module, args, kwargs):
9494

9595

9696
class EngineTracer:
97-
def __init__(self, tracer, engine, enable_commenter=False):
97+
def __init__(
98+
self, tracer, engine, enable_commenter=True, commenter_options=None
99+
):
98100
self.tracer = tracer
99101
self.engine = engine
100102
self.vendor = _normalize_vendor(engine.name)
101103
self.enable_commenter = enable_commenter
104+
self.commenter_options = commenter_options if commenter_options else {}
102105

103106
listen(
104107
engine, "before_cursor_execute", self._before_cur_exec, retval=True
@@ -141,8 +144,22 @@ def _before_cur_exec(
141144
for key, value in attrs.items():
142145
span.set_attribute(key, value)
143146
if self.enable_commenter:
144-
commenter_data = {}
145-
commenter_data.update(_get_opentelemetry_values())
147+
commenter_data = dict(
148+
db_driver=conn.engine.driver,
149+
# Driver/framework centric information.
150+
db_framework=f"sqlalchemy:{__version__}",
151+
)
152+
153+
if self.commenter_options.get("opentelemetry_values", True):
154+
commenter_data.update(**_get_opentelemetry_values())
155+
156+
# Filter down to just the requested attributes.
157+
commenter_data = {
158+
k: v
159+
for k, v in commenter_data.items()
160+
if self.commenter_options.get(k, True)
161+
}
162+
146163
statement = _add_sql_comment(statement, **commenter_data)
147164

148165
context._otel_span = span

instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlcommenter.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@ def test_sqlcommenter_enabled(self):
4646
engine=engine,
4747
tracer_provider=self.tracer_provider,
4848
enable_commenter=True,
49+
commenter_options={"db_framework": False},
4950
)
5051
cnx = engine.connect()
5152
cnx.execute("SELECT 1;").fetchall()
5253
self.assertRegex(
5354
self.caplog.records[-2].getMessage(),
54-
r"SELECT 1 /\*traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;",
55+
r"SELECT 1 /\*db_driver='(.*)',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;",
5556
)

0 commit comments

Comments
 (0)