opentelemetry-python
opentelemetry-python copied to clipboard
“pkg_resources.DistributionNotFound: The 'opentelemetry-sdk' distribution was not found” error when packed by PyInstaller
Describe your environment Python 3.6.8 | Opentelemery-sdk 1.9.1
Steps to reproduce I create a image through dockerfile, pseudo code:
...
RUN pip install pip==19.0.1 virtualenv==16.1.0 virtualenv-clone==0.4.0 setuptools==39.0.1
RUN pip install --no-use-pep517 pyinstaller
RUN pip install -r requirements.txt
...
RUN pyinstaller --onefile myprogram.spec
requirements.txt:
...
opentelemetry-api==1.9.1
opentelemetry-sdk==1.9.1
opentelemetry-exporter-otlp==1.9.1
...
myprogram.spec:
path = os.path.dirname('__file__')
def gen_key(length=16):
from random import choice
numbers = "0123456789"
letters = "sgmqwerqwerpoiupoiu"
chars = "".join(numbers + letters + letters.upper())
return ''.join(choice(chars) for _ in range(length))
block_cipher = pyi_crypto.PyiBlockCipher(key=gen_key())
a = Analysis(['app/app_runner.py'],
pathex=[path],
hiddenimports=['pymysql', 'logging.config', 'app.app_runner','sqlalchemy.ext.baked', 'gunicorn.glogging',
'gunicorn.workers.sync', 'gunicorn.workers.ggevent'],
hookspath=None,
cipher=block_cipher)
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[
],
name='myprogram',
debug=False,
strip=None,
upx=False,
console=True )
then when I execute 'myprogram' which pyinstaller gave me, I got
well the program can not run.
I just newly added opentelemetry to my program, before this it runs correctly.
What is the expected behavior?
I want to know why and how to fix it.
Not sure if this is related to OpenTelemetry. Have you tried adding another package as well? From this issue, it seems like some hooks may be missing to your application.
@LronDC Are you still facing the issue? What is that opentelemetry missing that should be added to fix this? or it's just not really related?
That's the issue of missing hooks for PyInstaller which are the way to adapt PyInstaller to different ways of using Python modules.
opentelemetry
relies on package metadata (entry_points.txt
within the *.dist-info
folders) of installed opentelemetry
component packages (e.g. api
, sdk
, various exporters and instrumentations) to find different pieces to activate. And in some use cases, those metadata may be needed to lookup components specified via numerous environment variables opentelemetry
uses for runtime configuration.
So I ended up with the central hook for api
:
# hook-opentelemetry.py
from PyInstaller.utils.hooks import collect_submodules, copy_metadata
hiddenimports = collect_submodules('opentelemetry')
datas = copy_metadata("opentelemetry_api", recursive=True)
and a hook per imported package e.g.:
# hook-opentelemetry.sdk.py
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata("opentelemetry_sdk", recursive=True)
# hook-opentelemetry.exporter.otlp.proto.grpc.py
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata("opentelemetry_exporter_otlp_proto_grpc", recursive=True)
This way you can either import a component directly or specify a corresponding "hiddenimport" if a component is expected to be activated via an environment variable.
Sorry to catch up so late. @ocelotl @srikanthccv You are right it's not really related to OTEL, it's PyInstaller's issue like @mr2dark commented(which is so great). I'll close this issue here. THANK YOU guys.