Merge pull request #195 from lonewolf3739/dbapi-semantic-conv

This commit is contained in:
Leighton Chen
2020-11-23 11:03:00 -05:00
committed by GitHub
13 changed files with 180 additions and 158 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@ var
sdist sdist
develop-eggs develop-eggs
.installed.cfg .installed.cfg
pyvenv.cfg
lib lib
lib64 lib64
__pycache__ __pycache__

View File

@ -101,9 +101,16 @@ class AsyncTracedCursor(TracedCursor):
*args: typing.Tuple[typing.Any, typing.Any], *args: typing.Tuple[typing.Any, typing.Any],
**kwargs: typing.Dict[typing.Any, typing.Any] **kwargs: typing.Dict[typing.Any, typing.Any]
): ):
name = ""
if len(args) > 0 and args[0]:
name = args[0]
elif self._db_api_integration.database:
name = self._db_api_integration.database
else:
name = self._db_api_integration.name
with self._db_api_integration.get_tracer().start_as_current_span( with self._db_api_integration.get_tracer().start_as_current_span(
self._db_api_integration.name, kind=SpanKind.CLIENT name, kind=SpanKind.CLIENT
) as span: ) as span:
self._populate_span(span, *args) self._populate_span(span, *args)
try: try:

View File

@ -215,12 +215,12 @@ class TestAiopgIntegration(TestBase):
spans_list = self.memory_exporter.get_finished_spans() spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 1) self.assertEqual(len(spans_list), 1)
span = spans_list[0] span = spans_list[0]
self.assertEqual(span.name, "testcomponent.testdatabase") self.assertEqual(span.name, "Test query")
self.assertIs(span.kind, trace_api.SpanKind.CLIENT) self.assertIs(span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual(span.attributes["component"], "testcomponent") self.assertEqual(span.attributes["component"], "testcomponent")
self.assertEqual(span.attributes["db.type"], "testtype") self.assertEqual(span.attributes["db.system"], "testcomponent")
self.assertEqual(span.attributes["db.instance"], "testdatabase") self.assertEqual(span.attributes["db.name"], "testdatabase")
self.assertEqual(span.attributes["db.statement"], "Test query") self.assertEqual(span.attributes["db.statement"], "Test query")
self.assertEqual( self.assertEqual(
span.attributes["db.statement.parameters"], span.attributes["db.statement.parameters"],
@ -230,7 +230,7 @@ class TestAiopgIntegration(TestBase):
self.assertEqual(span.attributes["net.peer.name"], "testhost") self.assertEqual(span.attributes["net.peer.name"], "testhost")
self.assertEqual(span.attributes["net.peer.port"], 123) self.assertEqual(span.attributes["net.peer.port"], 123)
self.assertIs( self.assertIs(
span.status.status_code, trace_api.status.StatusCode.UNSET, span.status.status_code, trace_api.status.StatusCode.UNSET
) )
def test_span_not_recording(self): def test_span_not_recording(self):
@ -281,7 +281,7 @@ class TestAiopgIntegration(TestBase):
span = spans_list[0] span = spans_list[0]
self.assertEqual(span.attributes["db.statement"], "Test query") self.assertEqual(span.attributes["db.statement"], "Test query")
self.assertIs( self.assertIs(
span.status.status_code, trace_api.status.StatusCode.ERROR, span.status.status_code, trace_api.status.StatusCode.ERROR
) )
self.assertEqual(span.status.description, "Test Exception") self.assertEqual(span.status.description, "Test Exception")

View File

@ -2,7 +2,10 @@
## Unreleased ## Unreleased
Stop capturing query parameters by default - Update dbapi and its dependant instrumentations to follow semantic conventions
([#195](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/195))
- Stop capturing query parameters by default
([#156](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/156)) ([#156](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/156))
## Version 0.13b0 ## Version 0.13b0

View File

@ -62,19 +62,19 @@ def trace_integration(
capture_parameters: bool = False, capture_parameters: bool = False,
): ):
"""Integrate with DB API library. """Integrate with DB API library.
https://www.python.org/dev/peps/pep-0249/ https://www.python.org/dev/peps/pep-0249/
Args: Args:
connect_module: Module name where connect method is available. connect_module: Module name where connect method is available.
connect_method_name: The connect method name. connect_method_name: The connect method name.
database_component: Database driver name or database name "JDBI", database_component: Database driver name or database name "JDBI",
"jdbc", "odbc", "postgreSQL". "jdbc", "odbc", "postgreSQL".
database_type: The Database type. For any SQL database, "sql". database_type: The Database type. For any SQL database, "sql".
connection_attributes: Attribute names for database, port, host and connection_attributes: Attribute names for database, port, host and
user in Connection object. user in Connection object.
tracer_provider: The :class:`opentelemetry.trace.TracerProvider` to tracer_provider: The :class:`opentelemetry.trace.TracerProvider` to
use. If ommited the current configured one is used. use. If ommited the current configured one is used.
capture_parameters: Configure if db.statement.parameters should be captured. capture_parameters: Configure if db.statement.parameters should be captured.
""" """
wrap_connect( wrap_connect(
__name__, __name__,
@ -101,18 +101,18 @@ def wrap_connect(
capture_parameters: bool = False, capture_parameters: bool = False,
): ):
"""Integrate with DB API library. """Integrate with DB API library.
https://www.python.org/dev/peps/pep-0249/ https://www.python.org/dev/peps/pep-0249/
Args: Args:
tracer: The :class:`opentelemetry.trace.Tracer` to use. tracer: The :class:`opentelemetry.trace.Tracer` to use.
connect_module: Module name where connect method is available. connect_module: Module name where connect method is available.
connect_method_name: The connect method name. connect_method_name: The connect method name.
database_component: Database driver name or database name "JDBI", database_component: Database driver name or database name "JDBI",
"jdbc", "odbc", "postgreSQL". "jdbc", "odbc", "postgreSQL".
database_type: The Database type. For any SQL database, "sql". database_type: The Database type. For any SQL database, "sql".
connection_attributes: Attribute names for database, port, host and connection_attributes: Attribute names for database, port, host and
user in Connection object. user in Connection object.
capture_parameters: Configure if db.statement.parameters should be captured. capture_parameters: Configure if db.statement.parameters should be captured.
""" """
@ -143,14 +143,14 @@ def wrap_connect(
def unwrap_connect( def unwrap_connect(
connect_module: typing.Callable[..., typing.Any], connect_method_name: str, connect_module: typing.Callable[..., typing.Any], connect_method_name: str
): ):
"""Disable integration with DB API library. """Disable integration with DB API library.
https://www.python.org/dev/peps/pep-0249/ https://www.python.org/dev/peps/pep-0249/
Args: Args:
connect_module: Module name where the connect method is available. connect_module: Module name where the connect method is available.
connect_method_name: The connect method name. connect_method_name: The connect method name.
""" """
unwrap(connect_module, connect_method_name) unwrap(connect_module, connect_method_name)
@ -251,8 +251,7 @@ class DatabaseApiIntegration:
args: typing.Tuple[typing.Any, typing.Any], args: typing.Tuple[typing.Any, typing.Any],
kwargs: typing.Dict[typing.Any, typing.Any], kwargs: typing.Dict[typing.Any, typing.Any],
): ):
"""Add object proxy to connection object. """Add object proxy to connection object."""
"""
connection = connect_method(*args, **kwargs) connection = connect_method(*args, **kwargs)
self.get_connection_attributes(connection) self.get_connection_attributes(connection)
return get_traced_connection_proxy(connection, self) return get_traced_connection_proxy(connection, self)
@ -278,6 +277,9 @@ class DatabaseApiIntegration:
self.database = self.database.decode(errors="ignore") self.database = self.database.decode(errors="ignore")
self.name += "." + self.database self.name += "." + self.database
user = self.connection_props.get("user") user = self.connection_props.get("user")
# PyMySQL encodes this data
if user and isinstance(user, bytes):
user = user.decode()
if user is not None: if user is not None:
self.span_attributes["db.user"] = str(user) self.span_attributes["db.user"] = str(user)
host = self.connection_props.get("host") host = self.connection_props.get("host")
@ -325,8 +327,10 @@ class TracedCursor:
span.set_attribute( span.set_attribute(
"component", self._db_api_integration.database_component "component", self._db_api_integration.database_component
) )
span.set_attribute("db.type", self._db_api_integration.database_type) span.set_attribute(
span.set_attribute("db.instance", self._db_api_integration.database) "db.system", self._db_api_integration.database_component
)
span.set_attribute("db.name", self._db_api_integration.database)
span.set_attribute("db.statement", statement) span.set_attribute("db.statement", statement)
for ( for (
@ -344,9 +348,16 @@ class TracedCursor:
*args: typing.Tuple[typing.Any, typing.Any], *args: typing.Tuple[typing.Any, typing.Any],
**kwargs: typing.Dict[typing.Any, typing.Any] **kwargs: typing.Dict[typing.Any, typing.Any]
): ):
name = ""
if args:
name = args[0]
elif self._db_api_integration.database:
name = self._db_api_integration.database
else:
name = self._db_api_integration.name
with self._db_api_integration.get_tracer().start_as_current_span( with self._db_api_integration.get_tracer().start_as_current_span(
self._db_api_integration.name, kind=SpanKind.CLIENT name, kind=SpanKind.CLIENT
) as span: ) as span:
self._populate_span(span, *args) self._populate_span(span, *args)
try: try:

View File

@ -50,19 +50,19 @@ class TestDBApiIntegration(TestBase):
spans_list = self.memory_exporter.get_finished_spans() spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 1) self.assertEqual(len(spans_list), 1)
span = spans_list[0] span = spans_list[0]
self.assertEqual(span.name, "testcomponent.testdatabase") self.assertEqual(span.name, "Test query")
self.assertIs(span.kind, trace_api.SpanKind.CLIENT) self.assertIs(span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual(span.attributes["component"], "testcomponent") self.assertEqual(span.attributes["component"], "testcomponent")
self.assertEqual(span.attributes["db.type"], "testtype") self.assertEqual(span.attributes["db.system"], "testcomponent")
self.assertEqual(span.attributes["db.instance"], "testdatabase") self.assertEqual(span.attributes["db.name"], "testdatabase")
self.assertEqual(span.attributes["db.statement"], "Test query") self.assertEqual(span.attributes["db.statement"], "Test query")
self.assertFalse("db.statement.parameters" in span.attributes) self.assertFalse("db.statement.parameters" in span.attributes)
self.assertEqual(span.attributes["db.user"], "testuser") self.assertEqual(span.attributes["db.user"], "testuser")
self.assertEqual(span.attributes["net.peer.name"], "testhost") self.assertEqual(span.attributes["net.peer.name"], "testhost")
self.assertEqual(span.attributes["net.peer.port"], 123) self.assertEqual(span.attributes["net.peer.port"], 123)
self.assertIs( self.assertIs(
span.status.status_code, trace_api.status.StatusCode.UNSET, span.status.status_code, trace_api.status.StatusCode.UNSET
) )
def test_span_succeeded_with_capture_of_statement_parameters(self): def test_span_succeeded_with_capture_of_statement_parameters(self):
@ -93,12 +93,12 @@ class TestDBApiIntegration(TestBase):
spans_list = self.memory_exporter.get_finished_spans() spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 1) self.assertEqual(len(spans_list), 1)
span = spans_list[0] span = spans_list[0]
self.assertEqual(span.name, "testcomponent.testdatabase") self.assertEqual(span.name, "Test query")
self.assertIs(span.kind, trace_api.SpanKind.CLIENT) self.assertIs(span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual(span.attributes["component"], "testcomponent") self.assertEqual(span.attributes["component"], "testcomponent")
self.assertEqual(span.attributes["db.type"], "testtype") self.assertEqual(span.attributes["db.system"], "testcomponent")
self.assertEqual(span.attributes["db.instance"], "testdatabase") self.assertEqual(span.attributes["db.name"], "testdatabase")
self.assertEqual(span.attributes["db.statement"], "Test query") self.assertEqual(span.attributes["db.statement"], "Test query")
self.assertEqual( self.assertEqual(
span.attributes["db.statement.parameters"], span.attributes["db.statement.parameters"],
@ -108,7 +108,7 @@ class TestDBApiIntegration(TestBase):
self.assertEqual(span.attributes["net.peer.name"], "testhost") self.assertEqual(span.attributes["net.peer.name"], "testhost")
self.assertEqual(span.attributes["net.peer.port"], 123) self.assertEqual(span.attributes["net.peer.port"], 123)
self.assertIs( self.assertIs(
span.status.status_code, trace_api.status.StatusCode.UNSET, span.status.status_code, trace_api.status.StatusCode.UNSET
) )
def test_span_not_recording(self): def test_span_not_recording(self):
@ -159,7 +159,7 @@ class TestDBApiIntegration(TestBase):
span = spans_list[0] span = spans_list[0]
self.assertEqual(span.attributes["db.statement"], "Test query") self.assertEqual(span.attributes["db.statement"], "Test query")
self.assertIs( self.assertIs(
span.status.status_code, trace_api.status.StatusCode.ERROR, span.status.status_code, trace_api.status.StatusCode.ERROR
) )
self.assertEqual(span.status.description, "Test Exception") self.assertEqual(span.status.description, "Test Exception")

View File

@ -51,7 +51,7 @@ class SQLite3Instrumentor(BaseInstrumentor):
# No useful attributes of sqlite3 connection object # No useful attributes of sqlite3 connection object
_CONNECTION_ATTRIBUTES = {} _CONNECTION_ATTRIBUTES = {}
_DATABASE_COMPONENT = "sqlite3" _DATABASE_COMPONENT = "sqlite"
_DATABASE_TYPE = "sql" _DATABASE_TYPE = "sql"
def _instrument(self, **kwargs): def _instrument(self, **kwargs):

View File

@ -37,7 +37,7 @@ class TestSQLite3(TestBase):
if cls._connection: if cls._connection:
cls._connection.close() cls._connection.close()
def validate_spans(self): def validate_spans(self, span_name):
spans = self.memory_exporter.get_finished_spans() spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 2) self.assertEqual(len(spans), 2)
for span in spans: for span in spans:
@ -50,34 +50,30 @@ class TestSQLite3(TestBase):
self.assertIsNotNone(root_span) self.assertIsNotNone(root_span)
self.assertIsNotNone(child_span) self.assertIsNotNone(child_span)
self.assertEqual(root_span.name, "rootSpan") self.assertEqual(root_span.name, "rootSpan")
self.assertEqual(child_span.name, "sqlite3") self.assertEqual(child_span.name, span_name)
self.assertIsNotNone(child_span.parent) self.assertIsNotNone(child_span.parent)
self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.parent, root_span.get_span_context())
self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT)
def test_execute(self): def test_execute(self):
"""Should create a child span for execute method """Should create a child span for execute method"""
""" stmt = "CREATE TABLE IF NOT EXISTS test (id integer)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
self._cursor.execute( self._cursor.execute(stmt)
"CREATE TABLE IF NOT EXISTS test (id integer)" self.validate_spans(stmt)
)
self.validate_spans()
def test_executemany(self): def test_executemany(self):
"""Should create a child span for executemany """Should create a child span for executemany"""
""" stmt = "INSERT INTO test (id) VALUES (?)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
data = [("1",), ("2",), ("3",)] data = [("1",), ("2",), ("3",)]
stmt = "INSERT INTO test (id) VALUES (?)"
self._cursor.executemany(stmt, data) self._cursor.executemany(stmt, data)
self.validate_spans() self.validate_spans(stmt)
def test_callproc(self): def test_callproc(self):
"""Should create a child span for callproc """Should create a child span for callproc"""
"""
with self._tracer.start_as_current_span("rootSpan"), self.assertRaises( with self._tracer.start_as_current_span("rootSpan"), self.assertRaises(
Exception Exception
): ):
self._cursor.callproc("test", ()) self._cursor.callproc("test", ())
self.validate_spans() self.validate_spans("test")

View File

@ -24,16 +24,16 @@ MONGODB_COLLECTION_NAME = "test"
MONGODB_DB_NAME = os.getenv("MONGODB_DB_NAME", "opentelemetry-tests") MONGODB_DB_NAME = os.getenv("MONGODB_DB_NAME", "opentelemetry-tests")
MONGODB_HOST = os.getenv("MONGODB_HOST", "localhost") MONGODB_HOST = os.getenv("MONGODB_HOST", "localhost")
MONGODB_PORT = int(os.getenv("MONGODB_PORT", "27017")) MONGODB_PORT = int(os.getenv("MONGODB_PORT", "27017"))
MYSQL_DB_NAME = os.getenv("MYSQL_DB_NAME ", "opentelemetry-tests") MYSQL_DB_NAME = os.getenv("MYSQL_DB_NAME", "opentelemetry-tests")
MYSQL_HOST = os.getenv("MYSQL_HOST ", "localhost") MYSQL_HOST = os.getenv("MYSQL_HOST", "localhost")
MYSQL_PORT = int(os.getenv("MYSQL_PORT ", "3306")) MYSQL_PORT = int(os.getenv("MYSQL_PORT", "3306"))
MYSQL_USER = os.getenv("MYSQL_USER ", "testuser") MYSQL_USER = os.getenv("MYSQL_USER", "testuser")
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD ", "testpassword") MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", "testpassword")
POSTGRES_DB_NAME = os.getenv("POSTGRESQL_DB_NAME", "opentelemetry-tests") POSTGRES_DB_NAME = os.getenv("POSTGRESQL_DB_NAME", "opentelemetry-tests")
POSTGRES_HOST = os.getenv("POSTGRESQL_HOST", "localhost") POSTGRES_HOST = os.getenv("POSTGRESQL_HOST", "localhost")
POSTGRES_PASSWORD = os.getenv("POSTGRESQL_HOST", "testpassword") POSTGRES_PASSWORD = os.getenv("POSTGRESQL_PASSWORD", "testpassword")
POSTGRES_PORT = int(os.getenv("POSTGRESQL_PORT", "5432")) POSTGRES_PORT = int(os.getenv("POSTGRESQL_PORT", "5432"))
POSTGRES_USER = os.getenv("POSTGRESQL_HOST", "testuser") POSTGRES_USER = os.getenv("POSTGRESQL_USER", "testuser")
REDIS_HOST = os.getenv("REDIS_HOST", "localhost") REDIS_HOST = os.getenv("REDIS_HOST", "localhost")
REDIS_PORT = int(os.getenv("REDIS_PORT ", "6379")) REDIS_PORT = int(os.getenv("REDIS_PORT ", "6379"))
RETRY_COUNT = 8 RETRY_COUNT = 8

View File

@ -20,11 +20,11 @@ from opentelemetry import trace as trace_api
from opentelemetry.instrumentation.mysql import MySQLInstrumentor from opentelemetry.instrumentation.mysql import MySQLInstrumentor
from opentelemetry.test.test_base import TestBase from opentelemetry.test.test_base import TestBase
MYSQL_USER = os.getenv("MYSQL_USER ", "testuser") MYSQL_USER = os.getenv("MYSQL_USER", "testuser")
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD ", "testpassword") MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", "testpassword")
MYSQL_HOST = os.getenv("MYSQL_HOST ", "localhost") MYSQL_HOST = os.getenv("MYSQL_HOST", "localhost")
MYSQL_PORT = int(os.getenv("MYSQL_PORT ", "3306")) MYSQL_PORT = int(os.getenv("MYSQL_PORT", "3306"))
MYSQL_DB_NAME = os.getenv("MYSQL_DB_NAME ", "opentelemetry-tests") MYSQL_DB_NAME = os.getenv("MYSQL_DB_NAME", "opentelemetry-tests")
class TestFunctionalMysql(TestBase): class TestFunctionalMysql(TestBase):
@ -53,7 +53,7 @@ class TestFunctionalMysql(TestBase):
) )
self._cursor = self._connection.cursor() self._cursor = self._connection.cursor()
def validate_spans(self): def validate_spans(self, span_name):
spans = self.memory_exporter.get_finished_spans() spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 2) self.assertEqual(len(spans), 2)
for span in spans: for span in spans:
@ -66,42 +66,47 @@ class TestFunctionalMysql(TestBase):
self.assertIsNotNone(root_span) self.assertIsNotNone(root_span)
self.assertIsNotNone(db_span) self.assertIsNotNone(db_span)
self.assertEqual(root_span.name, "rootSpan") self.assertEqual(root_span.name, "rootSpan")
self.assertEqual(db_span.name, "mysql.opentelemetry-tests") self.assertEqual(db_span.name, span_name)
self.assertIsNotNone(db_span.parent) self.assertIsNotNone(db_span.parent)
self.assertIs(db_span.parent, root_span.get_span_context()) self.assertIs(db_span.parent, root_span.get_span_context())
self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT) self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual(db_span.attributes["db.instance"], MYSQL_DB_NAME) self.assertEqual(db_span.attributes["db.system"], "mysql")
self.assertEqual(db_span.attributes["db.name"], MYSQL_DB_NAME)
self.assertEqual(db_span.attributes["db.user"], MYSQL_USER)
self.assertEqual(db_span.attributes["net.peer.name"], MYSQL_HOST) self.assertEqual(db_span.attributes["net.peer.name"], MYSQL_HOST)
self.assertEqual(db_span.attributes["net.peer.port"], MYSQL_PORT) self.assertEqual(db_span.attributes["net.peer.port"], MYSQL_PORT)
def test_execute(self): def test_execute(self):
"""Should create a child span for execute""" """Should create a child span for execute"""
stmt = "CREATE TABLE IF NOT EXISTS test (id INT)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
self._cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") self._cursor.execute(stmt)
self.validate_spans() self.validate_spans(stmt)
def test_execute_with_connection_context_manager(self): def test_execute_with_connection_context_manager(self):
"""Should create a child span for execute with connection context""" """Should create a child span for execute with connection context"""
stmt = "CREATE TABLE IF NOT EXISTS test (id INT)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
with self._connection as conn: with self._connection as conn:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") cursor.execute(stmt)
self.validate_spans() self.validate_spans(stmt)
def test_execute_with_cursor_context_manager(self): def test_execute_with_cursor_context_manager(self):
"""Should create a child span for execute with cursor context""" """Should create a child span for execute with cursor context"""
stmt = "CREATE TABLE IF NOT EXISTS test (id INT)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
with self._connection.cursor() as cursor: with self._connection.cursor() as cursor:
cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") cursor.execute(stmt)
self.validate_spans() self.validate_spans(stmt)
def test_executemany(self): def test_executemany(self):
"""Should create a child span for executemany""" """Should create a child span for executemany"""
stmt = "INSERT INTO test (id) VALUES (%s)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
data = (("1",), ("2",), ("3",)) data = (("1",), ("2",), ("3",))
stmt = "INSERT INTO test (id) VALUES (%s)"
self._cursor.executemany(stmt, data) self._cursor.executemany(stmt, data)
self.validate_spans() self.validate_spans(stmt)
def test_callproc(self): def test_callproc(self):
"""Should create a child span for callproc""" """Should create a child span for callproc"""
@ -109,4 +114,4 @@ class TestFunctionalMysql(TestBase):
Exception Exception
): ):
self._cursor.callproc("test", ()) self._cursor.callproc("test", ())
self.validate_spans() self.validate_spans("test")

