Skip to content

Commit f52c88b

Browse files
authored
Merge pull request #195 from lonewolf3739/dbapi-semantic-conv
2 parents aaa1928 + 184f786 commit f52c88b

File tree

13 files changed

+182
-160
lines changed

13 files changed

+182
-160
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var
1616
sdist
1717
develop-eggs
1818
.installed.cfg
19+
pyvenv.cfg
1920
lib
2021
lib64
2122
__pycache__

instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,16 @@ async def traced_execution(
101101
*args: typing.Tuple[typing.Any, typing.Any],
102102
**kwargs: typing.Dict[typing.Any, typing.Any]
103103
):
104+
name = ""
105+
if len(args) > 0 and args[0]:
106+
name = args[0]
107+
elif self._db_api_integration.database:
108+
name = self._db_api_integration.database
109+
else:
110+
name = self._db_api_integration.name
104111

105112
with self._db_api_integration.get_tracer().start_as_current_span(
106-
self._db_api_integration.name, kind=SpanKind.CLIENT
113+
name, kind=SpanKind.CLIENT
107114
) as span:
108115
self._populate_span(span, *args)
109116
try:

instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,12 @@ def test_span_succeeded(self):
215215
spans_list = self.memory_exporter.get_finished_spans()
216216
self.assertEqual(len(spans_list), 1)
217217
span = spans_list[0]
218-
self.assertEqual(span.name, "testcomponent.testdatabase")
218+
self.assertEqual(span.name, "Test query")
219219
self.assertIs(span.kind, trace_api.SpanKind.CLIENT)
220220

