diff --git a/opentelemetry-auto-instrumentation/src/opentelemetry/auto_instrumentation/bootstrap.py b/opentelemetry-auto-instrumentation/src/opentelemetry/auto_instrumentation/bootstrap.py index f8b5a566fac..570a4b932ba 100644 --- a/opentelemetry-auto-instrumentation/src/opentelemetry/auto_instrumentation/bootstrap.py +++ b/opentelemetry-auto-instrumentation/src/opentelemetry/auto_instrumentation/bootstrap.py @@ -20,33 +20,36 @@ import sys from logging import getLogger -logger = getLogger(__file__) +from .decorators import syscall -_ACTION_INSTALL = "install" -_ACTION_REQUIREMENTS = "requirements" +logger = getLogger(__file__) # target library to desired instrumentor path/versioned package name instrumentations = { - "dbapi": "opentelemetry-ext-dbapi>=0.6b0", - "flask": "opentelemetry-ext-flask>=0.6b0", - "grpc": "opentelemetry-ext-grpc>=0.6b0", - "requests": "opentelemetry-ext-requests>=0.6b0", - "mysql": "opentelemetry-ext-mysql>=0.6b0", - "psycopg2": "opentelemetry-ext-psycopg2>=0.6b0", - "pymongo": "opentelemetry-ext-pymongo>=0.6b0", - "pymysql": "opentelemetry-ext-pymysql", - "redis": "opentelemetry-ext-redis", - "sqlalchemy": "opentelemetry-ext-sqlalchemy", - "wsgi": "opentelemetry-ext-wsgi>=0.6b0", + "dbapi": "opentelemetry-ext-dbapi>=0.7b1", + "dbapi": "opentelemetry-ext-django>=0.7b1", + "flask": "opentelemetry-ext-flask>=0.7b1", + "grpc": "opentelemetry-ext-grpc>=0.7b1", + "requests": "opentelemetry-ext-requests>=0.7b1", + "jinja2": "opentelemetry-ext-jinja2>=0.7b1", + "mysql": "opentelemetry-ext-mysql>=0.7b1", + "psycopg2": "opentelemetry-ext-psycopg2>=0.7b1", + "pymongo": "opentelemetry-ext-pymongo>=0.7b1", + "pymysql": "opentelemetry-ext-pymysql>=0.7b1", + "redis": "opentelemetry-ext-redis>=0.7b1", + "sqlalchemy": "opentelemetry-ext-sqlalchemy>=0.7b1", + "wsgi": "opentelemetry-ext-wsgi>=0.7b1", } # relevant instrumentors and tracers to uninstall and check for conflicts for target libraries libraries = { "dbapi": ("opentelemetry-ext-dbapi",), + "django": ("opentelemetry-ext-django",), "flask": ("opentelemetry-ext-flask",), "grpc": ("opentelemetry-ext-grpc",), "requests": ("opentelemetry-ext-requests",), + "jinja2": ("opentelemetry-ext-jinja2",), "mysql": ("opentelemetry-ext-mysql",), "psycopg2": ("opentelemetry-ext-psycopg2",), "pymongo": ("opentelemetry-ext-pymongo",), @@ -69,17 +72,18 @@ def _install_package(library, instrumentation): Using --no-dependencies alone would leave potential for nonfunctional installations. """ - pip_list = _pip_freeze() + pip_list = _sys_pip_freeze() for package in libraries[library]: if "{}==".format(package).lower() in pip_list: logger.info( "Existing %s installation detected. Uninstalling.", package ) - _pip_uninstall(package) - _pip_install(instrumentation) + _sys_pip_uninstall(package) + _sys_pip_install(instrumentation) -def _pip_freeze(): +@syscall("pip freeze") +def _sys_pip_freeze(): return ( subprocess.check_output([sys.executable, "-m", "pip", "freeze"]) .decode() @@ -87,7 +91,8 @@ def _pip_freeze(): ) -def _pip_install(package): +@syscall("pip install") +def _sys_pip_install(package): # explicit upgrade strategy to override potential pip config subprocess.check_call( [ @@ -103,7 +108,8 @@ def _pip_install(package): ) -def _pip_uninstall(package): +@syscall("pip uninstall") +def _sys_pip_uninstall(package): subprocess.check_call( [sys.executable, "-m", "pip", "uninstall", "-y", package] ) @@ -150,6 +156,9 @@ def _run_install(packages): def run() -> None: + action_install = "install" + action_requirements = "requirements" + parser = argparse.ArgumentParser( description=""" opentelemetry-bootstrap detects installed libraries and automatically @@ -159,8 +168,8 @@ def run() -> None: parser.add_argument( "-a", "--action", - choices=[_ACTION_INSTALL, _ACTION_REQUIREMENTS], - default=_ACTION_REQUIREMENTS, + choices=[action_install, action_requirements], + default=action_requirements, help=""" install - uses pip to install the new requirements using to the currently active site-package. @@ -171,7 +180,7 @@ def run() -> None: args = parser.parse_args() cmd = { - _ACTION_INSTALL: _run_install, - _ACTION_REQUIREMENTS: _run_requirements, + action_install: _run_install, + action_requirements: _run_requirements, }[args.action] cmd(_find_installed_libraries()) diff --git a/opentelemetry-auto-instrumentation/src/opentelemetry/auto_instrumentation/decorators.py b/opentelemetry-auto-instrumentation/src/opentelemetry/auto_instrumentation/decorators.py new file mode 100644 index 00000000000..6f504e43965 --- /dev/null +++ b/opentelemetry-auto-instrumentation/src/opentelemetry/auto_instrumentation/decorators.py @@ -0,0 +1,15 @@ +from subprocess import SubprocessError + + +def syscall(cmd_name=None): + def wrapper(func): + def inner(*args, **kwargs): + try: + return func(*args, **kwargs) + except SubprocessError: + msg = "Error calling system command" + if cmd_name: + msg += ': {}'.format(cmd_name) + raise RuntimeError(msg) + return inner + return wrapper