View File

@ -22,11 +22,11 @@ from opentelemetry import trace as trace_api
from opentelemetry.instrumentation.aiopg import AiopgInstrumentor from opentelemetry.instrumentation.aiopg import AiopgInstrumentor
from opentelemetry.test.test_base import TestBase from opentelemetry.test.test_base import TestBase
POSTGRES_HOST = os.getenv("POSTGRESQL_HOST ", "localhost") POSTGRES_HOST = os.getenv("POSTGRESQL_HOST", "localhost")
POSTGRES_PORT = int(os.getenv("POSTGRESQL_PORT ", "5432")) POSTGRES_PORT = int(os.getenv("POSTGRESQL_PORT", "5432"))
POSTGRES_DB_NAME = os.getenv("POSTGRESQL_DB_NAME ", "opentelemetry-tests") POSTGRES_DB_NAME = os.getenv("POSTGRESQL_DB_NAME", "opentelemetry-tests")
POSTGRES_PASSWORD = os.getenv("POSTGRESQL_HOST ", "testpassword") POSTGRES_PASSWORD = os.getenv("POSTGRESQL_PASSWORD", "testpassword")
POSTGRES_USER = os.getenv("POSTGRESQL_HOST ", "testuser") POSTGRES_USER = os.getenv("POSTGRESQL_USER", "testuser")
def async_call(coro): def async_call(coro):
@ -61,7 +61,7 @@ class TestFunctionalAiopgConnect(TestBase):
cls._connection.close() cls._connection.close()
AiopgInstrumentor().uninstrument() AiopgInstrumentor().uninstrument()
def validate_spans(self): def validate_spans(self, span_name):
spans = self.memory_exporter.get_finished_spans() spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 2) self.assertEqual(len(spans), 2)
for span in spans: for span in spans:
@ -74,34 +74,31 @@ class TestFunctionalAiopgConnect(TestBase):
self.assertIsNotNone(root_span) self.assertIsNotNone(root_span)
self.assertIsNotNone(child_span) self.assertIsNotNone(child_span)
self.assertEqual(root_span.name, "rootSpan") self.assertEqual(root_span.name, "rootSpan")
self.assertEqual(child_span.name, "postgresql.opentelemetry-tests") self.assertEqual(child_span.name, span_name)
self.assertIsNotNone(child_span.parent) self.assertIsNotNone(child_span.parent)
self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.parent, root_span.get_span_context())
self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual( self.assertEqual(child_span.attributes["db.system"], "postgresql")
child_span.attributes["db.instance"], POSTGRES_DB_NAME self.assertEqual(child_span.attributes["db.name"], POSTGRES_DB_NAME)
) self.assertEqual(child_span.attributes["db.user"], POSTGRES_USER)
self.assertEqual(child_span.attributes["net.peer.name"], POSTGRES_HOST) self.assertEqual(child_span.attributes["net.peer.name"], POSTGRES_HOST)
self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT) self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT)
def test_execute(self): def test_execute(self):
"""Should create a child span for execute method""" """Should create a child span for execute method"""
stmt = "CREATE TABLE IF NOT EXISTS test (id integer)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
async_call( async_call(self._cursor.execute(stmt))
self._cursor.execute( self.validate_spans(stmt)
"CREATE TABLE IF NOT EXISTS test (id integer)"
)
)
self.validate_spans()
def test_executemany(self): def test_executemany(self):
"""Should create a child span for executemany""" """Should create a child span for executemany"""
stmt = "INSERT INTO test (id) VALUES (%s)"
with pytest.raises(psycopg2.ProgrammingError): with pytest.raises(psycopg2.ProgrammingError):
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
data = (("1",), ("2",), ("3",)) data = (("1",), ("2",), ("3",))
stmt = "INSERT INTO test (id) VALUES (%s)"
async_call(self._cursor.executemany(stmt, data)) async_call(self._cursor.executemany(stmt, data))
self.validate_spans() self.validate_spans(stmt)
def test_callproc(self): def test_callproc(self):
"""Should create a child span for callproc""" """Should create a child span for callproc"""
@ -109,7 +106,7 @@ class TestFunctionalAiopgConnect(TestBase):
Exception Exception
): ):
async_call(self._cursor.callproc("test", ())) async_call(self._cursor.callproc("test", ()))
self.validate_spans() self.validate_spans("test")
class TestFunctionalAiopgCreatePool(TestBase): class TestFunctionalAiopgCreatePool(TestBase):
@ -142,7 +139,7 @@ class TestFunctionalAiopgCreatePool(TestBase):
cls._pool.close() cls._pool.close()
AiopgInstrumentor().uninstrument() AiopgInstrumentor().uninstrument()
def validate_spans(self): def validate_spans(self, span_name):
spans = self.memory_exporter.get_finished_spans() spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 2) self.assertEqual(len(spans), 2)
for span in spans: for span in spans:
@ -155,34 +152,31 @@ class TestFunctionalAiopgCreatePool(TestBase):
self.assertIsNotNone(root_span) self.assertIsNotNone(root_span)
self.assertIsNotNone(child_span) self.assertIsNotNone(child_span)
self.assertEqual(root_span.name, "rootSpan") self.assertEqual(root_span.name, "rootSpan")
self.assertEqual(child_span.name, "postgresql.opentelemetry-tests") self.assertEqual(child_span.name, span_name)
self.assertIsNotNone(child_span.parent) self.assertIsNotNone(child_span.parent)
self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.parent, root_span.get_span_context())
self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual( self.assertEqual(child_span.attributes["db.system"], "postgresql")
child_span.attributes["db.instance"], POSTGRES_DB_NAME self.assertEqual(child_span.attributes["db.name"], POSTGRES_DB_NAME)
) self.assertEqual(child_span.attributes["db.user"], POSTGRES_USER)
self.assertEqual(child_span.attributes["net.peer.name"], POSTGRES_HOST) self.assertEqual(child_span.attributes["net.peer.name"], POSTGRES_HOST)
self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT) self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT)
def test_execute(self): def test_execute(self):
"""Should create a child span for execute method""" """Should create a child span for execute method"""
stmt = "CREATE TABLE IF NOT EXISTS test (id integer)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
async_call( async_call(self._cursor.execute(stmt))
self._cursor.execute( self.validate_spans(stmt)
"CREATE TABLE IF NOT EXISTS test (id integer)"
)
)
self.validate_spans()
def test_executemany(self): def test_executemany(self):
"""Should create a child span for executemany""" """Should create a child span for executemany"""
stmt = "INSERT INTO test (id) VALUES (%s)"
with pytest.raises(psycopg2.ProgrammingError): with pytest.raises(psycopg2.ProgrammingError):
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
data = (("1",), ("2",), ("3",)) data = (("1",), ("2",), ("3",))
stmt = "INSERT INTO test (id) VALUES (%s)"
async_call(self._cursor.executemany(stmt, data)) async_call(self._cursor.executemany(stmt, data))
self.validate_spans() self.validate_spans(stmt)
def test_callproc(self): def test_callproc(self):
"""Should create a child span for callproc""" """Should create a child span for callproc"""
@ -190,4 +184,4 @@ class TestFunctionalAiopgCreatePool(TestBase):
Exception Exception
): ):
async_call(self._cursor.callproc("test", ())) async_call(self._cursor.callproc("test", ()))
self.validate_spans() self.validate_spans("test")

