Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into majorgreys/jinja2
Browse files Browse the repository at this point in the history
  • Loading branch information
majorgreys committed May 11, 2020
2 parents 4353a8d + b2e671a commit 0c2c269
Show file tree
Hide file tree
Showing 18 changed files with 391 additions and 59 deletions.
2 changes: 2 additions & 0 deletions docs-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ sphinx-autodoc-typehints~=1.10.2
# Required by ext packages
aiohttp ~= 3.0
Deprecated>=1.2.6
django>=2.2
PyMySQL~=0.9.3
flask~=1.0
mysql-connector-python~=8.0
Expand All @@ -13,5 +14,6 @@ prometheus_client>=0.5.0,<1.0.0
psycopg2-binary>=2.7.3.1
pymongo~=3.1
redis>=2.6
sqlalchemy>=1.0
thrift>=0.10.0
wrapt >=1.0.0,<2.0.0
9 changes: 9 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@
from os import listdir
from os.path import isdir, join

# configure django to avoid the following exception:
# django.core.exceptions.ImproperlyConfigured: Requested settings, but settings
# are not configured. You must either define the environment variable
# DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
from django.conf import settings

settings.configure()


source_dirs = [
os.path.abspath("../opentelemetry-api/src/"),
os.path.abspath("../opentelemetry-sdk/src/"),
Expand Down
2 changes: 2 additions & 0 deletions ext/opentelemetry-ext-dbapi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- Implement instrument_connection and uninstrument_connection ([#624](https://github.com/open-telemetry/opentelemetry-python/pull/624))

## 0.4a0

Released 2020-02-21
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def wrap_connect(
"""

# pylint: disable=unused-argument
def wrap_connect_(
def _wrap_connect(
wrapped: typing.Callable[..., any],
instance: typing.Any,
args: typing.Tuple[any, any],
Expand All @@ -119,7 +119,7 @@ def wrap_connect_(

try:
wrapt.wrap_function_wrapper(
connect_module, connect_method_name, wrap_connect_
connect_module, connect_method_name, _wrap_connect
)
except Exception as ex: # pylint: disable=broad-except
logger.warning("Failed to integrate with DB API. %s", str(ex))
Expand All @@ -128,11 +128,65 @@ def wrap_connect_(
def unwrap_connect(
connect_module: typing.Callable[..., any], connect_method_name: str,
):
"""Disable integration with DB API library.
https://www.python.org/dev/peps/pep-0249/
Args:
connect_module: Module name where the connect method is available.
connect_method_name: The connect method name.
"""
conn = getattr(connect_module, connect_method_name, None)
if isinstance(conn, wrapt.ObjectProxy):
setattr(connect_module, connect_method_name, conn.__wrapped__)


def instrument_connection(
tracer,
connection,
database_component: str,
database_type: str = "",
connection_attributes: typing.Dict = None,
):
"""Enable instrumentation in a database connection.
Args:
tracer: The :class:`Tracer` to use.
connection: The connection to instrument.
database_component: Database driver name or database name "JDBI",
"jdbc", "odbc", "postgreSQL".
database_type: The Database type. For any SQL database, "sql".
connection_attributes: Attribute names for database, port, host and
user in a connection object.
Returns:
An instrumented connection.
"""
db_integration = DatabaseApiIntegration(
tracer,
database_component,
database_type,
connection_attributes=connection_attributes,
)
db_integration.get_connection_attributes(connection)
return TracedConnectionProxy(connection, db_integration)


def uninstrument_connection(connection):
"""Disable instrumentation in a database connection.
Args:
connection: The connection to uninstrument.
Returns:
An uninstrumented connection.
"""
if isinstance(connection, wrapt.ObjectProxy):
return connection.__wrapped__

logger.warning("Connection is not instrumented")
return connection


class DatabaseApiIntegration:
def __init__(
self,
Expand Down Expand Up @@ -167,8 +221,7 @@ def wrapped_connection(
"""
connection = connect_method(*args, **kwargs)
self.get_connection_attributes(connection)
traced_connection = TracedConnectionProxy(connection, self)
return traced_connection
return TracedConnectionProxy(connection, self)

def get_connection_attributes(self, connection):
# Populate span fields using connection
Expand Down
26 changes: 26 additions & 0 deletions ext/opentelemetry-ext-dbapi/tests/test_dbapi_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.


import logging
from unittest import mock

from opentelemetry import trace as trace_api
Expand Down Expand Up @@ -138,6 +140,30 @@ def test_unwrap_connect(self, mock_dbapi):
self.assertEqual(mock_dbapi.connect.call_count, 2)
self.assertIsInstance(connection, mock.Mock)

def test_instrument_connection(self):
connection = mock.Mock()
# Avoid get_attributes failing because can't concatenate mock
connection.database = "-"
connection2 = dbapi.instrument_connection(self.tracer, connection, "-")
self.assertIsInstance(connection2, dbapi.TracedConnectionProxy)
self.assertIs(connection2.__wrapped__, connection)

def test_uninstrument_connection(self):
connection = mock.Mock()
# Set connection.database to avoid a failure because mock can't
# be concatenated
connection.database = "-"
connection2 = dbapi.instrument_connection(self.tracer, connection, "-")
self.assertIsInstance(connection2, dbapi.TracedConnectionProxy)
self.assertIs(connection2.__wrapped__, connection)

connection3 = dbapi.uninstrument_connection(connection2)
self.assertIs(connection3, connection)

with self.assertLogs(level=logging.WARNING):
connection4 = dbapi.uninstrument_connection(connection)
self.assertIs(connection4, connection)


# pylint: disable=unused-argument
def mock_connect(*args, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import mysql.connector

from opentelemetry import trace as trace_api
from opentelemetry.ext.mysql import trace_integration
from opentelemetry.ext.mysql import MySQLInstrumentor
from opentelemetry.test.test_base import TestBase

MYSQL_USER = os.getenv("MYSQL_USER ", "testuser")
Expand All @@ -35,7 +35,7 @@ def setUpClass(cls):
cls._connection = None
cls._cursor = None
cls._tracer = cls.tracer_provider.get_tracer(__name__)
trace_integration(cls.tracer_provider)
MySQLInstrumentor().instrument()
cls._connection = mysql.connector.connect(
user=MYSQL_USER,
password=MYSQL_PASSWORD,
Expand All @@ -49,6 +49,7 @@ def setUpClass(cls):
def tearDownClass(cls):
if cls._connection:
cls._connection.close()
MySQLInstrumentor().uninstrument()

def validate_spans(self):
spans = self.memory_exporter.get_finished_spans()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def setUpClass(cls):
def tearDownClass(cls):
if cls._connection:
cls._connection.close()
PyMySQLInstrumentor().uninstrument()

def validate_spans(self):
spans = self.memory_exporter.get_finished_spans()
Expand Down
10 changes: 8 additions & 2 deletions ext/opentelemetry-ext-jinja2/tests/test_jinja2.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ def test_render_inline_template_with_root(self):
spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 3)

render, template, root = spans
# pylint:disable=unbalanced-tuple-unpacking
render, template, root = spans[:3]

self.assertIs(render.parent, root.get_context())
self.assertIs(template.parent, root.get_context())
Expand All @@ -59,6 +60,7 @@ def test_render_inline_template(self):
spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 2)

# pylint:disable=unbalanced-tuple-unpacking
template, render = spans

self.assertEqual(template.name, "jinja2.compile")
Expand All @@ -83,6 +85,7 @@ def test_generate_inline_template_with_root(self):
spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 3)

# pylint:disable=unbalanced-tuple-unpacking
template, generate, root = spans

self.assertIs(generate.parent, root.get_context())
Expand All @@ -98,7 +101,8 @@ def test_generate_inline_template(self):
spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 2)

template, generate = spans
# pylint:disable=unbalanced-tuple-unpacking
template, generate = spans[:2]

self.assertEqual(template.name, "jinja2.compile")
self.assertIs(template.kind, trace_api.SpanKind.INTERNAL)
Expand All @@ -124,6 +128,7 @@ def test_file_template_with_root(self):
spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 6)

# pylint:disable=unbalanced-tuple-unpacking
compile2, load2, compile1, load1, render, root = spans

self.assertIs(compile2.parent, load2.get_context())
Expand All @@ -144,6 +149,7 @@ def test_file_template(self):
spans = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans), 5)

# pylint:disable=unbalanced-tuple-unpacking
compile2, load2, compile1, load1, render = spans

self.assertEqual(compile2.name, "jinja2.compile")
Expand Down
2 changes: 2 additions & 0 deletions ext/opentelemetry-ext-mysql/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- Implement instrumentor interface ([#654](https://github.com/open-telemetry/opentelemetry-python/pull/654))

## 0.4a0

Released 2020-02-21
Expand Down
5 changes: 5 additions & 0 deletions ext/opentelemetry-ext-mysql/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ packages=find_namespace:
install_requires =
opentelemetry-api == 0.7.dev0
opentelemetry-ext-dbapi == 0.7.dev0
opentelemetry-auto-instrumentation == 0.7.dev0
mysql-connector-python ~= 8.0
wrapt >= 1.0.0, < 2.0.0

Expand All @@ -51,3 +52,7 @@ test =

[options.packages.find]
where = src

[options.entry_points]
opentelemetry_instrumentor =
mysql = opentelemetry.ext.pymysql:MySQLInstrumentor
Loading

0 comments on commit 0c2c269

Please sign in to comment.