221221
self.assertEqual(span.attributes["component"], "testcomponent")
222-
self.assertEqual(span.attributes["db.type"], "testtype")
223-
self.assertEqual(span.attributes["db.instance"], "testdatabase")
222+
self.assertEqual(span.attributes["db.system"], "testcomponent")
223+
self.assertEqual(span.attributes["db.name"], "testdatabase")
224224
self.assertEqual(span.attributes["db.statement"], "Test query")
225225
self.assertEqual(
226226
span.attributes["db.statement.parameters"],
@@ -230,7 +230,7 @@ def test_span_succeeded(self):
230230
self.assertEqual(span.attributes["net.peer.name"], "testhost")
231231
self.assertEqual(span.attributes["net.peer.port"], 123)
232232
self.assertIs(
233-
span.status.status_code, trace_api.status.StatusCode.UNSET,
233+
span.status.status_code, trace_api.status.StatusCode.UNSET
234234
)
235235

236236
def test_span_not_recording(self):
@@ -281,7 +281,7 @@ def test_span_failed(self):
281281
span = spans_list[0]
282282
self.assertEqual(span.attributes["db.statement"], "Test query")
283283
self.assertIs(
284-
span.status.status_code, trace_api.status.StatusCode.ERROR,
284+
span.status.status_code, trace_api.status.StatusCode.ERROR
285285
)
286286
self.assertEqual(span.status.description, "Test Exception")
287287

instrumentation/opentelemetry-instrumentation-dbapi/CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
## Unreleased
44

5-
Stop capturing query parameters by default
5+
- Update dbapi and its dependant instrumentations to follow semantic conventions
6+
([#195](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/195))
7+
8+
- Stop capturing query parameters by default
69
([#156](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/156))
710

811
## Version 0.13b0

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

+46-35
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,19 @@ def trace_integration(
6262
capture_parameters: bool = False,
6363
):
6464
"""Integrate with DB API library.
65-
https://www.python.org/dev/peps/pep-0249/
66-
67-
Args:
68-
connect_module: Module name where connect method is available.
69-
connect_method_name: The connect method name.
70-
database_component: Database driver name or database name "JDBI",
71-
"jdbc", "odbc", "postgreSQL".
72-
database_type: The Database type. For any SQL database, "sql".
73-
connection_attributes: Attribute names for database, port, host and
74-
user in Connection object.
75-
tracer_provider: The :class:`opentelemetry.trace.TracerProvider` to
76-
use. If ommited the current configured one is used.
77-
capture_parameters: Configure if db.statement.parameters should be captured.
65+
https://www.python.org/dev/peps/pep-0249/
66+
67+
Args:
68+
connect_module: Module name where connect method is available.
69+
connect_method_name: The connect method name.
70+
database_component: Database driver name or database name "JDBI",
71+
"jdbc", "odbc", "postgreSQL".
72+
database_type: The Database type. For any SQL database, "sql".
73+
connection_attributes: Attribute names for database, port, host and
74+
user in Connection object.
75+
tracer_provider: The :class:`opentelemetry.trace.TracerProvider` to
76+
use. If ommited the current configured one is used.
77+
capture_parameters: Configure if db.statement.parameters should be captured.
7878
"""
7979
wrap_connect(
8080
__name__,
@@ -101,18 +101,18 @@ def wrap_connect(
101101
capture_parameters: bool = False,
102102
):
103103
"""Integrate with DB API library.
104-
https://www.python.org/dev/peps/pep-0249/
105-
106-
Args:
107-
tracer: The :class:`opentelemetry.trace.Tracer` to use.
108-
connect_module: Module name where connect method is available.
109-
connect_method_name: The connect method name.
110-
database_component: Database driver name or database name "JDBI",
111-
"jdbc", "odbc", "postgreSQL".
112-
database_type: The Database type. For any SQL database, "sql".
113-
connection_attributes: Attribute names for database, port, host and
114-
user in Connection object.
115-
capture_parameters: Configure if db.statement.parameters should be captured.
104+
https://www.python.org/dev/peps/pep-0249/
105+
106+
Args:
107+
tracer: The :class:`opentelemetry.trace.Tracer` to use.
108+
connect_module: Module name where connect method is available.
109+
connect_method_name: The connect method name.
110+
database_component: Database driver name or database name "JDBI",
111+
"jdbc", "odbc", "postgreSQL".
112+
database_type: The Database type. For any SQL database, "sql".
113+
connection_attributes: Attribute names for database, port, host and
114+
user in Connection object.
115+
capture_parameters: Configure if db.statement.parameters should be captured.
116116
117117
"""
118118

@@ -143,14 +143,14 @@ def wrap_connect_(
143143

144144

145145
def unwrap_connect(
146-
connect_module: typing.Callable[..., typing.Any], connect_method_name: str,
146+
connect_module: typing.Callable[..., typing.Any], connect_method_name: str
147147
):
148148
"""Disable integration with DB API library.
149-
https://www.python.org/dev/peps/pep-0249/
149+
https://www.python.org/dev/peps/pep-0249/
150150
151-
Args:
152-
connect_module: Module name where the connect method is available.
153-
connect_method_name: The connect method name.
151+
Args:
152+
connect_module: Module name where the connect method is available.
153+
connect_method_name: The connect method name.
154154
"""
155155
unwrap(connect_module, connect_method_name)
156156

@@ -251,8 +251,7 @@ def wrapped_connection(
251251
args: typing.Tuple[typing.Any, typing.Any],
252252
kwargs: typing.Dict[typing.Any, typing.Any],
253253
):
254-
"""Add object proxy to connection object.
255-
"""
254+
"""Add object proxy to connection object."""
256255
connection = connect_method(*args, **kwargs)
257256
self.get_connection_attributes(connection)
258257
return get_traced_connection_proxy(connection, self)
@@ -278,6 +277,9 @@ def get_connection_attributes(self, connection):
278277
self.database = self.database.decode(errors="ignore")
279278
self.name += "." + self.database
280279
user = self.connection_props.get("user")
280+
# PyMySQL encodes this data
281+
if user and isinstance(user, bytes):
282+
user = user.decode()
281283
if user is not None:
282284
self.span_attributes["db.user"] = str(user)
283285
host = self.connection_props.get("host")
@@ -325,8 +327,10 @@ def _populate_span(
325327
span.set_attribute(
326328
"component", self._db_api_integration.database_component
327329
)
328-
span.set_attribute("db.type", self._db_api_integration.database_type)
329-
span.set_attribute("db.instance", self._db_api_integration.database)
330+
span.set_attribute(
331+
"db.system", self._db_api_integration.database_component
332+
)
333+
span.set_attribute("db.name", self._db_api_integration.database)
330334
span.set_attribute("db.statement", statement)
331335

332336
for (
@@ -344,9 +348,16 @@ def traced_execution(
344348
*args: typing.Tuple[typing.Any, typing.Any],
345349
**kwargs: typing.Dict[typing.Any, typing.Any]
346350
):
351+
name = ""
352+
if args:
353+
name = args[0]
354+
elif self._db_api_integration.database:
355+
name = self._db_api_integration.database
356+
else:
357+
name = self._db_api_integration.name
347358

348359
with self._db_api_integration.get_tracer().start_as_current_span(
349-
self._db_api_integration.name, kind=SpanKind.CLIENT
360+
name, kind=SpanKind.CLIENT
350361
) as span:
351362
self._populate_span(span, *args)
352363
try:

instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,19 @@ def test_span_succeeded(self):
5050
spans_list = self.memory_exporter.get_finished_spans()
5151
self.assertEqual(len(spans_list), 1)
5252
span = spans_list[0]
53-
self.assertEqual(span.name, "testcomponent.testdatabase")
53+
self.assertEqual(span.name, "Test query")
5454
self.assertIs(span.kind, trace_api.SpanKind.CLIENT)
5555

5656
self.assertEqual(span.attributes["component"], "testcomponent")
57-
self.assertEqual(span.attributes["db.type"], "testtype")
58-
self.assertEqual(span.attributes["db.instance"], "testdatabase")
57+
self.assertEqual(span.attributes["db.system"], "testcomponent")
58+
self.assertEqual(span.attributes["db.name"], "testdatabase")
5959
self.assertEqual(span.attributes["db.statement"], "Test query")
6060
self.assertFalse("db.statement.parameters" in span.attributes)
6161
self.assertEqual(span.attributes["db.user"], "testuser")
6262
self.assertEqual(span.attributes["net.peer.name"], "testhost")
6363
self.assertEqual(span.attributes["net.peer.port"], 123)
6464
self.assertIs(
65-
span.status.status_code, trace_api.status.StatusCode.UNSET,
65+
span.status.status_code, trace_api.status.StatusCode.UNSET
6666
)
6767

6868
def test_span_succeeded_with_capture_of_statement_parameters(self):
@@ -93,12 +93,12 @@ def test_span_succeeded_with_capture_of_statement_parameters(self):
9393
spans_list = self.memory_exporter.get_finished_spans()
9494
self.assertEqual(len(spans_list), 1)
9595
span = spans_list[0]
96-
self.assertEqual(span.name, "testcomponent.testdatabase")
96+
self.assertEqual(span.name, "Test query")
9797
self.assertIs(span.kind, trace_api.SpanKind.CLIENT)
9898

9999
self.assertEqual(span.attributes["component"], "testcomponent")
100-
self.assertEqual(span.attributes["db.type"], "testtype")
101-
self.assertEqual(span.attributes["db.instance"], "testdatabase")
100+
self.assertEqual(span.attributes["db.system"], "testcomponent")
101+
self.assertEqual(span.attributes["db.name"], "testdatabase")
102102
self.assertEqual(span.attributes["db.statement"], "Test query")
103103
self.assertEqual(
104104
span.attributes["db.statement.parameters"],
@@ -108,7 +108,7 @@ def test_span_succeeded_with_capture_of_statement_parameters(self):
108108
self.assertEqual(span.attributes["net.peer.name"], "testhost")
109109
self.assertEqual(span.attributes["net.peer.port"], 123)
110110
self.assertIs(
111-
span.status.status_code, trace_api.status.StatusCode.UNSET,
111+
span.status.status_code, trace_api.status.StatusCode.UNSET
112112
)
113113

114114
def test_span_not_recording(self):
@@ -159,7 +159,7 @@ def test_span_failed(self):
159159
span = spans_list[0]
160160
self.assertEqual(span.attributes["db.statement"], "Test query")
161161
self.assertIs(
162-
span.status.status_code, trace_api.status.StatusCode.ERROR,
162+
span.status.status_code, trace_api.status.StatusCode.ERROR
163163
)
164164
self.assertEqual(span.status.description, "Test Exception")
165165

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class SQLite3Instrumentor(BaseInstrumentor):
5151
# No useful attributes of sqlite3 connection object
5252
_CONNECTION_ATTRIBUTES = {}
5353

54-
_DATABASE_COMPONENT = "sqlite3"
54+
_DATABASE_COMPONENT = "sqlite"
5555
_DATABASE_TYPE = "sql"
5656

5757
def _instrument(self, **kwargs):

instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py

+11-15
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def tearDownClass(cls):
3737
if cls._connection:
3838
cls._connection.close()
3939

40-
def validate_spans(self):
40+
def validate_spans(self, span_name):
4141
spans = self.memory_exporter.get_finished_spans()
4242
self.assertEqual(len(spans), 2)
4343
for span in spans:
@@ -50,34 +50,30 @@ def validate_spans(self):
5050
self.assertIsNotNone(root_span)
5151
self.assertIsNotNone(child_span)
5252
self.assertEqual(root_span.name, "rootSpan")
53-
self.assertEqual(child_span.name, "sqlite3")
53+
self.assertEqual(child_span.name, span_name)
5454
self.assertIsNotNone(child_span.parent)
5555
self.assertIs(child_span.parent, root_span.get_span_context())
5656
self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT)
5757

5858
def test_execute(self):
59-
"""Should create a child span for execute method
60-
"""
59+
"""Should create a child span for execute method"""
60+
stmt = "CREATE TABLE IF NOT EXISTS test (id integer)"
6161
with self._tracer.start_as_current_span("rootSpan"):
62-
self._cursor.execute(
63-
"CREATE TABLE IF NOT EXISTS test (id integer)"
64-
)
65-
self.validate_spans()
62+
self._cursor.execute(stmt)
63+
self.validate_spans(stmt)
6664

6765
def test_executemany(self):
68-
"""Should create a child span for executemany
69-
"""
66+
"""Should create a child span for executemany"""
67+
stmt = "INSERT INTO test (id) VALUES (?)"
7068
with self._tracer.start_as_current_span("rootSpan"):
7169
data = [("1",), ("2",), ("3",)]
72-
stmt = "INSERT INTO test (id) VALUES (?)"
7370
self._cursor.executemany(stmt, data)
74-
self.validate_spans()
71+
self.validate_spans(stmt)
7572

7673
def test_callproc(self):
77-
"""Should create a child span for callproc
78-
"""
74+
"""Should create a child span for callproc"""
7975
with self._tracer.start_as_current_span("rootSpan"), self.assertRaises(
8076
Exception
8177
):
8278
self._cursor.callproc("test", ())
83-
self.validate_spans()
79+
self.validate_spans("test")

tests/opentelemetry-docker-tests/tests/check_availability.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@
2424
MONGODB_DB_NAME = os.getenv("MONGODB_DB_NAME", "opentelemetry-tests")
2525
MONGODB_HOST = os.getenv("MONGODB_HOST", "localhost")
2626
MONGODB_PORT = int(os.getenv("MONGODB_PORT", "27017"))
27-
MYSQL_DB_NAME = os.getenv("MYSQL_DB_NAME ", "opentelemetry-tests")
28-
MYSQL_HOST = os.getenv("MYSQL_HOST ", "localhost")
29-
MYSQL_PORT = int(os.getenv("MYSQL_PORT ", "3306"))
30-
MYSQL_USER = os.getenv("MYSQL_USER ", "testuser")
31-
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD ", "testpassword")
27+
MYSQL_DB_NAME = os.getenv("MYSQL_DB_NAME", "opentelemetry-tests")
28+
MYSQL_HOST = os.getenv("MYSQL_HOST", "localhost")
29+
MYSQL_PORT = int(os.getenv("MYSQL_PORT", "3306"))
30+
MYSQL_USER = os.getenv("MYSQL_USER", "testuser")
31+
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", "testpassword")
3232
POSTGRES_DB_NAME = os.getenv("POSTGRESQL_DB_NAME", "opentelemetry-tests")
3333
POSTGRES_HOST = os.getenv("POSTGRESQL_HOST", "localhost")
34-
POSTGRES_PASSWORD = os.getenv("POSTGRESQL_HOST", "testpassword")
34+
POSTGRES_PASSWORD = os.getenv("POSTGRESQL_PASSWORD", "testpassword")
3535
POSTGRES_PORT = int(os.getenv("POSTGRESQL_PORT", "5432"))
36-
POSTGRES_USER = os.getenv("POSTGRESQL_HOST", "testuser")
36+
POSTGRES_USER = os.getenv("POSTGRESQL_USER", "testuser")
3737
REDIS_HOST = os.getenv("REDIS_HOST", "localhost")
3838
REDIS_PORT = int(os.getenv("REDIS_PORT ", "6379"))
3939
RETRY_COUNT = 8

0 commit comments

Comments
 (0)