Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 @@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#3507](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3507))
- Fix documentation order of sections and headers for Django, Flask, MySQL, mysqlclient, psycopg, psycopg2, pymysql, sqlalchemy instrumentations.
([#3719](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3719))
- `opentelemetry-instrumentation-dbapi`: Fix sqlcomment calculation of mysql_client_version field if connection reassignment, with "unknown" fallback
([#3729](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3729))

### Added

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,24 @@ def _capture_mysql_version(self, cursor) -> None:
"mysql_client_version"
]
):
self._db_api_integration.commenter_data["mysql_client_version"] = (
cursor._cnx._cmysql.get_client_info()
)
try:
# Autoinstrumentation and some programmatic calls
self._db_api_integration.commenter_data[
"mysql_client_version"
] = cursor._cnx._cmysql.get_client_info()
except AttributeError:
# Other programmatic instrumentation with reassigned wrapped connection
try:
self._db_api_integration.commenter_data[
"mysql_client_version"
] = cursor._connection._cmysql.get_client_info()
except AttributeError as exc:
_logger.error(
"Could not set mysql_client_version: %s", exc
)
self._db_api_integration.commenter_data[
"mysql_client_version"
] = "unknown"

def _get_commenter_data(self) -> dict:
"""Uses DB-API integration to return commenter data for sqlcomment"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,89 @@ def test_non_string_sql_conversion(self):
spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 1)

def test_capture_mysql_version_primary_success(self):
connect_module = mock.MagicMock()
connect_module.__name__ = "mysql.connector"
connect_module.__version__ = "2.2.9"
db_integration = dbapi.DatabaseApiIntegration(
"instrumenting_module_test_name",
"mysql",
enable_commenter=True,
connect_module=connect_module,
)
mock_cursor = mock.MagicMock()
mock_cursor._cnx._cmysql.get_client_info.return_value = "8.0.32"
mock_connection = db_integration.wrapped_connection(
mock_connect, {}, {}
)
cursor = mock_connection.cursor()
cursor._cnx = mock_cursor._cnx
cursor.execute("SELECT 1;")
mock_cursor._cnx._cmysql.get_client_info.assert_called_once()
self.assertEqual(
db_integration.commenter_data["mysql_client_version"], "8.0.32"
)

def test_capture_mysql_version_fallback_success(self):
connect_module = mock.MagicMock()
connect_module.__name__ = "mysql.connector"
connect_module.__version__ = "2.2.9"
db_integration = dbapi.DatabaseApiIntegration(
"instrumenting_module_test_name",
"mysql",
enable_commenter=True,
connect_module=connect_module,
)
mock_cursor = mock.MagicMock()
mock_cursor._cnx._cmysql.get_client_info.side_effect = AttributeError(
"Primary method failed"
)
mock_cursor._connection._cmysql.get_client_info.return_value = "8.0.33"
mock_connection = db_integration.wrapped_connection(
mock_connect, {}, {}
)
cursor = mock_connection.cursor()
cursor._cnx = mock_cursor._cnx
cursor._connection = mock_cursor._connection
cursor.execute("SELECT 1;")
mock_cursor._cnx._cmysql.get_client_info.assert_called_once()
mock_cursor._connection._cmysql.get_client_info.assert_called_once()
self.assertEqual(
db_integration.commenter_data["mysql_client_version"], "8.0.33"
)

@mock.patch("opentelemetry.instrumentation.dbapi._logger")
def test_capture_mysql_version_fallback(self, mock_logger):
connect_module = mock.MagicMock()
connect_module.__name__ = "mysql.connector"
connect_module.__version__ = "2.2.9"
db_integration = dbapi.DatabaseApiIntegration(
"instrumenting_module_test_name",
"mysql",
enable_commenter=True,
connect_module=connect_module,
)
mock_cursor = mock.MagicMock()
mock_cursor._cnx._cmysql.get_client_info.side_effect = AttributeError(
"Primary method failed"
)
mock_cursor._connection._cmysql.get_client_info.side_effect = (
AttributeError("Fallback method failed")
)
mock_connection = db_integration.wrapped_connection(
mock_connect, {}, {}
)
cursor = mock_connection.cursor()
cursor._cnx = mock_cursor._cnx
cursor._connection = mock_cursor._connection
cursor.execute("SELECT 1;")
mock_cursor._cnx._cmysql.get_client_info.assert_called_once()
mock_cursor._connection._cmysql.get_client_info.assert_called_once()
mock_logger.error.assert_called_once()
self.assertEqual(
db_integration.commenter_data["mysql_client_version"], "unknown"
)


# pylint: disable=unused-argument
def mock_connect(*args, **kwargs):
Expand Down