View File

@ -20,11 +20,11 @@ from opentelemetry import trace as trace_api
from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor
from opentelemetry.test.test_base import TestBase from opentelemetry.test.test_base import TestBase
POSTGRES_HOST = os.getenv("POSTGRESQL_HOST ", "localhost") POSTGRES_HOST = os.getenv("POSTGRESQL_HOST", "localhost")
POSTGRES_PORT = int(os.getenv("POSTGRESQL_PORT ", "5432")) POSTGRES_PORT = int(os.getenv("POSTGRESQL_PORT", "5432"))
POSTGRES_DB_NAME = os.getenv("POSTGRESQL_DB_NAME ", "opentelemetry-tests") POSTGRES_DB_NAME = os.getenv("POSTGRESQL_DB_NAME", "opentelemetry-tests")
POSTGRES_PASSWORD = os.getenv("POSTGRESQL_HOST ", "testpassword") POSTGRES_PASSWORD = os.getenv("POSTGRESQL_PASSWORD", "testpassword")
POSTGRES_USER = os.getenv("POSTGRESQL_HOST ", "testuser") POSTGRES_USER = os.getenv("POSTGRESQL_USER", "testuser")
class TestFunctionalPsycopg(TestBase): class TestFunctionalPsycopg(TestBase):
@ -53,7 +53,7 @@ class TestFunctionalPsycopg(TestBase):
cls._connection.close() cls._connection.close()
Psycopg2Instrumentor().uninstrument() Psycopg2Instrumentor().uninstrument()
def validate_spans(self): def validate_spans(self, span_name):
spans = self.memory_exporter.get_finished_spans() spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 2) self.assertEqual(len(spans), 2)
for span in spans: for span in spans:
@ -66,47 +66,48 @@ class TestFunctionalPsycopg(TestBase):
self.assertIsNotNone(root_span) self.assertIsNotNone(root_span)
self.assertIsNotNone(child_span) self.assertIsNotNone(child_span)
self.assertEqual(root_span.name, "rootSpan") self.assertEqual(root_span.name, "rootSpan")
self.assertEqual(child_span.name, "postgresql.opentelemetry-tests") self.assertEqual(child_span.name, span_name)
self.assertIsNotNone(child_span.parent) self.assertIsNotNone(child_span.parent)
self.assertIs(child_span.parent, root_span.get_span_context()) self.assertIs(child_span.parent, root_span.get_span_context())
self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT) self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual( self.assertEqual(child_span.attributes["db.system"], "postgresql")
child_span.attributes["db.instance"], POSTGRES_DB_NAME self.assertEqual(child_span.attributes["db.name"], POSTGRES_DB_NAME)
) self.assertEqual(child_span.attributes["db.user"], POSTGRES_USER)
self.assertEqual(child_span.attributes["net.peer.name"], POSTGRES_HOST) self.assertEqual(child_span.attributes["net.peer.name"], POSTGRES_HOST)
self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT) self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT)
def test_execute(self): def test_execute(self):
"""Should create a child span for execute method""" """Should create a child span for execute method"""
stmt = "CREATE TABLE IF NOT EXISTS test (id integer)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
self._cursor.execute( self._cursor.execute(stmt)
"CREATE TABLE IF NOT EXISTS test (id integer)" self.validate_spans(stmt)
)
self.validate_spans()
def test_execute_with_connection_context_manager(self): def test_execute_with_connection_context_manager(self):
"""Should create a child span for execute with connection context""" """Should create a child span for execute with connection context"""
stmt = "CREATE TABLE IF NOT EXISTS test (id INT)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
with self._connection as conn: with self._connection as conn:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") cursor.execute(stmt)
self.validate_spans() self.validate_spans(stmt)
def test_execute_with_cursor_context_manager(self): def test_execute_with_cursor_context_manager(self):
"""Should create a child span for execute with cursor context""" """Should create a child span for execute with cursor context"""
stmt = "CREATE TABLE IF NOT EXISTS test (id INT)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
with self._connection.cursor() as cursor: with self._connection.cursor() as cursor:
cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") cursor.execute(stmt)
self.validate_spans() self.validate_spans(stmt)
self.assertTrue(cursor.closed) self.assertTrue(cursor.closed)
def test_executemany(self): def test_executemany(self):
"""Should create a child span for executemany""" """Should create a child span for executemany"""
stmt = "INSERT INTO test (id) VALUES (%s)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
data = (("1",), ("2",), ("3",)) data = (("1",), ("2",), ("3",))
stmt = "INSERT INTO test (id) VALUES (%s)"
self._cursor.executemany(stmt, data) self._cursor.executemany(stmt, data)
self.validate_spans() self.validate_spans(stmt)
def test_callproc(self): def test_callproc(self):
"""Should create a child span for callproc""" """Should create a child span for callproc"""
@ -114,4 +115,4 @@ class TestFunctionalPsycopg(TestBase):
Exception Exception
): ):
self._cursor.callproc("test", ()) self._cursor.callproc("test", ())
self.validate_spans() self.validate_spans("test")

