diff --git a/CHANGELOG.md b/CHANGELOG.md index 93f0cab4fc..e56afd1e0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4457](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4457)) ### Fixed - +- `opentelemetry-instrumentation`: Batch all packages into a single `pip install` call in `bootstrap.py` to improve performance + ([#4530](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4530)) - `opentelemetry-instrumentation-pika` Use `ObjectProxy` instead of `BaseObjectProxy` for `ReadyMessagesDequeProxy` to restore iterability with wrapt 2.x ([#4461](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4461)) - `opentelemetry-instrumentation-dbapi` Use `ObjectProxy` instead of `BaseObjectProxy` for `TracedCursorProxy` to restore iterability with wrapt 2.x diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py index 3fbee088e4..e0934b7334 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py @@ -42,38 +42,31 @@ def _syscall(func): - def wrapper(package=None): + def wrapper(packages=None, upgrade=True): try: - if package: - return func(package) + if packages: + return func(packages, upgrade) return func() except SubprocessError as exp: cmd = getattr(exp, "cmd", None) if cmd: msg = f'Error calling system command "{" ".join(cmd)}"' - if package: - msg = f'{msg} for package "{package}"' + if packages: + msg = f'{msg} for package "{packages}"' raise RuntimeError(msg) return wrapper @_syscall -def _sys_pip_install(package): +def _sys_pip_install(packages, upgrade=True): # explicit upgrade strategy to override potential pip config try: - check_call( - [ - sys.executable, - "-m", - "pip", - "install", - "-U", - "--upgrade-strategy", - "only-if-needed", - package, - ] - ) + cmd = [sys.executable, "-m", "pip", "install"] + if upgrade: + cmd += ["-U", "--upgrade-strategy", "only-if-needed"] + cmd += [*packages] + check_call(cmd) except CalledProcessError as error: print(error) @@ -133,9 +126,10 @@ def _run_requirements(default_instrumentations, libraries): ) -def _run_install(default_instrumentations, libraries): - for lib in _find_installed_libraries(default_instrumentations, libraries): - _sys_pip_install(lib) +def _run_install(default_instrumentations, libraries, upgrade=True): + libs = list(_find_installed_libraries(default_instrumentations, libraries)) + if libs: + _sys_pip_install(libs, upgrade=upgrade) _pip_check(libraries) @@ -170,6 +164,11 @@ def run( be piped and appended to a requirements.txt file. """, ) + parser.add_argument( + "--no-upgrade", + action="store_true", + help="Do not upgrade packages with -U flag during install", + ) args = parser.parse_args() if libraries is None: @@ -178,8 +177,9 @@ def run( if default_instrumentations is None: default_instrumentations = gen_default_instrumentations - cmd = { - action_install: _run_install, - action_requirements: _run_requirements, - }[args.action] - cmd(default_instrumentations, libraries) + if args.action == action_install: + _run_install( + default_instrumentations, libraries, upgrade=not args.no_upgrade + ) + else: + _run_requirements(default_instrumentations, libraries)