View File

@ -20,11 +20,11 @@ from opentelemetry import trace as trace_api
from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor
from opentelemetry.test.test_base import TestBase from opentelemetry.test.test_base import TestBase
MYSQL_USER = os.getenv("MYSQL_USER ", "testuser") MYSQL_USER = os.getenv("MYSQL_USER", "testuser")
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD ", "testpassword") MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", "testpassword")
MYSQL_HOST = os.getenv("MYSQL_HOST ", "localhost") MYSQL_HOST = os.getenv("MYSQL_HOST", "localhost")
MYSQL_PORT = int(os.getenv("MYSQL_PORT ", "3306")) MYSQL_PORT = int(os.getenv("MYSQL_PORT", "3306"))
MYSQL_DB_NAME = os.getenv("MYSQL_DB_NAME ", "opentelemetry-tests") MYSQL_DB_NAME = os.getenv("MYSQL_DB_NAME", "opentelemetry-tests")
class TestFunctionalPyMysql(TestBase): class TestFunctionalPyMysql(TestBase):
@ -50,7 +50,7 @@ class TestFunctionalPyMysql(TestBase):
cls._connection.close() cls._connection.close()
PyMySQLInstrumentor().uninstrument() PyMySQLInstrumentor().uninstrument()
def validate_spans(self): def validate_spans(self, span_name):
spans = self.memory_exporter.get_finished_spans() spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 2) self.assertEqual(len(spans), 2)
for span in spans: for span in spans:
@ -63,34 +63,38 @@ class TestFunctionalPyMysql(TestBase):
self.assertIsNotNone(root_span) self.assertIsNotNone(root_span)
self.assertIsNotNone(db_span) self.assertIsNotNone(db_span)
self.assertEqual(root_span.name, "rootSpan") self.assertEqual(root_span.name, "rootSpan")
self.assertEqual(db_span.name, "mysql.opentelemetry-tests") self.assertEqual(db_span.name, span_name)
self.assertIsNotNone(db_span.parent) self.assertIsNotNone(db_span.parent)
self.assertIs(db_span.parent, root_span.get_span_context()) self.assertIs(db_span.parent, root_span.get_span_context())
self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT) self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual(db_span.attributes["db.instance"], MYSQL_DB_NAME) self.assertEqual(db_span.attributes["db.system"], "mysql")
self.assertEqual(db_span.attributes["db.name"], MYSQL_DB_NAME)
self.assertEqual(db_span.attributes["db.user"], MYSQL_USER)
self.assertEqual(db_span.attributes["net.peer.name"], MYSQL_HOST) self.assertEqual(db_span.attributes["net.peer.name"], MYSQL_HOST)
self.assertEqual(db_span.attributes["net.peer.port"], MYSQL_PORT) self.assertEqual(db_span.attributes["net.peer.port"], MYSQL_PORT)
def test_execute(self): def test_execute(self):
"""Should create a child span for execute""" """Should create a child span for execute"""
stmt = "CREATE TABLE IF NOT EXISTS test (id INT)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
self._cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") self._cursor.execute(stmt)
self.validate_spans() self.validate_spans(stmt)
def test_execute_with_cursor_context_manager(self): def test_execute_with_cursor_context_manager(self):
"""Should create a child span for execute with cursor context""" """Should create a child span for execute with cursor context"""
stmt = "CREATE TABLE IF NOT EXISTS test (id INT)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
with self._connection.cursor() as cursor: with self._connection.cursor() as cursor:
cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") cursor.execute(stmt)
self.validate_spans() self.validate_spans(stmt)
def test_executemany(self): def test_executemany(self):
"""Should create a child span for executemany""" """Should create a child span for executemany"""
stmt = "INSERT INTO test (id) VALUES (%s)"
with self._tracer.start_as_current_span("rootSpan"): with self._tracer.start_as_current_span("rootSpan"):
data = (("1",), ("2",), ("3",)) data = (("1",), ("2",), ("3",))
stmt = "INSERT INTO test (id) VALUES (%s)"
self._cursor.executemany(stmt, data) self._cursor.executemany(stmt, data)
self.validate_spans() self.validate_spans(stmt)
def test_callproc(self): def test_callproc(self):
"""Should create a child span for callproc""" """Should create a child span for callproc"""
@ -98,4 +102,4 @@ class TestFunctionalPyMysql(TestBase):
Exception Exception
): ):
self._cursor.callproc("test", ()) self._cursor.callproc("test", ())
self.validate_spans() self.validate_spans("test")